1. Си / Говнокод #26316

    −1

    1. 001
    2. 002
    3. 003
    4. 004
    5. 005
    6. 006
    7. 007
    8. 008
    9. 009
    10. 010
    11. 011
    12. 012
    13. 013
    14. 014
    15. 015
    16. 016
    17. 017
    18. 018
    19. 019
    20. 020
    21. 021
    22. 022
    23. 023
    24. 024
    25. 025
    26. 026
    27. 027
    28. 028
    29. 029
    30. 030
    31. 031
    32. 032
    33. 033
    34. 034
    35. 035
    36. 036
    37. 037
    38. 038
    39. 039
    40. 040
    41. 041
    42. 042
    43. 043
    44. 044
    45. 045
    46. 046
    47. 047
    48. 048
    49. 049
    50. 050
    51. 051
    52. 052
    53. 053
    54. 054
    55. 055
    56. 056
    57. 057
    58. 058
    59. 059
    60. 060
    61. 061
    62. 062
    63. 063
    64. 064
    65. 065
    66. 066
    67. 067
    68. 068
    69. 069
    70. 070
    71. 071
    72. 072
    73. 073
    74. 074
    75. 075
    76. 076
    77. 077
    78. 078
    79. 079
    80. 080
    81. 081
    82. 082
    83. 083
    84. 084
    85. 085
    86. 086
    87. 087
    88. 088
    89. 089
    90. 090
    91. 091
    92. 092
    93. 093
    94. 094
    95. 095
    96. 096
    97. 097
    98. 098
    99. 099
    100. 100
    double end_line( char data[0][200]){
    double x = 0 , y = 0, sum = 0,ml = 0    ; 
    char	*point =   strtok(  &data[1][0] , " " );
    	
    	while( point !=   '\0'   ){
    			
    			if(isdigit(  *point ) ){
    				
    			ml  = atof( (char *)  point  )  ;
    		
    				push_stack_2( &topPTR_2,ml);
    				}	
    			
    			
    			else if ( isOperator ( *point ) == 1 ){
    				 
    				 y =	pop_2(&topPTR_2);
    				 x = 	pop_2(&topPTR_2);	 	
    					
    					if( *point  == '^' ){
    						  sum  =  pow(x, y) 	  ;
    						 	push_stack_2(  &topPTR_2, sum  );
    						 }
    					
    					
    					if( *point  == '*' ){
    						 
    							
    							 push_stack_2(&topPTR_2,    	x * y         );
    						 }
    				 		
    				 	  if( *point == '+' ){
    			
    							 push_stack_2(&topPTR_2, 	x + y  	 );
    						 }
    				 
    				     if(  *point == '/' ){
    						 	
    							    
    							 push_stack_2(&topPTR_2, x / y    );
    						 }
    				 
    				 if(   *point == '-' ){
    					 
    							 push_stack_2(&topPTR_2,   x - y     );
    						 }
    				 	}
    				
    			point = strtok(NULL , " " ) ;
    	return    pop_2(&topPTR_2);
    }
    
    int in_line(char data[][200] , int  lng  ){
    	
    double x = 0 , y = 0, sum = 0 ; 
    int j = 0  , k = 0 , d = 0;
    	
    	data[0][lng ] = ')';
        push_stack(&topPTR, '(');
    	
    	for (k = 0; check_stack((void *) &topPTR) != 1   ; k++)  {
    
    		if (  isdigit(data[0][k]) ||  data[0][k] == '.'  ) {
    
    			data[1][j++] = data[0][k];
    	
    		}
    
    		if (data[0][k] == '(') {
    
    			push_stack(&topPTR, infix[0][k]);
    
    		}
    			if (isOperator(data[0][k]) == 1) {
    				data[1][j++]  = ' ';
    			for (;         precedence(topPTR->alpha, data[0][k]) != -1 ; ) {
    		
    			data[1][j++] = pop(&topPTR);
    				data[1][j++]  = ' ';	
    		}
    				
    			push_stack(&topPTR, data[0][k]);
    			push_stack(&topPTR, ' ' );
    			
    		}
    
    		if (data[0][k] == ')') {
    	
    		d = pop(&topPTR);
    			for (; d != '('     ; 	d = pop(&topPTR)) {
    					data[1][j++] = d;
    				}
    			}
    		else if (isalpha(data[0][k]   ) ) {
    			puts ("error");
    			return 0;
    		}
    	}
    	return 1;
    	}

    calc 2

    Запостил: tyrin, 05 Января 2020

    Комментарии (110) RSS

    • > int in_line(char data[][200] , int lng ){
      лукавая какая конструкция, лол
      Ответить
      • Мне больше понравилось double end_line( char data[0][200]) — тут ноль в скобочках.
        Ответить
        • питуз проткнутый же потом сделает

          sizeof(data)

          стопудово сделает

          надо вообше запретить этот говносвинтаксис
          Ответить
          • После ЯП, в которых в функцию можно передавать массивы по значению, на сишке писать опасно. Сразу начинаются багры.
            Ответить
            • Именно по этому я считаю, что начинать обучение нужно с сишки.

              После сишки ты осилишь джаву. А после джавы у тебя такой брейн демдж, что ты не понимаешь что и как и куда передается
              Ответить
            • Обратное тоже справедливо. А всё потому, что при переходе с одного языка без ссылочной прозрачности на другой язык без ссылочной прозрачности обязательно где-нибудь вылезут багры. Мутабельность вызывает сразу два рода проблем: "это говно было случайно скопировано и не перезаписалось" и "это говно передали по ссылке и случайно перезаписали".
              Ответить
              • А вот в Ди есть транзитивная иммутабельность и константность.
                Ответить
              • >Обратное тоже справедливо.
                ну кстати нет

                Сишнику легко будет понять, что массив в джаве это объект в куче, с которым работают через указатель

                А вот джависту понять си будет куда сложнее
                Ответить
                • А в джаве массивы передаются по значению? Или какое утверждение Вы посчитали обратным к горилловскому?
                  Ответить
            • > передавать массивы по значению

              А есть вообще такие языки?

              В том же паскале можно передать массив без var/const?
              Ответить
              • Можно.

                На самом деле в стек пушится не сам массив, а указатель на его копию. Вызывающий код снимает копию с массива и передаёт в функцию указатель, а после возврата освобождает память от этой копии.

                С точки зрения же кода на «Паскале» всё выглядит так, как будто передали значение.
                Ответить
                • Сколько умных, но не нужных слов! Указатели какие-то, массивы, пушится. Паскаль - это математик? Ладно, не суть. Готовься к худшему.
                  Ответить
                  • к кодингу на 1С и общению с бухами?
                    Ответить
                    • Когда я посещу тебя, насущные проблемы отойдут на второй план.
                      Ответить
                    • реально нравится отвечать раковому уёбку?
                      Ответить
      • А разве двумерный массив не передается с указанием длины ?
        Ответить
        • В сишке ВСЕ* массивы пердаются по указателю, без инфы о размере.
          _______________________________________
          *кроме запханных в структуры
          Ответить
          • Сенкью
            Ответить
            • Это ты Ричи спасибо скажи, за такое чудо программерской мысли.

              Сейчас придёт KOPOHABuPYC и скажет, что ты с ним скоро встретишься.
              Ответить
              • >сейчас придет ёбаный рак
                неужели ёбаный рак всё еще жив?
                Ответить
            • void func1() {
                  char massiv1[50]; // это массив; под него выделено место
                  char *massiv2; // это указатель на массив; под него место не выделено
              }
              
              void func2(char * massiv3, // это указатель на массив
              char massiv4[50] // это всё равно указатель на массив, как будто тут написано char * massiv4,
                  // потому что функция не принимает массивы,
                  // вместо них она принимает указатели без размера
              ){}
              
              typedef struct {
                  char data[50];
              } foo;
              
              void func3(foo massiv5){} // А тут передастся массив строго из 50 элементов,
              // потому что он завёрнут в структуру
              Ответить
              • ахаха
                а тут?
                void func3(foo& massiv5)
                (это плюсики)
                Ответить
              • В Ди додумались сделать массивы сразу в виде скрытой структуры размер/указатель. Это решило сишкопроблемы с ними.
                Ответить
                • в си надо было просто копировать их по значению, если ты явно не кастанул их в указатель. И все было бы ок

                  Просто и логично.

                  Вот референс в ++ это уже не так логично
                  Ответить
          • Всё хитрее. Многомерные массивы передаются как указатели на безразмерный массив конечных массивов размерности (N-1). Т. е. только старшая размерность теряет количество элементов.

            #include <stdio.h>
            
            void foo(char x[][10]) {
              printf("%d\n", sizeof(x)); // тут выведет размер указателя в байтах, потому что x — это указатель, а не массив
              printf("%d\n", sizeof(x[0])); // тут выведет 10, потому что x — это указатель на массив массивов 10 чаров
            }
            
            
            char massiv[2][10];
            
            int main() {
              foo(massiv);
              return 0;
            }
            Ответить
            • ёбаные наркоманы
              Ответить
              • Т. е. массив можно завернуть не только в структуру, но и в массив.

                В параметрах функции char data[100][200] эквивалентно char data[][200] и эквивалентно char (*data)[200]. Без скобочек, кстати, получится совершенно другая питушня. Попрошу не путать, а то могут и напутать.

                Правда, легко запомнить?
                Ответить
                • Массив, завернутый в массив, все равно передастся как указатель же, так что заворот не поможет.

                  Причем массив превращается в указатель только при вызове.
                  В струкутре или просто в памяти он в него не превращается.

                  za4em?za4em?
                  Ответить
                  • При передаче в функцию разворачивается один уровень многомерного массива, самый верхний. Поэтому sizeof(arg) даст размер указателя в байтах, а sizeof(arg[0]) даст размер проекции массива на (n-1)-мерное пространство.

                    Да, при заворачивании массива в массив передастся указатель. Но второй уровень не развернётся, он останется массивом.

                    Правда, очевидно?
                    Ответить
                    • иными словами, я получу указатель на массив

                      в стек мне скопируется все равно указатель, но указывать он ьудет не на другой указатель, а на массив

                      так?
                      Ответить
                    • Что-то говно какое-то. И тут уже нужна цепочка из двух звеньев:
                      1. массив передаётся как указатель на переменную типа его элемента
                      2. поэтому - указатель.

                      Но всё равно это, в сущности, говно. Потому, что
                      1. Для char a[7][7]; как переменной sizeof(a) равен 49. Почему тогда для char a[7][7] как аргумента - как указатель.
                      2. Функция всё равно знает размерности массива, запись младших размеров в типе жизненно важна для доступа к элементам, и потому используется.

                      Я, конечно, могу понять, почему если записать в аргументе char* и потом передать char[10] или char[20], sizeof скажет одно и то же. Потому, что запись "char*" ничего не говорит о точном количестве элементов. Аналогично - с "char[]".

                      Но когда я явно записал "char[7][11][13]", почему нельзя это запомнить и учесть? Ведь сишка умеет помнить N-1 размеров, когда это выгодно ей самой. А как программист попросил запомнить ещё одно сраное число - так всё - садись на указатель.
                      Ответить
                      • Какая-то жуткая неконсистентность. Предлагаю изменить стандарт и сделать такое поведение:

                        1. Для char a[7][11] sizeof(a) равен 77.
                        2. Для char a[][11] sizeof(a) вызывает ошибку компиляции.
                        3. Для char (*a)[11] sizeof(a) равен sizeof(void*)

                        P.S. вообще, типы вида char[] нужно выпилить как нелогичное говно, поскольку уже есть char[размер] и char*, которые покрывают все случаи и не имеют проблем с семантикой.
                        Ответить
                        • Вот в Ди все консистентно:
                          (char[7][11]).sizeof == 77
                          (char[][11]).sizeof == 176 // char[] - это встроенный динамический массив
                          (char*[11]).sizeof == 88 // массив из 11 указателей
                          Ответить
                          • А для char (*a)[11] и char *a[11] сделали непердольные обозначения?
                            Например, в C++ есть хотя бы std::shared_ptr<std::array<char, 11>> и std::array<std::shared_ptr<char>, 11>.

                            А для функций?

                            P.S. Бесит, когда имя типа надо читать по спирали и по словарю иероглифов, а также когда имя переменной вставляется куда-то в середину имени типа.
                            Ответить
                            • Ты путаешь синтаксис и библиотеки. Плюсовый вариант не равен сишному по функционалу.
                              (char[11]*).sizeof == 8

                              Функции пишутся так:
                              int abc(int x) { return x + 1; }
                              int function(int) fp = &abc;
                              Ответить
                              • В Ди вообще со встроенными массивами весело:
                                void foo(int[] a)
                                {
                                    writeln(a.sizeof); //8
                                    writeln(a.length); //5
                                    writeln(a); //[0,0,0,0,0]
                                    a ~= 7;
                                    writeln(a); //[0,0,0,0,0,7]
                                }
                                
                                void main()
                                {
                                    int[5] a;
                                    foo(a);
                                    writeln(a); //[0,0,0,0,0]
                                }
                                Ответить
                                • Передача по значению, как в Паскале. Функция foo изменила копию массива.
                                  Ответить
                                  • Нет. Был передан указатель на массив с размером (8 байт, т.к. 32-битная версия). В начале foo a.ptr равен a из main. Потом после добавления значения массив создается в куче.
                                    Ответить
                                    • Кажется, понял. Похоже только внешне, а устроено по-другому.
                                      Ответить
                                • В «Delphi» и во «Free Pascal» есть так называемые «открытые массивы» (open arrays). Если в заголовке функции не указан диапазон индексов, то рядом с массивом невидимым аргументом передаётся размер массива:
                                  https://freepascal.org/docs-html/current/ref/refsu68.html

                                  И ещё есть динамические массивы:
                                  https://freepascal.org/docs-html/current/ref/refsu14.html

                                  Т. е. Ди в чём-то похож на Object Pascal, только с сишным синтаксисом.
                                  Ответить
                                  • Может и так, но оба поля .length и .ptr никто не скрывает.
                                    Ответить
                              • > Ты путаешь синтаксис и библиотеки.
                                Нет. В C есть только модификаторы типа одного вида c говённым синтаксисом, а в C++ - двух видов - с говённым синтаксисом и с чуть получше.
                                Питушня со скобками - часть синтаксиса C++, которую нельзя использовать C

                                > Плюсовый вариант не равен сишному по функционалу.
                                Это мелочи. В некотором смысле там описываются массив указателей и указатель на массив.
                                С точки зрения использования, массив - это питушня, у которой можно взять длину и элементы, а указатель - небольшая питушня, которая может дать доступ к психозе в памяти.
                                В C++старьё и C++11+ можно использовать using template или иную питушню, чтобы скорректировать поведение.
                                Ответить
                                • В Ди shared_ptr не нужен, т.к. есть сборка мусора (но хотят прикрутить подсчет ссылок).
                                  std::array - это костыль, с помощью которого к указателю на массив добавляют длину, а это есть у всех массивов в Ди.
                                  Ответить
                                  • не понятно зачем тогда это вообще сравнивать с си?

                                    Сборка мусора не нужна, кстати.
                                    Это самая большая глупость (после скриптовых языков)
                                    Ответить
                                    • ради срача конечно же
                                      Ответить
                                    • А почему бы не сравнить?
                                      Вот мне для программы надо хранить и доставять несколько значений одного типа, и я хочу узнать, в каком языке будет удобнее это делать.

                                      Задач, где требуется именно "анскильная питушня, притворяющаяся указателем на блок в памяти, где лежит непонятное число элементов, к которой можно прибавлять числа, чтобы получить анскильную питушню, указыающаю на следующие элементы", исчезающе мало.
                                      Поехавших, которым требуется для работы именно такая питушня, и которые скажут "не стоит это путать с std::array из C++ или Array из JS, это принципиально другое" уже развезли по дуркам и отобрали у них электронно-вычислительные устройства.
                                      Ответить
                                      • Потому что это всё равно, как сравнивать Verilog и lua.

                                        Языки для разных задач.

                                        Те задачи, где можно использовать сборщик мусора, не надо решать на си.

                                        Те задачи, которые решают на си, не будут работать нормально со сборщиком мусора.

                                        Сравнивайте тогда D и go
                                        Ответить
                                        • В Ди есть режим BetterC без всяких сборщиков. Но там динамические массивы не будут работать.
                                          Ответить
                                          • Я уже узнал, что в @nogc много чего просто не компилируется. Даже собственную рантайм-библиотеку без gc написать нельзя. Нужно вмешательство в сам компилятор, чтобы сделать по-другому.
                                            Ответить
                                        • Ну, Verilog - это больше язык описания какой-то питушни, а не для вычислений, его логично сравнивать с XML, ограниченным схемой, а не с языком для вычислений.

                                          Но вот сравнивать вычислительные языки общего назначения, такие как C, C++, D, C#, Haskell, JS, между собой - вполне себе нормально.

                                          Тем более, что мы начинали с хранения размера массива. Это вообще не относится к сборке мусора. В одном и том же C++ без сборки мусора есть и вариант массивов, которые хранят длину, и - которые не хранят.

                                          Аналогично, в Java можно вполне себе реализовать Array2 с методами getElement и setElement, но без length, и он будет работать абсолютно так же, как и void* в C, но будет подвергаться сборке мусора.
                                          Ответить
                                    • > Сборка мусора не нужна, кстати.
                                      > Это самая большая глупость (после скриптовых языков)
                                      Какой багор )))

                                      Вам что, хочется все переменные питушить руками?
                                      Без сборки мусора даже два вектора сложить - отдельный пердолинг. Вместо c = a + b или c = f(a + b) нужно писать лишний бойлерплейт, чтобы явно сохранить временное значение суммы и удалить временное значение суммы и слагаемые.

                                      Единственное, к сборке мусора необходимо прикручивать явное удаление объекта. Нечасто, но таки не никогда, требуется явно удалить большой объект и освободить память, либо закрыть файл. В языке с GC должно быть 3 оцпии:
                                      *
                                      * вызов деструктора
                                      * вызов деструктора и удаление
                                      В первом случае объект убивается и подчищается на этапе сборки мусора, во вторм - убивается на этапе вызова, очищается на этапе сборки мусора, в третьем - убивается и очищается на этапе вызова.
                                      Ответить
                                      • >Вам что, хочется все переменные питушить руками?
                                        Нет, мне вполне хватит референс каунтинга как в свифте, например
                                        Ответить
                                        • Но ведь, если это делается неявно (в отличие от std::shared_ptr), это всё равно в некотором смысле сборка мусора
                                          * Автоматизирует питушню
                                          * Удаляет объекты, когда это удобно алгоритму, а не программисту
                                          Ответить
                                          • она гарантирует что:

                                            * десктрукторы вызовутся перед удалением объекта
                                            * удаление будет предсказуемо, я всегда понимаю когда и что удалится
                                            * не будет вдруг внезапно секунда потрачена на сборку
                                            Ответить
                                            • В общем-то да, после ARC и крестового RAII сборка мусора ощущается как шаг назад.
                                              Ответить
                                              • Попробуй скажи это вслух.

                                                Сразу набигут питухи, ни на чем кроме джавы никогда не писавшие, которым в школе учитель информатики сказал, что "в си всегда есть меморилики, а с ГЦ все безопасно" и начнут повторять тебе вот эту самую говномантру.

                                                Парадокс блаба в общем: чтбы понять почему ГЦ -- говно надо пописать на языке с ARC или на крестах с RAI I и умными указателями
                                                Ответить
                                                • Ну у ГЦ таки есть преимущество, когда у тебя структуры составляют сложный граф и содержат только анонимные ресурсы типа памяти. Тот самый DOM в браузерах, к примеру.

                                                  С ARC'ом такие данные очень неудобно обрабатывать, надо думать где будут сильные связи, а где слабые.

                                                  И ещё ГЦ иногда работает быстрее, если ты порождаешь тонны мелких объектов и тут же их удаляешь. Но это обычно можно тупо убрать на стек и не дрочить аллокатор.

                                                  На всём остальном ГЦ тупо сосёт.
                                                  Ответить
                                                  • Про сложный граф всё равно нужно понимать кто на кого ссылается, иначе ты легко утечешь памятью зацпив огромный кусок говна за маленький листик.

                                                    Если же ты все равно его понимаешь, то что мешает тебе придлерживаца простого правила:
                                                    * у папы сильная ссылка на ребенка
                                                    * все остальные ссылки слабые

                                                    Это же физически так и устроено: папу убили -- и все дети самовыпилились.

                                                    Если у тебя много мелких объектов, то проще сделать арену, засрать её под завязку, и потом грохнуть.

                                                    Ну либо выудить место в стеке, как ты сказал, и потом тоже грохнуть круто крутанув SP.

                                                    ГЦ не нужен
                                                    Ответить
                                              • плюсовая профдеформация
                                                Ответить
                                      • У тебя же есть файка скриптовой петух
                                        Ответить
                                        • Мне проще покукарекать с этой учётки, чтобы не тратить время на залогинивание.

                                          Ку-ка-ре-ку! Скрип-туш-ня!
                                          Ответить
                          • > (char*[11]).sizeof == 88 // массив из 11 указателей

                            Кстати да, добавляю четвёртый пункт в предложение:
                            4. Для char *a[11] sizeof(a) равен (11 * sizeof(void*))
                            Ответить
                • > Правда, легко запомнить?
                  Легко, если знать, как запоминать.

                  Массив elem_t имеет тип elem_t[число] и эквивалентен указателям типа elem_t[] и elem_t*. На месте elem_t может быть произвольный тип, например double, int[10][20], int(*)(float[][200], time_t).
                  typedef char string[200];
                  // string[100] эквивалентно atring[] и string*
                  Ответить
        • скажи быстро, что ты пошутил
          Ответить
      • вот такое "комильфо" *(*data + 200 + j++ ) по всей простыне
        https://ideone.com/ep4v00
        Ответить
    • >strtok
      Самая ненужная функция в мире
      Ответить
      • Ну-ка, не глядя в справку, расскажите, что делает эта функция.
        Ответить
      • Не удержался и сам подглядел. Самый кошмар в этом: «If str == NULL, the call is treated as a subsequent calls to strtok: the function continues from where it left in previous invocation». Т. е. в какой-то глобальной переменной библиотеки (к которой у нас прямого доступа нет) хранится состояние этой функции. Говнопаттерн «Одиночка» a. k. a. «Синглтон». Настоящий «unix-way».

        Мы не можем использовать эту функцию для обработки более чем одной строки. Чтобы начать обрабатывать вторую строку, мы должны закончить обрабатывать первую.

        Кстати, как это работает с многопоточностью?
        Ответить
        • никак, она не тред сейф

          Так делали функции в 1971 году, в 2020 юзать её не надо
          Ответить
          • Но зачем так делали? Экономия, чтобы ничего не аллоцировать и не передавать?
            Ответить
            • а зачем errno глобальный?

              ты видел сырцы первого юникса на си?
              там царский код, и каждая утилита состоит из одного .c файла строк на двести. Это было еще до манифеста про структурное программирование, никто и не думал о реюзабильности
              Ответить
        • > с многопоточностью

          Нормально. Всё это говно сейчас с тредлокалами.

          > зачем так делали

          Дык тогда не было тредов, даже идеи такой не было. Вот и не парились про глобалки.
          Ответить
          • >Нормально
            на пинде да

            https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strtok-strtok-l-wcstok-wcstok-l-mbstok-mbstok-l?view=vs-2019

            Each function uses a thread-local static variable


            на прыще -- не обязан
            http://man7.org/linux/man-pages/man3/strtok_r.3.html
            │strtok() │ Thread safety │ MT-Unsafe race:strtok
            Ответить
            • О как. Не думал, что всё так плохо. Впрочем похуй, я его ни разу и не юзал.
              Ответить
              • Бамп отсосу прыщеблядей!
                Ответить
                • Кстати, в прыщах потоков нет.
                  В винде есть, а в прыщах нет.

                  А хотя нет: kernel threads там всё таки есть.
                  Засрали терминологию, и испортили мне такую шутку
                  Ответить
                  • Дык потоки не нужны. Процессы с расшаренной памятью намного лучше - у тебя есть контроль над тем, что ты расшариваешь. Никто тебе в стек не насрёт, например, если его не шарить. И при этом ты спокойно можешь сэмулировать потоки, расшаривая всё подряд.
                    Ответить
                    • Ну вообще я хотел сострить о том, что ядро знает только понятие "task".
                      Если такси шарят кучу, то питухи называют их потоками.
                      Если не шарят -- то процесами.

                      Еще есть наверное pid у них, но то такое

                      А потоки это высокоуровневая абстракция библоиотиеки pthreads и ее друзей.

                      Но так как внутри ядра есть понятие кернел треды (ну которые как систем треды в винде) то шутка не удалась.

                      Я, в целом, согласен, что прыщеподход лучше виндового.

                      Кстати, а как сделано у яблока? Вроде, у mach тоже таски?
                      Ответить
                    • Есть библиотека pthreads, которая эмулирует потоки на чём угодно. Есть даже порт для «DOS», который вешает обработчик на прерывание от аппаратного таймера и переключает нити.
                      Ответить
                      • Ну вот видишь: дос -- самая настоящая многозадачная ОС.

                        кстати, о прерыва таймр
                        знаешь про
                        https://en.wikipedia.org/wiki/Tickless_kernel ?
                        Ответить
                        • Нет, не знаю. А как оно работает?

                          С копропротивной корпоративной многозадачностью всё ясно — там каждое приложение само отдаёт тики, вызывая соответствующий сисколл, когда оно свободно.

                          С вытесняющей по таймеру тоже ясно.

                          А tickless как работает?
                          Ответить
                          • Да тот же таймер, просто взводится на конкретное время а не равномерно тикает.
                            Ответить
                          • "when the (i386) kernel goes into its idle loop, it checks the next pending timer event. If that event is further away than the next tick, the periodic tick is turned off altogether; instead, the timer is is programmed to fire when the next event comes due."

                            Смысл в том, что операционка заводит таймер на далёкое будушее, и ложится спать.
                            Ответить
                            • Ну это вполне логично. Тикалка нужна только чтобы прерывать текущий тред. Если все треды спят, то прерывать нечего и тики не нужны.
                              Ответить
                              • Кстати, а кто обновляет часы? Или там второй таймер?
                                Ответить
                                • Я не знаю, что сейчас реально юзается в качестве источника времени. Но это либо rdtsc либо acpi таймер. У обоих достаточно большой период, т.е. "обновлять часы" нинужно. По крайней мере каждый тик.
                                  Ответить
                                  • ого, как там всё круто
                                    может юзаться любой, и ядро об этом говорит

                                    https://0xax.gitbooks.io/linux-insides/content/Timers/linux-timers-6.html

                                    нук покаж свой
                                    /sys/devices/system/clocksource/clocksource0/current_clocksource


                                    ps: какая милая книжка
                                    надо чвитнуть
                                    Ответить
                                    • tsc. Видимо потому что constant_tsc в /proc/cpuinfo.
                                      Ответить
                                      • Это типа у тебя новый проц, где эта хуйня тикает с постоянным временем в независимости от буста процессора?

                                        Иными словами, ядро переодически спрашивает у процессора "эй, а сколько прошло времени с момента запуска?", и так обновляет часы. Да?

                                        Причем делать это можно раз в секунду (а не 100 и не 1000, как для шедулера)
                                        Ответить
                                        • Нафиг надо обновлять часы, если у таймера ебический период и он равномерно тикает? Понадобится тебе время - позовёшь rdtsc, прибавишь оффсет да и всё.
                                          Ответить
                                          • А не надо разве сохранять переодически время в те часы, которые поддерживает CMOS?

                                            А не
                                            Я пиздун

                                            Это делает юзерлендовая программа при выключении.
                                            Ядру вообще пофиг.

                                            Тогда ты прав
                                            Ответить
                          • Кстати, Заметь: винда8 это тоже умеет

                            Так что ноут с ней будет меньше есть батарейку не делая ненужной хуйни
                            Ответить
                          • >копро

                            Раньше многозадачность была именно такой. Приходилось пися код помнить, что ты не один на свете.

                            Потом изобрели вытесняющую многозадачность на таймере, и стало можно писать код так, словно бы ты один. Ну то-есть хуеть типа "while(1){}" конечно не надо, но можно не елдиться постоянно.

                            А потом питузы снова изобрели коопертивку посредством асинков. И опять стало надо писать код помня, что есть и другие питухи.

                            И все страшно радуются.

                            А, блядь.
                            Как харашо стало, Блядь.

                            Ёбаные милениалы переизобрели деревянное колесо, и записали это себе в заслуги.

                            Гомосапиенсы туповаты, конечно.
                            Ответить
    • В 1985 году компания Nintendo подала в суд и попыталась аннулировать патенты Баера, заявив, что в 1958 году Уильям Хигинботэм[en] создал игру Tennis for Two. Однако суд постановил, что Tennis for Two была сделана на основе осциллографа и не использовала видеосигналы, и поэтому не может квалифицироваться как видеоигра

      Как же раньше было всё интересно
      Ответить
    • Питухи Леонардо
      https://publish.twitter.com/?query=https%3A%2F%2Ftwitter.com%2FWhore sofYore%2Fstatus%2F1261971353873403904&w idget=Tweet
      Ответить
      • Зачем здесь это?
        Ответить
        • Гость заебал оффтопить, если честно. У нас тут так не принято.
          надо бы его удалить
          Ответить
          • А в почту, в icq гость тебе случайно не пишет?
            Ответить
            • в одиго пишет
              Ответить
              • «Одиго» прошёл мимо меня. Я его даже не заметил.

                „Его особенностью была возможность поиска людей, одновременно находящихся на любом сайте Интернета. Например, находясь на сайте Википедии, можно было включить «радар» и увидеть на нём всех людей, просматривающих этот сайт, после чего начать общаться с ними. Таким образом можно было найти единомышленников.“

                Т. е., если бы он не закрылся в 2007-м году, можно было бы, например, в нём найти всех, кто просматривает «Говнокод»?
                Ответить
                • Скорее всех, кто юзает эту штуку и просматривает говнокод? Иначе это пиздец.
                  Ответить
                  • Есть идеи, как реализовать мессенджер, чтобы он показывал даже тех, кто не юзает эту штуку?
                    Ответить
    • Исходный пример это калькулятор? Гляньте на главной dlang.org пример "Tiny RPN calculator":
      // Reduce the RPN expression using a stack
          readln.split.fold!((stack, op)
          {
              switch (op)
              {
                  // Generate operator switch cases statically
                  static foreach (c; "+-*/")
                      case [c]:
                          return stack[0 .. $ - 2] ~
                              mixin("stack[$ - 2] " ~ c ~
                                  " stack[$ - 1]");
                  default: return stack ~ op.to!real;
              }
          })((real[]).init).writeln;
      Ответить
      • В сишке этот же код будет многословнее, потому что макропроцессор не поддерживает циклы (костыли для реализации циклов через макросы выглядят очень страшно).
        Ответить
        • да тут и цепочка вызовов функций, и работа со срезами массивов мозг ломает с непривычки
          Ответить
      • Нати вам в догонку петушинский "конвертер величин"
        http://www.govnokod.ru/23400
        Ответить

    Добавить комментарий