Тред, посвященный прародителю всех С-подобных языков и по совместительству единственному идеальному и всесторонне годному средству программирования как на системном, так и на прикладном уровне.
- Очевидный GCC. - clang: оче годно, батя рекомендует. - Intel C++ Compiler: оптимизации, тысячи их. - Visual Studio Community Edition: внезапно этим стало можно пользоваться, особенно с тулсетом clang/C2. Поддержка C11 на уровне "есть все, что тебе понадобится в реальном проекте плюс кривая библиотека". Анализатор кода в комплекте. - Pelles C (шиндоуз онли): поучиться, вкатиться в C11 (стандарт полностью реализован, имеются в том числе threads.h и прочие stdatomic.h), но количество багов в оптимизаторе и редкие апдейты напрочь отбивают желание собирать этим что-то сколько-нибудь серьезное. - TCC: очень маленький компилятор с багами и поддержкой C99. С ключом -run умеет компилировать код в память и запускать его, что позволяет писать скрипты прямо на сишечке.
Samuel P. Harbison, Guy L. Steele Jr. "C: A Reference Manual, 5th Edition" (2002) Ебаный пересказ стандартов C89 и C99 (включая стандартную библиотеку). Для не осиливающих стандарт в оригинале. Читать в качестве подготовки к собеседованиям (есть задачник с ответами) и для ознакомления с масштабами пиздеца перед написанием своего парсера/компилера.
Peter Van Der Linden "Expert C Programming. Deep C Secrets" (1994) "Си: грязные истории". Смехуечки, немного объяснений, чем обусловлены особенности языка, всем известные подводные камни кто там ругал косяки в JS? у нас в сишечке их гораздо больше, просто они лучше спрятаны, немного байтоебли и непонятно откуда взявшаяся глава про старинные плюсы. Читать в качестве сказки на ночь (на пару вечеров хватит).
Richard M. Reese "Understanding and Using C Pointers. Core Techniques for Memory Management" (2013) - почитать, вкатиться в указатели.
Ben Klemens "21st Century C: C Tips from the New School" (2012)
Paul Deitel, Harvey Deitel "C for Programmers with an Introduction to C11" (2013)
Stephen G. Koch@n "Programming in C (3rd Edition или 4th Edition, если найдется)" (2014)
- https://godbolt.org/ - Compiler Explorer позволяет посмотреть выхлоп компиляторов для введенного куска кода (больше полусотни разных версий компиляторов). - http://cdecl.org/ - С Gibberish ↔ English помогает читать сложные сишные декларации.
>>1874674 Да, если архитектура это предусматривает. main не фактическая точка входа в программу argv это массив указателей, элементы будут все так же лежать где-то в памяти.
Экспериментирую с CLI программами, вот хочу поинтересоваться, а как можно вызвать аргументы для ввода через TAB? К примеру: беру я название программы которую нужно открыть, ввожу первые 3 буквы, нажимаю TAB и чтобы все файлы которые начинаются с этих букв показывались в консоли. Это как то через какие то готовые утилиты делается и библиотеки да?
Еще спрошу. А как открыть файл в режиме w+ и сделать так чтобы можно было не просто его дополнять, но и менять содержимое. Намекните хотя бы на библиотеку или инструменты которые можно использовать. Редактор будет тоже в CLI. Если что я сейчас изучаю stdlib с fopen и т.д
>>1874941 Какой-то bash это и так сделает если твоя приложуха лежит в пути который в PATH. А если ты хочешь ещё и аргументы дополнять - там уже надо читать как bash autocomplete настраивать и писать скрипт. Powrshell кажись тоже там умеет. >>1874945 r+ тебе нужен. Ну а вообще если файл большой, и надо активно мелкие моменты в нем менять - изволь делать через mmap, но если ты начинающий, то даже не связывайся с этим.
>>1875935 Вообще UB. Ты не знаешь точно когда компилятор может всунуть инкремент - после всего блока вычислений три раза, или после каждого взятия значения из b. https://ideone.com/QrjJty
Как работает выравнивание? Если я в мейне объявлю char x; и int y;, то x находится по адресу 10, а y - по адресу 11. Разве не должно быть какого-то выравнивания в памяти? То есть, почему y размещается по адресу 14? Ведь на 32 бит системе, машинное слово составляет 4 бита. То есть проц не сможет обратиться к 11-му адресу, ибо он читает по 4 бита, а 11 не кратко четырем. Или я что-то не так понимаю?
Сап, программач, начал изучать С и не понимаю одну вещь. Как я понял, когда инициализируем переменную к примеру
long i = 5 + 3;
То сами 5 и 3 перед тем как быть посчитанными и стать i принимаются за int, если не хватает места то unsigned int - long - unsigned long - long long - unsigned long long. Так вот в чем смысл добавлять суффиксы к этим статическим числам типо ULL (unsigned long long), если язык сам это делает автоматически? Не понимаю зачем это нужно именно с интами, с числами с плавающей точкой понятно, там изначально все числа даблы и если хотим сэкономить память, то используем флоаты при вычислении. В итоге контролируем не только к какому типу приводить, но и с каким вычислять. Но насколько я понимаю с интами все наоборот и изначально отчет стартует с самого минимального типа инта, и сам приводится автоматически к нужному типу. Так зачем это нужно? Сэкономить не выходит очевидно.
>>1876845 > Сап, программач, начал изучать С Рекомендую дальше продолжать изучение и искать смысл для каждой возможности этого чудесного и максимально простого языка. >Так вот в чем смысл добавлять суффиксы к этим статическим числам типо ULL (unsigned long long), если язык сам это делает автоматически? Чтобы подсказать компилятору как лучше сделать, очевидно же. Если ты пока не столкнулся с проблемой, это не значит что ее нет.
>>1876911 Ну меня конкретные случаи применения интересовали.
>When you declare a decimal integral literal in C, the compiler treats it as the first integral type that can hold the value, checking in the following order: int, long int, long long int. But your number is so large that it can not fit the signed long long type. To get rid of the warning, define the literal explicitly as unsigned by adding U or u.
Как я понял есть два случая: 1. Когда проводим вычисления и мы перелетаем границы типа при этом используя два младших типа (int + int = int, по логике компилятора, но это может быть и лонг, поэтому хотя бы один литерал нужно обозначить как лонг, чтобы производилось приведение типов, если у нас такой случай.) 2. Когда литерал больше типа long long, то есть unsigned long long, тогда достаточно просто поставить U или u и компилятор поймет, что имеется ввиду unsigned long long.
Короче учебник неверную информацию предоставил о поведении компилятора, мол литералы приводятся прям до unsigned long long, хотя выше long long нужно уже вручную обозначать и особой разницы между ULL, UL, U нет, они только в выражениях играют роль, если приводить надо.
>>1876815 У операции "присваивание" приоритет выше, чем у постинкремента. У постинкремента самый низкий приоритет. Покажи мне компилятор, который посчитает это выражение как 6 и 4.
>>1877035 >Это какой-то феерический пиздец с ключами. Что с ними не так? >Где вы такие "компиляторы" находите? Обычный онлайн компилятор. Написал в нем, потому что пк не под рукой. >>1877036 Чтобы явно показать, что следующий адрес на единицу больше в десятичной системе. В общем, для наглядности конкретного примера, не более.
>>1877020 >У постинкремента самый низкий приоритет. Это неважно, потому что в данном случае важны точки следования (sequence points) а их тут нет Это UB (Undefined behavior), неопределенно поведение. Оно не определено, хоть и не является ошибкой. Компилятору на вход дали мусор, компилятор может выдать мусор. Более того, сегодня он тебе выдаст 1 и 4, а завтра ты допишешь какую то функцию, оптимизация поменяется, и выведет что то другое - why not? >Покажи мне компилятор, который посчитает это выражение как 6 и 4. Clang, GCC.
>>1877037 Вряд ли на хосте того веб-компилятора используется восьмибитный проц. Ниже результаты msvc и gcc. В обоих случаях компилировалось под x86 32-бит. Видно, что char всегда располагается по нечетному адресу, а int - по четному (возможно, кратному 4-м). Чем это обусловлено? Еще раз повторю вопрос: разве не должно применяться принудительное выравнивание памяти по 4 байта на 32-бит и по 8 байт на 64-бит, дабы соответствовать машинному слову? Ведь так процу на 32 бит придется бегать не по 4 294 967 296 адресам, а по 1 073 741 824 фрагментам по 4 байта. Я вообще раньше думал, что так и работает. Но факт того, что char'ы размещаются в нечетных адресах уже приводит к тому, что разметка наебется. Плюс, чел >>1877041 говорит, что x86 может обращаться к любой ячейке. Если по умолчанию компиляторы для x86 не включают выравнивание в ОЗУ, то нахуя они это делают в структурах, например?
>>1877048 Я хз, что за компилятор там используется и с какими ключами он запускается по умолчанию. Вообще, такие вещи касательно выравнивания как-то описываются в стандарте языка? Или это уже приколы компиляторов и только?
>>1877046 Процессор всё равно будет выбирать с шины или из кэша целым словом. Ради теста сделай два char, а затем int Наверняка в памяти каждое из них будет в границах 4-х байт. А уже как внутри этих 4-х байт будет выровнен char это уже дело десятое.
Хотя... с другой стороны, если приведёшь неыровненный указатель к указателю на int, то получится чушь. Странно. Но проверять лениво.
>>1877058 >такие вещи касательно выравнивания как-то описываются в стандарте языка?
va_arg должен понимать выравнивание и он платформо и системо зависим. Но видя какое выравнивание тут постят троллят вестимо, лучше всегда смотреть что сгенерировал компилятор, когда выравнивание критично.
>>1877060 >Наверняка в памяти каждое из них будет в границах 4-х байт. Да, так и вышло. Если добавить еще три чара, то адреса будут: 41 - char 40 - char 39 - char 38 - char 34 - int (с 34-го по 37-й байт -- 4 байта) То есть фрагменты действительно по 4 байта, если объявлять char компилятор ставит его в самый последний байт фрагмента. Т.е., фрагмент в 4 байта заполняется от начала к концу. >Хотя... с другой стороны, если приведёшь неыровненный указатель к указателю на int, то получится чушь. Странно. Но проверять лениво. Почему чушь? Указатель же может в любой адрес указывать. Тип, на который он указывает, нужен лишь для адресной арифметики.
>>1876309 Выравнивают структуры. Зачем одинокую переменную выравнивать? Нету смысла. Более того, есть команды во всяких армах/riscv которые могут делать load/store для байтных значений. По твоей логике выходит если у процессора машинное слово это 4 байта, то он с другими типами не должен иметь возможности работать и нужно городить костыли? На пикриле можешь увидеть как компилятор спокойно кладет по адресу SP + 31 значение char командой strb. И ничего плохого не случается.
Пытаюсь написать трубу du myfile . | awk '{print $1;}', чтобы был вывод типа 4 180 Что надо выводится, но awk продолжает принимать на вход строки с клавиатуры и не спешит завершать работу. Почему так и как его заставить сдохнуть после вывода этих двух чисел?
>The attached kernel patch (applied on top of 4.18.5) that I've tried, almost completely eliminates the disk thrashing(the constant reading of executable(and .so) files on every context switch) associated with freezing the OS and so, with this patch, the OOM-killer is triggered within a maxium of 1 second when it is needed, rather than, without this patch, freeze the OS for minutes
сап, глупый вопрос. Учусь в ПТУ на 09 02 03. Основной язык программирования у нас Си , а также параллельно Js c php и SQL. Таки вот это рассчитано лишь на 1 год обучения. Что будет ждать меня на следующем курсе? Неужели C++ или C#. Или продолжим зубрежку? Поделитесь опытом с зеленым, как у вас проходило обучение в ПТУ.нет, программы на следующий год нету, только 1 год существует в моей мухосране ПТУ где обучают программированию(конкретно на базе 11 класса) Не бейте плиз, просто ответьте.
>>1878409 Запомни, учишься ты сам. А пту/универ/остальная шарага нудны чтобы подтянуть слегка уровень в общем развитии и найти людей с такими же взглядами как ты. Без разницы что дальше изучаешь. Можешь вообще хоть забить, не ходить туда. Главное самостоятельно обучаться.
>>1878437 Я так и делаюмои бивисы некоторые еще до массивов не дошли, лол, но просто интересно, что ждет дальше? Какой язык программирования будет, или последующая зубрешка си'шки и js. Просто хочу знать и да, и смешно слушать про саморазвитие и т.п в си треде, лол.
>>1878437 >Запомни, учишься ты сам. Да. >А пту/универ/остальная шарага нудны чтобы подтянуть слегка уровень в общем развитии и найти людей с такими же взглядами как ты. Лолнет. Учебки не учат, а калечат. Это такой фильтр/экзамен на "взрослую жизнь", принуждающий делать всякое бессмысленное говно уровня копать от забора и до обеда "потому что важный начальник (здесь препод) скозал нада" молча повинуясь, и заодно вертеться в обществе, выкручиваясь с оценачками и прочей поебалой, чтобы не делать всё как честный дурак и не сдохнуть от стресса в результате. В итоге выходят годные члены общества - рабочие мураввьи, без мозга, но исполнительные и умеющие в коллектив, где можно - откосить, кому нужно - подсосать, и так далее. Вот что учат все эти учебки.
>>1873113 (OP) Сап байтоебач. Дублирую пост с C++ треда. >>1879047 → Есть функция на Си и ее интерпретация на асме, пик тотали рилейтед. Казалось бы, компилятор должен выделить 16 байт под буфер и 4 байта под флаг, и тогда стек должен выглядеть как на рисунке 1, но нет, он выглядит как на рисунке 2. А именно -- флаг, 12 байт непонятной хуйни, 16 байт буфера, 8 байт указатель (типа в регистре он их оставлять не хотел) и еще 8 байт выделенных хуй знает зачем. Больше всего меня беспокоят 12 байт между флагом и буфером, т.к. от этого зависит, как будет работать эксплойт через переполнение буфера. Через компилер эксплорер код прогнал, гцц и клэнг выдают примерно то же самое. Пока что нагуглить смог только canary value, но не уверен, что это оно.
Я не понимаю, почему нельзя избавить стандарт C от ub. Вот, например, такой код:
int b = 1; b = ++b;
Я так понимаю, значение b может быть 2, если пре-инкремент прибавит к b единицу и вернет полученное значение, которое затем будет присвоено b. Или же b может быть равно 3, если будет отдельно посчитано значение b+1 (без изменения значения b), и уже после того, как полученное значение будет присвоено b, выполнится инкремент. То есть, либо это сработает так
b = b+1; b = b + 1;
либо так
b = b + 1; b = b;
Вопрос в том, почему нельзя уточнить этот момент в стандарте? Например, обязать реализацию выполнять преинкремент сразу, и не считать b+1 отдельно. Неужели, эта проблема не решается?
>>1879065 >это паддинг Понял, спасибо. Забыл сказать, что компилировалось скорее всего с флагом -fno-stack-protector. Нагуглил, что gcc выравнивает стек по 16 байт. Т.е. там получается как на картинке пикрилейтед слева? Почему он не может сделать как второй вариант? Гцц без флагов оптимизации просто в тупую выделяет переменные по одной и каждый раз делает алигнмент, вместо того, чтобы выделить сразу все и сделать алигнмент для всех? Второй вариант расценивается уже как оптимизация? Олсо, попробовал флаг mpreferred-stack-boundary=3, я думал, что он выдаст третий вариант, но раздутый пэддинг никуда не пропал, как будто гцц вспомнил, что стэк баундари равно 3 только когда отнял из rsp 40 байт. >>1879104 >размер слова в стеке равен разрядности процессора. Так тут все равно лишнее место получается, даже если выравнивалось по 8 байт. >Ассемберный код не соответствует картинке с исходником. Не понимаю, о чем ты, compiler explorer почти идентичную залупу выдает. https://godbolt.org/z/nTqYen
нужно получить сертификат на sololearn по С курсу,но я не знаю английский и не хочу вникать в суть так как мне это не очень нужно.Вопрос???? где найти готовые ответы или может есть другие варианты
>>1879285 Либо перестаешь пользоваться scanf и переходишь на какой нибудь fgets Либо затыкаешь варнинг, задав #define _CRT_SECURE_NO_WARNINGS как там написано
>>1879285 А, ну что касается первого ворнинга, scanf возвращает количество распарсеннгого, то есть ты можешь обрабатывать ошибки int read_x = 0; do { read_x = scanf("%f", &x); if(read_x == 0) printf("ошибка ввода бла бла"); } while (readx == 0 && ready == 0);
>>1879250 Получается так. >>1879338 Это flag, я не весь код скинул, а только фрагмент, который меня интересует, дальше там условные переходы. Без -fno-stack-protector кстати там реально будет лишняя переменная, видимо защищающая стек от повреждения.
>>1879325 так нахуя тут проверка? Явно человек учиться и до циклов не дошел, а ты его грузишь лишней инфой. Да и проверка на дурака нахер тут не нужна в реалиях.
>>1879357 Он спросил что у него за ворнинг. Там прямым текстом написано что программист игнорирует возращаемое значение. Я написал зачем эта функция что-то возвращает.
>>1873113 (OP) ЯННП. Объясните пж. Вот у меня есть файл yoba.c. К нему я инклюжу yoba.h. Так вот, в файле yoba.c у меня было несколько переменных и функций с идентефекатором static и все компилится/билдится. И я часть из них перенес в файл yoba.h и прога все равно компилтся без ошибок. Но какого хуя? Ведь идентефикатор static делает видимость только в пределах одного файла, почему тогда функции и переменные, обозначенные в файле yoba.h видны в файле yoba.c????
>>1873113 (OP) Няшки подскажите, на сколько рекурсия отсасывает в производительности? У меня есть рекурсивная функция, четкая и красива, а вот переписать ее это получается ебаный нечитаемый ад.
>>1879730 Сравни количество слов, сохраняемых на стеке с тем, сколько будешь сохранять после переписывания. Есть разница в разы? А глубина рекурсии какая?
>>1879765 >А глубина рекурсии какая? Не более 5 >сколько будешь сохранять после переписывания Я там сам стек заводил пихал туда состояния и я ебанулся за ним следить, код превратился в нечитаемое говно и мой мозг поломался
>>1879671 >на сколько рекурсия отсасывает в производительности? С чего бы это? Если не гоняешь по стеку большое количество аргументов функции, то рекурсия вполне хороша.
Ну а так считай сам - на первом входе будут Page Faults при росте стека. Но дальше эта память твоя и просадки по скорости не будет.
>>1880562 Точно, ещё и локальные переменные к аргументам добавляются. Но всё равно стек "дрочится" только единожды. Дальше виртуальные страницы стека уже отображены процессу и всё быстро работает.
>>1880701 Виртуальную машину. Не полностью, а просто выполнение инструкций. Без прерываний, без видео и любой периферии - просто виртуальную машину, чтобы умела по шагам выполняться и показыват текущее значение регистров, верхушки стека и по желанию дамп памяти.
Цель отобразить массив nums в обратном порядке. Какого хуя ошибка сегментации вылетает? Судя по отладке с помощью printf проблема где то ещё на чтении чисел. Хотя scanf допускает применение нескольких спецификаторов через пробел.
Собираю модуль ядра, большую часть исходников kbuild собирает сам, но некоторые мне нужно собирать самому в особом виде, а потом подкладывать объектники просто. Типа filename.o_shipped
Но вот проблема, kbuild хочет .cmd файлы иметь для всех объектников. Якобы, чтоб как-то проверять что-то связанное с необходимостью пересборки. И он их сам генерит, если сишники сам собирает. Но для готовых объектников не генерит. Я воткнул везде touch .object_file_name.o.cmd - помогло. Но это вроде как костыль. Знает кто?
Приветствую. Как написать прокси-сервер для игры на Winsock2? Обязательно ли ставить ловушку на функцию connect или можно как-то из ловушки WSASend / WSARecv передавать данные на мой сокет а потом с него уже на клиент / сервер? Помогите пожалуйста.
Почему пикрил 1 код работает как надо, а пикрил 2 выдает ошибку пикрил 3? Ведь по сути они делают одно и то же, какая разница, передать указатель и разыменовать его, или передать структуру? (Про -> знаю, записал именно так для наглядности)
>>1882729 Потому что во втором случае создается копию структуру и инициализируется. Изначальный объект, который в main, при этом остаётся неинициализированным.
>>1882777 > Потому что во втором случае создается копию структуру и инициализируется. Изначальный объект, который в main, при этом остаётся неинициализированным. Не понял. Как инициализация зависит от вызова функции где-то дальше по программе?
>>1882785 Ты вызываешь InitStack, где полям структуры присваивается значения, в том числе происходит аллокация памяти. После выхода из функции копия структуры уничтожается (а память утекает).
struct stack s остаётся дефолтным, с не инициализированными полями, без аллоцированной памяти.
Кто-нибудь может пояснить за conversion specifier %g? Как я понимаю он сравнивает результаты %e и %f и выдает наиболее короткий. Только можно ли к нему применять аргументы в стиле %5.2g? У меня фигня какая-то выходит на этом моменте.
>>1882785 В параметрах функций всегда передается не то, что ты в них пишешь, а делается его копия и уже эта копия отправляется в параметр. Таким образом, функция получает копии, а исходная сущность всегда остается неизменной. То есть, если ты отправляешь константу, создается переменная (параметр) с этим значением. Если отправляешь переменную, создается копия этой переменной. И не важно какой тип. Если переменная int, создается новая переменна int, если указатель, создается новая переменная указатель, если структура, создается новая структура. Параметры функций (переменные-копии) существуют пока работает функция, когда функция завершается, они естественно уничтожаются.
Исключением являются массивы, которые вроде как не копируются, а передаются по указателю, вопреки тому, что передаешь именно сам массив, а не указатель. Но массивы это вообще особенный феномен, наговнокоженный вопреки логике языка. Массивы надо учить отдельно, как ебанутую хуйню, просто потому что есть в языке такаой бред и надо смириться.
И возвращаясь к началу, в крестах таки можно передавать в параметр саму сущность, а не копию, для этого там есть ссылки. Но в си ссылок нет, тут для изменения исходной сущности передают указатель на неё.
пацаны, я новичок в си и у меня появилась проблема: при вводе через scanf буквы(задумана цифра) начинается бесконечный вывод printf'a, как с этим бороться?
Привет анончики. Есть задачка, нужно создать прогу которая будет подставлять слова в конец файла, задача в том чтобы создать нумерацию добавленных слов по порядку и при повторном заходе в программу нужно чтобы порядок возобновлялся с того же места 1 слово 2 слово 3 слово
Я так понял использовать нужно бинарный формат, я создал отдельный файл для этого в бинарной форме, через fwrite вставил туда переменную которая сохраняется каждый раз при закрытий программы, т. е задача решена. Но я хотел бы поинтересоваться, могу ли я использовать один файл для сохранения этой переменной не создавая второй? И как это сделать? Открыть этот же файл в текстовой форме и присвоить на один указатель на файл, а бинарную форму на второй указатель?
>>1883470 Scanf не занимается выводом >>1883620 Как тебе пришла в голову светлая мысль про бинарный.формат? >>1883738 И какой по твоему должен быть sizeof обычного указателя?
>>1883812 >>1883816 потому что если не пердолишь то нет смысла сидеть на хуевой кастрированной глючной версии винды когда есть собственно винда а раз пердолишь то и такие базовые вещи умеешь
>>1883824 Я не понимаю тебя. Причем тут ОС и доступ к файлам через язык программирования? Ты о чем вообще? Я учусь. Мне нужно через stdlib создать файл в который будут добавляться слова после ввода и печатать в каком порядке были добавлены слова.
>>1883803 Ну ты скорее всего не понял задачу, спроси у учителя. Очевидно что ты можешь просто прочитать файл по одной строке и сосчитать таким образом их количество. Или ты можешь прочитать последнюю строку и распарсить число которое у нее в начале.
>>1883856 Ага, уже сообразил. Проще было посчитать количество строк. А вообще как это работает с fprintf, fwrite? Если юзаешь fprintf то пишешь в текстовый режим текст, а fwrite или fwrite то только в бинарном сохраняешь данные правильно? Т.е я не смогу достать переменную сохраненную в текстовом режиме?
>>1883127 #include<stdio.h> #include <locale.h> void main(){ setlocale(LC_ALL, "Rus"); int a[100]; int n, i, b; puts("Указать размер массива:"); scanf_s("%d", &n); puts("Эллементы массива:"); for (i = 0; i < n; i++){ scanf_s("%d", &a); } for (i = 0; i < n / 2; i++){ b = a; a = a[n - i - 1]; a[n - i - 1] = b; } for (i = 0; i < n; i++) printf("%d ", a); } Тоже новичек, но в пту так учили
>>1883993 #include<stdio.h> #include <locale.h> void main(){ setlocale(LC_ALL, "Rus"); int a[100]; int n, i, b; puts("Указать размер массива:"); scanf_s("%d", &n); puts("Эллементы массива:"); for (i = 0; i < n; i++){ scanf_s("%d", &a); } for (i = 0; i < n / 2; i++){ b = a; a = a[n - i - 1]; a[n - i - 1] = b; } for (i = 0; i < n; i++) printf("%d ", a); }обосрався
>>1879558 .h это заголовочный файл, если ты включил заголовочный файл в .c файл то он исчезает при комплияций и становится единым целым с исходным файлом, по крайней мере так видит это компилятор. Если ты используешь static в заголовочном файле, то ты не напрямую получаешь инфу, а копируешь. Если бы ты использовал static в другом исходном файле и пытался получить доступ с другого, компилятор бы тебя не понял, потому что для него это слепая зона.
Зашел в этот тред случайно. Никогда не писал на C, но накидал тут что-то. >>1883998 >>1883127 Нахуя создавать reverse массив, если вы пишите, что его нужно просто вывести в обратном порядке?
#include <stdio.h>
int main() { int i,n;
printf("Введите размер массива: "); scanf("%d",&n); int nums[n];
for (i=0;i<n;i++) { printf("Введите %d элемент массива: ",i); scanf("%d",&nums); }
printf("Заданный массив в обратном порядке: ");
for (i=n-1;i>=0;i--) printf("%d ",nums); return 0; }
Нихуя не понимаю. Почему я не могу записать бинарные данные в текстовый формат? В один файл? Я использую fprintf, чтобы вписать строки в файл, если я напишу бинарную переменную через fprintf, я смогу ее сохранить в бинарном формате потому через fwrite? Потому что когда я пытаюсь так сделать, она становится мусором по какой то причине.
>>1884358 Ну переменные в бинарном формате, т.е они сохраняются так как компьютер их видит. Есть текстовый формат, в котором сохраняется только текст, а есть бинарный в котором может сохраняться и текст и переменные но в бинарном виде.
>>1884358 Короче могу ли я сохранить переменные в текстовом файле, вот в чем вопрос. Можно же как то раз предполагается, пишут что в текстовом файле можно сохранять бинарные данные.
>>1884360 >>1884359 Нет текстового и бинарного формата, все хранится в бинарном, просто твой текстовый редактор будет отображать бинарные данные говном, юзай hex-editor.
>>1884360 Что тебе мешает сохранить переменную текстом? Что по твоему случится с переменной в бинарном виде, если твой текстовый файл откроют блокнотом, поменяют пару строчек, а потом сохранят?
>>1884405 Спасибо. Я снова прочитал различия, в юниксе их нет для файла оказывается. Но вот почему когда я пытаюсь вытащить переменную из текстового файла, при этом сохраняя её через fwrite, выходит мусор при использований этой переменной типа -123123123123123123? Влияет ли на это использование fscanf и fprintf?
>>1884406 Ну смотри, мне нужно достать из файла эту переменную потом, нужно писать функцию которая будет искать внутри текста это число, потом конвертировать его через atoi? Аааа ничего не понимаю. Кто нибудь подскажите я смогу посмотреть через дебагер что творится внутри программы в плане просмотра содержимого буфера итд?
Про мейкфайл не нашёл лучшей ветки спросить: В моём мейкфайле есть куча одинаковых команд, с разными таргет/пререквизтами Application.o: Core/Application.cpp $(CXX) $< -c $(INCLUDES) -o $@ Log.o: Logger/Log.cpp $(CXX) $< -c $(INCLUDES) -o $@
Как записать это в одно правило? Везде пишут %.o: %.cpp, но мне не нужно для всех целей, а только для определённых, плюс непонятно, как dirname отбросить для таргета.
Где есть какой-нибудь быстрый гайд по Си? Есть одна библиотека, но так как в елиспе нельзя подключать Си библиотеки, решил написать на программу на Си и вызывать её из елиспа.
>>1884481 Рекурсия на стеке. Представь себе колоду карточек Ты пытаешься считать число и если получилось, то записываешь его на карточку в поле n Когда числа закончились, ты начинаешь выводить записанное на верхней карточке n, а потом скидываешь эту карточку открывая ту что под ней.
>>1884491 Для начала определись что такое красивый код, когда выведешь формальные критерии - их и придерживайся. Вообще C маловыразительный язык, поэтому красоты в нем мало.
Почему в сишечку ни в каких новых стандартах не хотят ввести деструкторы в каком-нибудь виде? Да хоть слизнуть у конкретного комипилтора. Там же есть всякие директивы компиляторам. Почему не ввести еще одну типа destructor, что когда ее объявляешь для какого-то типа (а у нас он будет один - это пользовательсая структура), то вызовется эта данная функция. Т.е. будет что-то вида destructor my_struct f() { // что-то делаем }
>>1884835 upd: это же по сути никак не изменит язык, не переусложнит его. Он же и сейчас отслеживает, когда структура выходит из области видимости и выкидывает ее, а так просто при создании ассемблерного выхлопа перед этим освобождением бы всовывал имеющуюся деструктурную функцию.
>>1884842 Речь про C и его все новые стандарты 11/17/2x.. Почему все не вводят и не вводят такую мега удобную вещь. Это же не испортит старую кодовую базу никак, не добавит накладных расходов.
>>1884863 Ну так и в чем изменится его нелинейность при создании на этапе компиляции ассемблерного выхлопа? Просто вместо освободить память у базового типа удет вставляться при необходимости вызов еще одной функции. Ну вот как в это gcc, например. Почему не берут очевидную полезную и нужную вещь в стандарт. Это же избавило бы от кучи возможного забытия очищения памяти, не добавляя никаких накладых расходов.
>>1884918 плюсы с растом сейчас плюс-минус на одном уровне по скорости, и - да, в крупных сложных проектах, а не линейных алгоритмах, они обгоняют уже сишечку по скорости из-за того же отсутсвия расходов для некоторых действий в рантайме
>>1884866 Нелинейность будет не в ассемблерном коде, а в программе на Си. Появляется неявный вызов не в той точке, где он написан. Ну это как... Исключения в c++.
>>1884951 Так кому не надо и не будут этим пользоваться, а вот кому из-за отсутствия деструкторов библиотеки приходится переусложнять и апи для них, что потом пользователям надо помнить не забывать делать free для кучи вещей, хотя это можно было бы от них скрыть - это сильно бы помогло.
>>1884962 в смысле, ну так это такая же функция. Вот ты вызвал из сторонней либы f() ты же тоже не знаешь, что она под капотом делает и что вызывает. Поэтому читаешь доки или смотришь код, где уже и видешь, что именно оно делает. Если тебе в твоем коде это не нужно, то и не используешь никак. Ну во всех компиляторах это есть в том или ином виде, просто нужно это стандартизовать.
>>1884835 Ты хочешь разменять протечку по памяти/ресурсам на потенциальную протечку по памяти при отсутствии деструктора и потенциальный UaF при его наличии. Спизди себе набор _cleanup_ макросов из systemd если очень надо.
>>1885035 > Спизди себе набор _cleanup_ макросов из systemd если очень надо. Куда я его спизжу, если он не на всех компиляторах работает. > на потенциальную протечку по памяти при отсутствии деструктора и потенциальный UaF при его наличии. утечка будет только в том случае, если предоставляемый код был кривым, от этого ты и так не застрахуешься снимается возможность забыть пользователем освободить ресурс соответственно при его отсутствии мы имеем все как было, при его наличии всего лишь выполнется +1 функция, которую не пользователь вынуждено вызывает ручками, а она сама на этапе компиляции вставится
>>1885041 Нет, ты не понял. Тебе всё-равно ВСЕГДА нужно будет проверять не забыл ли ты конкретно для этой структуры определить деструктор. А заодно и для вложенных полей этой структуры (их нужно удалять в своём деструкторе или нет, как считаешь?). Кстати, если так подумать, то нахуй тебе деструктор, если у тебя и конструктора нет? Если в структуре хранится что-то что надо чистить, то это что-то всегда было передано извне и сруктура этим не владеет и не может почистить сама. И ты прелагаешь непонятный костыль, который приносит в код UB.
> Куда я его спизжу, если он не на всех компиляторах работает. Ну сорян, сделай ifdef и крэшся если собирают не шлангом с gcc.
>>1885046 так UB появиться неоткуда, из минусов только чуть дольше происходит компиляция
ну конструктор еще можно пережить, в крайнем случае пользователь условную функцию init не забудет вызвать, т.к. делает это прямо здесь и сейчас, а вот потом где-то там освободить ресурс - постоянно
ну вот есть допустим структура, а в ней вектор есть динамический функции есть для работы с этой структурой типа добавить элемент/удалить а вот при выходе самой структуры из области видимости пользователи часто забывают вызвать условное free() для этой структуры поэтому и говорю, что очень часто не хватает деструкторов (хотя напоминаю, что почти во всех компиляторах они есть, с разными названиями)
>>1873113 (OP) Двач, не гони меня тряпками, а лучше объясни. Без какого либо бэкграунда начал вкатываться. Пытаюсь осилить курс CS50, смотрю как украинскую так и ангельскую версии лекций. Собственно вопрос в PSETe 1, а именно mario. У меня получилось сделать задание, но я его всё написал через printf, понял, что получилась стена говна и пошёл в интернет. Нашёл пикрелейтед и нихуя не понимаю. Как работает этот алгоритм. Знакомых которые могли бы объяснить у меня нет. Если можно, то прям как бабуину на пальцах. Cпасибо.
>>1883289 > Исключением являются массивы, которые вроде как не копируются, а передаются по указателю, вопреки тому, что передаешь именно сам массив, а не указатель. Но ведь "сам массив" и есть указатель на его первый элемент, вроде все логично, нет?
>>1885051 >так UB появиться неоткуда, из минусов только чуть дольше происходит компиляция Если ты неправильно отследил кто владеет памятью и почистил её, то возникает UaF и что в программе произойдёт дальше тебе никто не гарантирует. Также пользователь либы может вытащить из твоей структуры указатель, которым не владеет, и сохранить у себя.
> ну вот есть допустим структура, а в ней вектор есть динамический > функции есть для работы с этой структурой типа добавить элемент/удалить Без внятной концепции владения деструктор только сделает хуже. Тебе не деструктор нужен, а умные указатели. Я не пробовал - https://github.com/Snaipe/libcsptr
>>1885078 почитаю всю ветку, я вообще не о том спрашиваю как кому-то что-то сделать в конкретном случае, я про стандарт и его развитие и про причины торможения
>>1885061 Всё просто, на пикрелейтеде написана полная хуйня, которая скорее всего и не работает. Держи - https://ideone.com/VxBsws Тут всё просто, сам разберёшься.
>>1885061 >>1885069 В программировании стараются избегать повторения кода, поэтому придумали циклы. Цикл for выполняется от, до (пока условие соблюдается), и с шагом. Внешний цикл выполняется size раз, рисуя строчки. В конце каждой строчки рисуется перевод на новую строку. Внутренний цикл выполняется _для каждого шага внешнего цикла_, size раз Внутри него рисуется по 1 символу (пока забьем на условие), таким образом у тебя будет нарисована таблица size на size. Остается вопрос какой символ рисовать, закрашенный или пустую клеточку. Для этого грубо говоря складывают x и y координату. Можешь проверить в тетради в клетку. Примерно так: если строка 23, то нарисовать можно только в столбце 0; если строка 22, то логично что можно нарисовать в столбце 0 и 1; если 21, то в 0, 1 и 2; и так далее.
>>1885080 Ещё раз ты просишь деструкторы, не понимая зачем они появились в плюсах, для задач которые деструкторы нормально не решают впринципе. Никто такую хуйню в стандарт тащить не будет.
>>1885092 плюсы тут ни при чем, это ж просто концепция, а тут она более чем востребована и опять же всеми разрабами компилатор уже как-то да запилена, но каждый написал свой костыль и поэтому почти никто не пользуется
>>1885094 Помню читал такой срач и там чуваку просто скинули ссылку где вступить в WorkGroup чтобы официально давать предложения в стандарт :3 Погугли, запплайся, напиши, вдруг добавят.
>>1885112 в интерпретируемых - да, в работающих уровнем пониже - пока не получится избавится, т.к. железо разное и его поведение разное, порой принципиально
>>1885094 Ты эту концепцию сначала опиши нормально. >>1885096 > UB Есть один нюанс. UB в стандарте появился не от балды, а потому что C - кроссплатформенный ассемблер под абсолютно разную хуйню с абсолютно разной реакцией на граничные ситуации которые потом и назвали UB. И когда ты решаешь UB ты по сути отрезаешь платформы. > почему никто не сделает диалект C без UB. Сделали кучу раз. Последняя попытка называется golang, можешь попробовать.
>>1885121 > Ты эту концепцию сначала опиши нормально описал выше уже подробно: возможность описать функцию, которая вызывается перед выходом объекта этого типа из области видимости. С примерами описал где она многим требуется и жалуются, что не хватает. И как разрабы, так и пользователи. Описал, что это ничего никому не испортит, а только добавит полезный функционал языку (видимо поэтому все почти разрабы компиляторов это уже сто лет реализовали)
int foo(void) { array a = { .data=malloc(10 • sizeof(int)) }; fill(&a); // <= заполняем check(a); // <= проверяем что заполнили printf("%d", a.data[0]); // <= UaF :( } ``` Вот абсолютно нормальный код, который с появлением деструктора стал крешится. Потому что в check передаётся копия структура, для которой при выходе из check вызывается деструктор и сносится data.
Чувак, серъёзно, что тебе мешает взять С++98 пожить с деструкторами и понять что в C они будут бесполезны, более того опасны? Я как будто с первокуром общаюсь.
>>1885133 пиздец.. ты вообще пишешь какую-то хуйню про другое. Ты или перечитай внимательно, что обсуждаем или уж не лезь тогда. А то повылезают из серии дишь бы что-то сказать, даже не пытаясь понять о чем речь. Ты еще как умник выше скажи про реализацию на языке умных указателей.
>>1885166 >А вот для умных деструкторов Чем умнее язык, тем тупее программист. А си не для дебилов. Поэтому умного говна и деструкторов в частности не будет.
>>1885217 Проблема современной цивилизации в толерастии. Тупому быдлу внушают, что все люди одинаковые, равны. В результате, дебилы лезут в треды умных считая себя такими же и кукарекают "то не так, это не так", не понимая, что это только от их тупости. Но указать некому, толерастия же.
>>1885092 Два чаю. Вот пример, когда человек просто хотел сделать сигнатуру чуть более правильной, добавив const на указатель, который и так не должен быть изменён: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2526.htm Оказалось, что это breaking, потому что компиляторы начали бы генерить предупреждения, а вендоры считают новые варнинги (даже семантически верные, даже не ошибка компиляции) ломающим изменением: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2565.pdf Правильно это или нет: хз, тут это философский вопрос
>>1885337 >Правильно это или нет: хз, тут это философский вопрос Правильно. Библиотека существует для пользователей, это не игрушка её разработчиков, которой можно вертеть как захочешь. Разработчик должен думать не о себе, а о пользователях. Если его изменения будут поводом высирания кучи варнингов где их раньше не было, это головная боль пользователям, поэтому так делать не надо. А свои "ну такжы лучшы!" можешь в анус себе засунуть, это типичный лепет тупых эгоцентричных малолеток.
Сап Керниганы и Ричи, помогите найти годные книги или на крайняк татуриалы на тему геймдева на Си с меня нихуя как обычно. Пробовал гуглировать, но либо нахожу таки код на крестах, либо какие-то демки 1989 года под ДОС, либо нихуя, так как попробуй нагуглить что-то с просто символом «C». Хотелось бы чего-то современного, с ECS, дата ориентед дизайном, Vulcan/Metal хотя сейчас подумал что там наверное апи уже под плюсы/обжективные плюсы минимум. Выручай анон.
Тут могут быть объёбы? Чего я хотел этим добиться: по состоянию флага нужна подмена символа, входящего в массив строк, для поиска по новому - подменному значению в строке. Реализовал как мог.
Беда вот какая: как только отработает этот код, следующая за ним функция (работающая с джи-сон) виснет, вешая весь цикл.
Ещё есть либа cJSON, которая используется для пакинга \ парсинга джи-сон строки: https://github.com/DaveGamble/cJSON Но там вобще мрак и я не знаю как её проверить.
>>1885747 Короче на Гите в awesome C есть ссылки на ресурсы. Но я знаю один ресурс в котором объясняют на пряниках всё про векторы и так далее. Но там очень тяжело. Позже скину.
>>1885061 Как я рад что был прав на счёт CS50, такой раковый вброс. Они даже код писать не могут, более того учат своих студентиков писать некачественный код с умершими конструкциями которые никто не использует. Кому нужен do while в 2021? Ну если только для макросов каких нибудь и то не знаю, не использовал.
Ку анонче, вообщем это опять я с файлами и прочим своим говном. У меня есть файл в котором символы, мне нужно взять этот файл, подставить после каждого символа пробел и сохранить в этом же файле. Пока что не получается, только сохраняя в новый файл. Переписать прошлый не получается.
Вроде работает, можете посмотреть на ошибки и моменты которые можно исправить? Или есть ли идеи как получше написать циклы и т.д? Щас буду писать версию с уравниванием значений в массиве, типа если у символа есть разница более чем на единицу с соседом, то нужно будет поставить среднее значение между ними.
Кто-нибудь может подкинуть ресурс почитать про то, как работает printf с format specifiers? Вот к примеру я хочу вывести signed char, на экран (и использую вместо %hhd, %hd), тогда printf должен считать не 1 байт, а 2 байта начиная с точки, где хранится число захватив предположительно участок памяти с рандомными значениями сделав UB (читал, что такое точно происходит в учебнике, но там несколько значений выводилось), но он просто продлевает лишними нулями до размера signed short число типа signed char. Зато когда суем signed short в signed char, у нас случается integer overflow, если не помешается число в тип. Так что именно происходит? C продлевает число до нужного типа или все таки не продлевает и просто выводит то, что было в памяти согласно размеру типа?
>>1886113 Ну короче там есть ячейки памяти, каждый спецификатор выделяет определенную память согласно размеру типа. Если int 4 байта, если вставишь вместо int - long размером 8, то выведется половина, те 4 байта вместо 8. Если тип меньше спецификатора (поменяем long и int местами) то одна половина памяти будет просто нулями, а вторая значением которое тебе нужно вывести. Но есть проблема, незанятое пространство из первого спец. перенесется на второй соседний спец. если ты его туда поставишь. Либо он просто останется в памяти и тут UB.
>>1886113 Если совсем педантичный ответ дать, то смотри соглашения о вызове функций и то, как там реализован vararg. Например, вот выдержка из SystemV x64 ABI (стандартный линуксовый): >The prologue of a function taking a variable argument list and known to call the macro va_start is expected to save the argument registers to the register save area То есть у тебя копируются в память регистры и va_arg просто шагает по памяти. Указал va_arg(args, int)? Шагнули на столько-то байт в памяти. va_arg(args, double)? Шагнули на столько-то.
>>1886125 Если выводим signed char = 1 как %hd, то будет
|00000000| + |00000001| Просто продление до нужного спецификатора.
Если signed short = 1 как %hhd и потом еще один %hhd
То значение в памяти разделится на два? |00000000| |00000001| и будет выведено 0 и 1? А до второй переменной дело даже не дойдет. Ведь будет шагать от начала числа по заданному кол-ву байт. Что-то в онлайн компиляторе проверил, все равно все верно выводит.
У меня есть прога на плюсах где просто дохуя вычислений надо сделать. Она по времени немного не заходит. (Вычислений столько, что дано аж 7 секунд). Может ли смена крестов на си без использования всяких std::min улучшить ситуацию?
Вывод: 4 8 2 1, инт в два раза короче лонга, но когда подсовываем лонг и говорим читать как инт и затем еще инт он похоже читает с конца, а не с начала и нигде не спотыкается. Читал просто в учебнике как все это происходит, но даются две версии разные, в одной читается с конца применяя modulus или просто отбрасывая лишнюю часть, если в двоичной системе смотреть, а в другой (там где объясняется UB) наоборот говорится, что все стартует с начала по кол-ву байту соответствующему спецификатору. Не понимаю, в итоге компилятор то понимает, что от него хотят, то не понимает.
>>1886372 >инт он похоже читает с конца Ну так ты запускаешь скорее всего на x64 архитектуре с Little-endian. Попробуй с большими числами, не 1 а какое нибудь 0x13579246 >Не понимаю, в итоге компилятор то понимает, что от него хотят, то не понимает. А это в принципе неважно, потому что раз у тебя спецификаторы не соответствуют переданным аргументам, у тебя UB, а при UB компилятор не обязан ничего понимать. Так что то что ты исследуешь, это не какое то истинное свойство языка, а просто стечение обстоятельств, как это работает на каком то одном компьютере с каким то одним компилятором с каким то набором флагов компиляции.
>>1886422 Понял, спасибо. Как я понял, операция modulus точно происходит при конвертировании типов, но необязательно при спецификаторах форматов в printf, тут уже зависит от архитекторы и может быть по-разному. Лучше UB не делать играясь со спецификаторами и все делать вне printf с помощью арифметики. Я думал это как-то можно понять как пресловутый integer overflow, который вроде как ошибка, но в рамках логики.
Дядям в комитете нужно менеджить главный язык программирования этого чёртового шарика, который должен транслироваться в опкоды для всего: начиная от суперкомпьютера и заканчивая твоим вибратором. С такой ответсвтвенностью люди становятся оочень консервативными и действуют по принципу: "работает - не трогай".
>>1886698 Лол, долбоеб, дяди из комитета еще 31 год назад всех хардварщиков нахуй послали. Они нихуя не делают, только иногда собираются на свои сходочки и отклоняют предложения людей не входящих в СОВЕТ.
>>1887243 Именно поэтому сишка еще не растеклась в то бесформенное говно, в которое превратился соседний язык. Вон давеча в комитет притаскивали замыкания с маллоком внутри, это ж где я им маллок возьму, когда у меня на МК памяти два килобайта?
>>1887333 Никто и нигде последние лет 15 не использует сишку на мк, сдохнут легаси станки сдохнет и сишка. Вместе со своим профнепригодным комитетом. Ну а если ты на полном серьезе отрицаешь что комитет хуево справляется со своей работой то ты долбоеб
>>1887344 > Никто и нигде последние лет 15 не использует сишку на мк, сдохнут легаси станки сдохнет и сишка. Сам работаешь? А что тогда по-твоему используют? Трансо раст?
>>1885063 Нет, sizeof тебе не вернет размер адресного регистра целевой архиктуры. Просто в любых операциях компилятор подставляет константу либо вычисление по стеку адреса нулевого элемента.
бля, посоны, ламповый тредик у вас, аж захотелось вернуться в студенчество безработное чтоб с сями играться или устроиться по сабжу ага, правда все равно творчества будет не хватать
>>1887788 strcmp Конечно есть нюансы, такие как в разных локалях может быть другой порядок букв в каких нибудь европейских языках Или например если ты хочешь не лексикографический, а натуральный порядок, как в папках, чтобы file15 шел после file2.
>>1873113 (OP) Привет, аноны. Так вышло, что мне нужно так скажем распарсить строку. Вот пример
на вход дается строка CD , мне нужно чтобы что-то запустилось, если на вход будет дана CD и еще что-то. Например так if ( strcmp(line, "CD") == 0 )){ printf("odin") if (strcmp(line, "CD + пробел иные символы") == 0)){ printf("dwa");
как мне это сделать? вот пример пишу CD - просто переходит в домашний каталог и все пишу CD Desktop/Folder/ перейдет в соотв. место
Помогите, пожалуйста, уж силы иссякли ебаться с этим.
>>1888330 Если на вход идёт строка, то оно разве разбивает по пробелу ? То бишь если на вход CD, то это 2 символа, а если test, то это уже 4, но если cd test , то как выцепить инфу после пробела ?
>>1888330 Я просто к тому спрашиваю, что мне надо обрабатывать текст после предполагаемой команды, например чтобы разные настройки доступа менять и тд(пишу терминал)
>>1888358 argv изкоропки разбивает все аргументы, расспличенные одним и более пробелом Нулевой индекс включает в себя вызов программы e.g. ./a.out Зачем тебе сырые строки ковырять?
>>1888401 Говорю же, терминал надо написать, а в нем очевидно что ввод строки, на вход аргументами программы это не сделать, ведь он сделает 1 команду и все, а надо обрабатывать динамически. Если я сделаю функцию, которая принимает строку с стандартного входа как char *list[] , то обращаясь к скажем индексу 1 , разве я получу символы до первого пробела , ведь он отдаст первый символ и все? Понимаю, что это ебля ещё та, но надо.
>>1873113 (OP) Здарова, байтоебы, бля ну си конечно заебись язык ничего лишнего, да и ничего нужного, аля сам ебись придумывая связные списки под каждый пук. Короче си - говно без задач в современном мире, если только вы не пилите ядро линукс или драйвера, хотя и драйвера уже на с++ пишутся.
>>1888597 Лол, я на си в свое время много писал и много чего использовал, но ты сам то видел эти "готовые" либы? Это хуйня полная и неудобная.
Да и вообще какой смысл писать на си сейчас? Быстрее чем с++ это точно не будет, при разумном использовании последнего. А вот скорость написания, читабельность и емкость кода будет намного намного выше.
Почему при вычитании всех типов, кроме int, он конвертирует результат операции к этому типу? Потому что типа int на конкретно моей платформе самый быстрый и он соптимизировал?
Приведение типов это насколько затратная операция? Если я впишу условное (short int) x - y это скажется?
>>1888908 >Потому что типа int на конкретно моей платформе самый быстрый и он соптимизировал Да, размер инта зависит от платформы, но это всегда самый оптимальный тип.
>>1888440 >Говорю же, терминал надо написать, В смысле?
Получил строку и пользуешь функцию strchr(mystr, " "); Вернёт указатель на первый пробел или NULL, если пробела нет. Или создай массив указателей и разбивай строку на токены в цикле.
Пиздец вопросы. Пиздец ответы. Убить вас всех нахуй. Или отправить на лесоповал озеленять вырубленные площади.
>>1873113 (OP) Почему для того чтобы из буфера не читался \n в условиях проверки стоит while(getchar() != '\n') continue; Почему НЕ равно? Потому что оно в любом случае перейдёт в тру, т.к ты ввод нажимаешь, и вместо continue пойдёт проверка следущего символа буфера, т.е \n
Здравствуйте. Я полный нуб пришел к вам из ньюфаготреда. Мне нужно скомпилить вот это дело, желательно без установки и настройки тонн софта и докачки библиотек.
Помогите незнающему студенту. У меня задание сделать аницаию в openGL, с самой рисовкой я разобрался, только не знаю, как реализовать таймер/пропуск определённого количества времени. То есть я рисую 1 кадр, проходит 30 милисекунд и этот кадр должен нарисоваться ещё раз, но с изменениями, которые я прописал в программе.
>>1890671 >>1891050 Решил проблему, в библиотеке которая нужна для отрисовки была своя функция таймера, с запуском функции по окончании, нахер я с этим 2 часа ебался, если можно было так легко сделать.
void Time() { glutPostRedisplay(); glutDisplayFunc(renderScene); glutTimerFunc(30, Time, 0); }
>>1890974 Спасибо анон, но нихрена в итоге не получилось все равно. Для компиляции еще надо собрать библиотеку, этого я не осилил. Написал разработчику с просьбой скомпилять и он скомпилил.
Патч с реализацией мягкой защиты Active(file), с тремя крутилками. В настройках по умолчанию побочек не выявлено, в отличие от всех других вариантов. По умолчанию жесткая защита отключена, а мягкая соответственно действует весьма мягко, но ощутимо положительно при своппинге.
У меня есть структура состоящая из трех полей. Одно поле это значение, а другие просто какие то свойства (число от 1 до n). Допустим я отсортировал кучу таких объектов (n^n) по возрастанию значения. Теперь мне нужно сделать так: перебираю каждый объект и мне нужно посчитать сколько элементов, которые по значению меньше чем текущий объект и при этом у них ни одно из оставшихся двух полей не совпадает. Есть ли в программировании для этого какая нибудь структура данных для быстрого подсчета таких объектов?
Сап, программач. Пишу протокол обмена с железякой ARM. Объявляю enum cmd_type_t наподобие CMD_0001 = 0x0001U и т.п. несколько кодов команд. Компилятор для железки (GCC) успешно делает поле кода команд двухбайтовым, а такой же точно код на Винде (Qt) делает его четырехбайтовым. Запись CMD_0001 = (uint16_t)0x0001 не помогает. Упаковывание структуры pragma pack(push,1) тоже не дает эффекта.
Как заставить компилятор под комп сделать правильную разрядность cmd_type_t - два байта?
>>1891621 enum достаточно большой, чтобы вместить используемые в нём числа, плюс компилятор можно попросить упаковать его поплотнее какими-нибудь __attribute__ ((__packed__)) или -fshort-enums если загуглишь `sizeof enum`, первая же ссылка ведёт на stack overflow, где это всё написано
>>1889658 >>1889658 Твой буффер будет расположен в сегменте данных. Поэтому сигнал может быть сгенерирован если выйдешь за границу виртуальной страницы. Но пока не перешагнёшь границу страницы, исключения не будет.
БОЛЕЕ ТОГО! В сегмент данных попадают переменные из разных исходников. Т.ч. граница сегмента данных может далеко - при выходе за границы массивы ты просто прочитаешь или перезапишешь глобальные или статические переменные, обхявленные в других файлах.
Есть байт, третий и четвёртый биты в котором принимают значение: 0x00, 0x08, 0x10, 0x18.
Надо с помощью операций с битами вывести следующие значения: 0x00 => 3, 0x08 => 5, 0x10 => 7, 0x18 => 9. Т.е. если в байте третий и четвёртый биты равны 0x08, то надо вывести 5 и т.д.
Понятно, что какой-нибудь switch-case и маска 0x18 решили бы проблему. Но надо вычленить это именно битовыми операциями.
>>1892199 >А писать за пределы все равно незаконно. Наоборот. Си - свободный язык, позволяет очень много всего делать, и так и надо. Можно всё, а делать или не далеть решать только тебе. Язык не запрещает, не сковывает руки, а наоборот помогает делать что угодно. И из за этого он прозрачен, что ты пишешь, то и получаешь. Ты видишь что ты пишешь, в отличие от других параш, где язык является черным ящиком, хуй знает что там под капотом реально происходит.
Да, забыл добавить: Продолжаю искать: DO-178C.PDF (A и В тоже подойдут), DO-254.PDF, DO-385.PDF (всё ещё некритично), ARINC-653.PDF. Без смс и регистрации!
>>1892347 > Ситуации при которых возникает UB описаны именно в стандарте. Ты даун? Ты хоть раз читал стандарт? Тебе пояснили, что ситуации при которых UB происходит наоборот в стандарте не описаны.
>>1892308 И что? Следуя твоим дебильным мемасам, свобода это и есть UB. Когда можно делать всё, значит предскащзать действия невозможно. И тут нет проблемы. Поедсказать невозможно только со стороны, например дебил как ты или компилятор, который вообще машина, не сможет предсказать, но это и не нужно. Главное, что умный человек, либо не будет так делать, либо будет когда ему это нужно. Главное есть возможность, это всегда плюс. Важно что язык предсказуем, ты пишешь код заранее зная что он делает, буквально.
А вот всякая пидарасня из других говноязыков программирует наоборот. Сначала "предполагает" от балды, что "наверное" код будет делать надо, но не факт, ибо неизвестно. Так что сначала надо запустить и посмотреть что выйдет. Посмотрел, если "сработало", ну окей, если "не сработало", продолжает гадать на кофейной гуще пока наконец не "сработает".
Программирование на си это техника - выдача устройству четких команд на исполнение. Ты сначала должен знать работу устройства и поддерживаемые команда, а потом просто перечисляешь что делать и всё четко исполняется.
"Программирование" же на другом говне - как бюрокрания: "Господин язык, мне тут надо сделать это, я вроде составил прошение по форме (но неуверен), пожалуйста рассмотрите, если у вас будет время и желание, а я холоп, человек маленький, дальше не моего ума дело, подожду решения господина, если что не так, перепишу и подам прошение снова и снова, пока вас не устроит. С низким поклоном, макака Чухан Объебосов".
И вот таких чуханов объебосов, из говна залетевших в си-тред видно сразу. Си - четкий язык, поэтому программист на си всегда знает что делает, ведь есть доки. А залетные чуханы делают наоборот, пишут на авось от балды примерно так: >char a[NN], b[NN] >"введите 1 строку:", a >"введите 2 строку:", b >if (a == b) "строки одинаковые" Потом запускают, не понимают результата, и бегут в тред с вопросами "а пачиму ниработаит?". Потому что привыкли писать хуету, сами не зная какую, чисто интуитивно, на авось "может прокатит". И вот этот вот пиздец эти ебланы считают протраммированием. В си-то всё четко, прежде чем писать, читаешь доку, и заранее знаешь что получишь. Вообще не вопрос, проблемы не существует. А у хуесосов, в говне вместо языков, никакой ясности нет, язык - черный ящик, делает хуй знает что, вот и "программисты" тоже пишут хуй знает что, на удачу.
>>1892508 >пук Дальше не читал. Ты не достоит программировать на Си. Все изящество программиста на Си в том, чтобы читать раздел J2 в стандарте языка, и избегать всяческого UB по коду. Ты не имеешь права с такими мыслями писать код на Си. Ты меня слышишь? Не имеешь права!!
>>1892518 >Дальше не читал. Я и говорю. Быдло макаки залетевшие из своей параши в си - читать не приучены, не читают они, а значит не знают что пишут, тогда как программист на си - наоборот, сначала читает и уже знает, а только потом пишет. Или, еще яснее: если не знает, не пишет ничего, пока не разберется в том, что собственно собирвается напечатать в редактор кода. В си нельзя ебашить непонятный код, в надежде на авось или на "потом докрутить по результату". Это и есть тот самый, настоящий UB, UB головного мозга дебиломакаки, которой в си делать нечего.
>>1892508 Пчел, решил дать шанс твоему шизовысеру. Так вот, язык Си не имеет никакого отношения ни к устройству, ни к его командам. Язык - это лингвистический конструкт. В языке Си нет никаких .bss секций, page faults и прочего. Зато в языке четко сказано что запись за пределами массива - UB, то есть лажа.
>>1892613 >Си не имеет никакого отношения ни к устройству, ни к его командам. Язык - это лингвистический конструкт Как в воду глядел. Как раз об этом размышлял, но писать было лень, а тут ты такой. Поражаюсь себе. То ли я такой умный, то ли глупцы такие предсказуемые. Хоть и отрицаешь голословно, но, по крайней мере, это говорит, что более-менее понял написанное. Уже хорошо. А то я уже привык к ответам уровня пеньков.
Для ясности, начну с терминологии. Будет так: си – «язык (программирования)», соответственно: «программирование», «программисты». Другие языки – «говно», соответственно: «говношлепство», «говношлепы / макаки».
Итак, рассмотрим следующий код: int a=1; Говношлепов учат так: «переменная – это ячейка памяти, в которой хранится значение». Определение – гуманитарное, в соответствии с обычным житейским здравым смыслом – философия. Ячейка является сущностью, объектом. Ничего учить не надо, любой человек по дефолту – понимает простую философию на интуитивном уровне. И хорошо, правильно учат, оно так и работает, но только в говне.
А вот в си это не работает, от слова совсем, потому что си – это программирование машины, техника, а вовсе не пиздоблядская гуманитарная философия. Начнем с того, что переменная в си это не объект, а значит никакая не ячейка. Ячейка имеет защиту, она изолирована стенками. Нельзя из одной ячейки попасть в другую. Если попытаться засунуть в ячейку слишком много, ничего страшного не произойдет, просто часть не влезет и всё. Именно так работает говно, но не си. Си это машинный интерфейс. Прежде чем написать эту простейшую строчку кода, ты должен понимать как работает железо (процессор+память) и выучить, что переменная это просто место в памяти, никакими «стенками» не защищенное и не ограниченное. Это технические спецификации машины и языка си как её интерфейса. Этому нельзя догадаться философской интуицией – только выучить, заранее читая документацию. Иначе, без этих технических знаний, ты уже крупно обосрался одной этой строчкой.
Ты полном дерьме, по уши, по одной простой причине – гуманитарное говноблядство безопасно. Ты можешь на дваче пиздеть любую хуйню, не зная, заливать в уши лапшу, и максимум тебя просто пошлют и всё. Именно так происходит в говне, Тебе просто либо выдается ошибка, либо получаешь не тот результат. Ничего страшного, просто крутишься как уж на сковородке пока не получишь желаемое. Обычная повседневная жизнь любого быдлана, бытовая философия – суть говношлепства. А техника, машина – наоборот, очень уязвима. Машина – не автомобиль для быдла, а большой сложный механизм на заводе (компьютер) и пульт управления на всю стену с кучей лампочек, кнопок и рычажков, её интерфейс (язык си). Ты не можешь просто подойти, не изучив, что это за машина, как устроена и работает, как на неё воздействует каждая кнопка, и просто наугад тыкать гуманитарнным способом: «та кнопочка зелененькая, значит можно жать, будет только лучше, а вот та красная, значит лучше не трогать» и так далее. С машиной, любое неверное движение и она просто ломается нахуй. Поэтому говношлепов к машинам не подпускают, сначала требуют выучить всё и сдать экзамен. Иначе еблан первым же действием всё ломает нахуй. Тут не прокатит метод научного тыка как у говношлепов гуманитарных, вторых шансов нет, машина слишком сложная. Даже повторяя косяки, ты ничему не научишься. Только читать документацию заранее, до полного понимания куда ты лезешь.
Что мне сделать чтобы вкатиться в эмбед по Си без образования? Хочу пойти получить, а вдруг прокатит и без него? Сам язык то знаю, пишу всякие приложухи. Говорят могут даже не знающего дауна на завод взять у которого есть вышка и за неделю научат.
>>1892982 Потому что поняли что писать сложную логику, в которой друг с другом взаимодействуют десятки пользовательских сущностей, на процедуропараше — пустая трата времени.
>>1893036 Школьнексон, плиз. ООП — это не о языке. Это концепция. И эта концепция старше чем езык погромирования це. Ты можешь на каком угодно языке писать в ООП стиле. И ты скорее всего и пишешь, просто не знаешь об этом.
Аноны, программирую уже давольно давно на python, недавно появилось желание вкатиться в какой-нибудь по настоящему фундаментальный язык, выбрал си. Прочел книгу Ритчи уже на две трети, попрактиковался на прогах аля "хело ворлд" и тд. Хотелось бы узнать, а что вообще интересного пишут на си? да да, в гугле не забанили, в интернетах встречается много противоречивой, глупой, очень поверхностной информации по этому вопросу. И второй вопрос: на чем бы вы порекомендовали попрактиковаться начинающиму?
>>1896521 Например? Я в этом вашем "системном" не шарю от слова совсем. На пайтоне я пишу боты, парсеры, и веб на джанго/фласке. Приведи примеы, пожалуйста
>>1892014 Спасибо. А вот ещё назрел вопрос: что тогда делает sys_brk(addr)? В гуглах несколько противоречивая информация, в мануале же написано, что по успешному выполнению конец ДС становится равным addr, т.е. простая аллокация/деаллокация для сегмента. Типа еще линкер рожает символ _end, указывающий на конец сегмента; он виден в отладчике, но в рантайме простой программы _end всегда равен 0x00. Одним словом, что определяет начало и размер сегмента? Вообще я так понял, что brk() просто проверяет лежит ли addr в пределах сегмента данных, если - нет, то ENOMEM
допустим я знаю адрес первого байта флота, и знаю что флот 32 битный. Как мне собрать флот? У меня получаются огромные инты и коневертация пораждает соотв. огромный флот, хотя там лежит 0.556
>>1897672 По указателю лежат только байты. "Какие там данные" это абстракции у тебя в воображении. Язык лишь имеет сахарок прочитать столько байт, сколько ты укажешь (типом), так что сам должен знать сколько тебе надо.
>>1897720 Смотрят кто и куда обращается и на основании своего опыта подобных явлений делают предположения, которые потом проверяют. Так же смотрят на сами данные. Опытные кулхацкеры просто глядя на хекс-дамп могут сказать что это такое, лишь по внешнему виду чисел. Изучаешь все аспекты программ и с обытом набиваешь глаз.
Тестирую, что быстрее, копировать сначала по первому адресу двумерного массива, или по второму? copyij будет копировать аргументы или передовать память из рук в руки? Сколь большой массив можно объявить?
>>1899947 Ты копируешь аргументы через stack, два массива по 2048 * 2048 байт(~8 миллионов байт), вполне вероятно ты вываливаешься из-за этого в SIGSEGV. А вот если бы ты имел операционную систему с дефрагментацией стэка, то думаю бы с бы такой бы проблемой бы ты бы не бы столкнулся бы. >>1899976 Яхуйзнает, может так: >int8_t ××array = (int8_t ××)malloc(sizeof(int8_t ×) × LEN); >for (size_t i = 0; i < LEN; ++i) { > array = (int8_t ×)malloc(sizeof(int8_t) × LEN); >} Хотя я не уверен до самого конечного конца...
Может кто подсказать, как сделать префиксный калькулятор со стеком, но оператор пользователь вводит словами. Тип + add, - sub, ^ pow и тд. Алгорит действий вроде понимаю, но понять не могу, какие функции использовать, чтоб разделить слова и цифры на входе
>>1904081 а зачем мне заглавная? Мне надо, чтоб оно считывало к примеру так: 1 2 add = или так 7 0.5 add 2.2 0.2 sub mul Да и не особо понимаю, как я потом числа анси, могу использовать в расчетах.
>>1904225 Ты говоришь о распознавании текстового синтаксиса. Либо пишешь парсер сам, либо используй готовые интерпретаторы скриптов. К языку программирования это не относится и быть в нём не может. Это относится к написанию компилятора/интерпретатора языка.