Тред, посвященный прародителю всех С-подобных языков и по совместительству единственному идеальному и всесторонне годному средству программирования как на системном, так и на прикладном уровне.
- Очевидный GCC. - clang: оче годно, батя рекомендует. - Intel C++ Compiler: оптимизации, тысячи их. - Visual Studio 2017 Community Edition: внезапно этим стало можно пользоваться, особенно с тулсетом clang/C2. Поддержка C11 на уровне "есть все, что тебе понадобится в реальном проекте плюс кривая библиотека". Анализатор кода в комплекте. - Pelles C (шиндоуз онли): поучиться, вкатиться в C11 (стандарт полностью реализован, имеются в том числе threads.h и прочие stdatomic.h), но количество багов в оптимизаторе и редкие апдейты напрочь отбивают желание собирать этим что-то сколько-нибудь серьезное. - TCC: очень маленький компилятор с багами и неполной поддержкой C99. С ключом -run умеет компилировать код в память и запускать его, что позволяет писать скрипты прямо на сишечке.
Что еще почитать:
Stephen Prata "C Primer Plus, 6th Edition" (2014) Свежая знает про C89, C99, C11, описывает различия, объемная около тысячи страниц, годная хотя есть некоторые шероховатости, с вопросами, упражнениями и ответами. Читать после K&R или до.
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 помогает читать сложные сишные декларации.
>>1055783 А если я поучу по книге 80х годов (там классно написано) - смогу откомпилить? Или современные компиляторы несовместимы со старыми версиями C?
>>1055788 Там рассматривается си в стандарте 89 года надо читать второе издание, в первом рассматривается старый си. С89. С тех пор вышло только 2 стандарта - С99 и С11. В принципе любой компилятор будет поддерживать С89, так что проблем не возникнет.
>>1055796 >С.Прата Есть шестое издание, там уже рассматривается самый свежий стандарт С11, на торрентах есть. Называется Язык программирования Си Лекции и упражнения
>>1055796 У тебя могут возникнуть некоторые проблемы. Старый синтаксис поддерживается, но категорически не рекомендуется. Почему именно эта книга? Почему нельзя взять прату или к&р из шапки? Ты любишь сложности?
>>1055803 >Старый синтаксис поддерживается, но категорически не рекомендуется Можно пример старого синтаксиса, который категорически не рекомендуется? Строки?
>>1055865 Неявный инт? Не думаю, что это такая уж огромная неприятность. > return 12345 А так никто со времен Кернигана и Ритчи не делает. Корректно завершившаяся программа должна вернуть ноль.
Сап, есть один тип sigset_t, в котором каждому биту соответствует включенный или отключенный сигнал с номером signo. На пикрил функции для основными действиями с этим типом: sigaddset - добавить сигнал в набор, sigdelset, sigismember - проверить, является ли сигнал членом сета. Функция sigdelset непонятна. Почему в add нет лишних скобок в правой части, которые есть в del? Алсо, почему в sigdelset вообще происходит выключение нужного бита, ведь там побитовое И? И эти операции не должны затронуть остальные биты, а sigdelset занулит же там всё, не?
>>1056020 >Функция sigdelset непонятна. Почему в add нет лишних скобок в правой части, которые есть в del? Имхо, вкусовщина - просто выделили выражение мкобками, хотя я не эксперт в Си
Чёт опять делать нехуй. Написал алгоритм проверки номеров кредиток и заодно самотест к нему (первые 4 и последние 4 цифры взял от реальной карты). Сам не погромист ни разу.
Зачем вам Си? Лабы в универе писать? Устроиться червем-байтоебом и получать всю жизнь столько, сколько получает жуниор-пхпшник? Дрочить на линупш и писать опен соурсе? Или есть какие-то годные варианты, которых я не знаю? Не ради траллинга спрашиваю. Чем занимаются си-пограммисты?
>>1056476 Даже C++ не расширенная версия Си. Они эволюционировали по своему и у них свои стандарты. Есть такие вещи которые не существуют в C++, например как массив переменной длины, а так же сложные числа. Но обратно же, такие вещи как объекты, шаблоны, стандартные библиотеки не поддерживаются Си. Можешь почитать об этом на досуге. Во встроенных системах и системном программировании, Си все еще главный доминирующий язык, потому что ты, обычно не нуждаешься в объектах нежели в обращений к низкоуровневым вещам типа прямого интерфейса оборудования. Более того, у тебя более точные требования по времени и вместительности доступной памяти. Представь как бы ты вместил кучу информации с высокой подачей с помощью объектов С++ в пяти сот байтов микро-контроллера оперативки? Линуксы написаны на C. Другие же языки, даже включая C++, предназначены для других нужд, и в глаза Линукса он - Ужасен. Большинство людей кстати после выхода Си остались на Ассемблере, боялись уходить от традиций. Несмотря на то, что у Си был намного лучше код. С++ стал другим языком для других нужд, пусть даже и похожим на Си, но он потерял низкоуровневые способности, типа доступа к процессорному влиянию. Т.е такие языки как Си или Фортран это системные языки. Да, есть годные варианты, о которых ты не знаешь. Но я намекну, почему он все еще популярен в наше время: Операционные системы, Языковые компиляторы, Ассемблеры, Интерпретаторы, Дата-Базы, Драйвера, Утилиты, Движки игр и списочек продолжается.
>>1056476 Я взялся за него, потому что Страуструп сказал в своей книжке, мол, что я обязан знать Си, чтобы изучить C++ и использовать его полную силу. Да конечно не обязательно знать Си, чтобы пользоваться С++, но я подумал, знание еще одного языка это не помеха, а лишь еще одно преуспевание.
Анончики помогите дауну. Задача: при вводе a,b,c выводить "Right", при вводе q завершать программу, при вводе остальных знаков писать "Wrong". Вот мой код:
#include <stdio.h>
int main (void){ char c; while (scanf ("%c",&c), c != 'q') { if (c >= 'a' && c <= 'c') printf ("Right \n"); else printf ("Wrong \n"); } return 0; }
Ввожу a получаю : Right Wring
Ввожу e получаю : Wrong Wring Где ошибка? Заранее благодарю.
>>1056528 Ему нужно чтобы при каждом неправильно набранном значений об этом намекалось. Т.е введет adc Должно выводиться - right wrong right Если abc - Right Right Right Если ggg - Wrong wrong wrong У тебя условие истинно в любом случае, алсо wrong тоже выведется, потому что значение истинно.
>>1056561 Если ввести bac cab bca cba и т.д выводится right Если ввести abcabc выводятся лишние значения Если ввести bbb или aaa или ccc выводится - Right Будут годные советы? Кто нибудь?
хотя если бы и запускался, система же сама определяет типы. хотя я не очень понял как это, есть типа какая-то специальная бумажка, которая советует компиляторам делать так, как там написано?
достаточно вспомнить разность int,long на винде64 и лине64.
>>1056476 Сравнивать программирование с написанием веб-говна на PHP нельзя. Ты бы еще PHP в математикой сравнил. Это разные вещи.
Вчера вот заглядывал в сырцы Python - так там куча .c и .h файлов. Уверен, что и много другого интересного софта написано на C. А чтобы его например пропатчить, нужно C знать. Да и вообще это другое программирование, нежели на скриптоязыках. Ты программированием ради денег занялся или тебе что-то в нём понравилось?
>>1056853 Потому что программист должен знать английский, тем более, если он не на сишечке пишет, а не на каком-нибудь jQuery. А что касается третьего издания, то изданий два, а русское "третье" - багфикс для русского перевода второго.
>>1056860 Какие комплексы? Большинства годных статей на русском нет. Либо ты макака, потому что тебе негде учиться, либо ты осознаешь ситуацию и учишь язык. Это не говоря уже об общении с другими программистами и комментариях в коде.
>>1056888 у тебя какая-то каша в голове. с чего ты решил, что всем нужно читать годные, что есть только на английском, твоему мнению, статьи, и читать исходники на английском?
какой-то максимализм выпирает. как кто хочет, так пусть и учится. ты лучше свои навыки реализовывай и не выёбуйся.
>>1056742 >Counter Я тоже об этом подумал, но ты тут очень много кода впихнул. Можно создать набор символов - образцов и потом программа по ним делает сравнение, но и у тебя неплохая идея со счетчиком. Т.е псевдокод - Принять значение Сравнить с [Переменная] Все совпадения Right Вывести Несовпадения Wrong Вывести
>>1056891 Он прав вообщет. Я специально занялся английским, потому что русский контент сосет жепу, редко найдешь учебное пособие которое переведено как следует. Везде провалы. Да и ресурсы в основном где пишутся полезные статьи, фичи, алсо конференций, В россии кто нибудь C конференций устраивает? Интервью с Брайаном Керниганом, расширенный набор книг по программированию от разных авторов, спецификации вместе с драфтами, да куча всего на английском. И поэтому нужно обязательно знать английский, особенно если ты хочешь чего то добиться. А так если ты программингом занялся ради смехуечков и пиздхаханек то для этого подойдет какой нибудь, ну... Язык для создания приложений для телефончиков?
>>1056853 Там перевод пиздец какой корявый. Например: >Напишите программу, копирующую символы ввода в выходной поток и заменяющую стоящие подряд пробелы на один пробел. Т.е спрашивается, какой нахуй выводящий поток? Напиши как в книжке - Напишите программу копирующая ввод в вывод, заменяя каждую последовательность нескольких пробелов одним. Все. Сложно? И так вся книга.
>>1056888 > Большинства годных статей на русском нет Знать английский и читать технические (научные) статейки не одно и то же. В студенчестве я регулярно делал доклады по алгебре с англицких книжек. Однако не мог без субтитров смотреть даже мультики для детей-аутистов, а любая неадаптированная книга уже на первой странице содержала сотню незнакомых мне слов. Для вопросов на стековерфлоу хватает английского уровня гуглопереводчика.
>>1056928 Собственно, в этом и смысл. Человека >>1056888 спросили, почему нет русского перевода в шапке? Самый первый пришедший в голову ответ был не "потому что перевод плохой" могу сказать, что он не плохой, а потому что ТЫ ОБЯЗАН ЗНАТЬ АНГЛИЙСКИЙ, ЕСЛИ ТЫ НЕ МАКАКА. Логика прослеживается, конечно, но связь между вопросом и ответом ОЧЕНЬ опосредованная и явно прошла через цепочку когнитивных искажений. Я, если что, хорошо знаю английский, просто мне бомбит с тех, кто делает из него священную корову по поводу и без.
Я уже молчу про то, что, действительно, давайте будем честными: нихуя не надо знать английский для программирования. Если вы называете уровень чтения литературы по программированию (обычно сухой и бедной на сложную лексику или, тем более, грамматику, дабы читатель сосредоточился на предмете) или прослушивания лекций ЗНАНИЕМ АНГЛИЙСКОГО, то у меня для вас плохие новости -- это уровень седьмого-девятого класса. А то слюней напускали, ояебу просто.
>>1056952 >нихуя не надо знать английский для программирования Мы приняли твое мнение во внимание На самом деле нет. >то у меня для вас плохие новости Всем похуй на твои новости. >это уровень седьмого-девятого класса. Так хули ты не выучил то?
Помогите с организацией хедеров. Дело такое. Скажем есть хедер файл, в нем есть прототипы функций, одна функция возвращает uint8_t, значит, нам надо stdint. Где логично будет подключать stdint ? Если тянуть его до хедера в файле .с то все нормально. Не будет ли тупо, если я засуну его прямо в хеадер ? Или так и надо ? Спасибо.
>>1057060 Основное правило такое: хедер должен включать свои зависимости. Если в хедере используется uit8_t - подключаешь stdint в хедере. Ну и очевидно, что в парном .c подключать stdint не нужно.
>>1057264 Если что, вся эта простыня говнокода аллокейтит новый argv через анусай, после чего запихивает туда имя обрабатываемой вебсервером в данный момент страницы. Частично портабельно (на соплярис). А вот во фряхе вместо всего этого ебалова есть setproctitle()
Можно как-то передать структуру в функцию, без объявления? Типа: func(arg, {1,2,3,4}); Ну или хотя бы объявить сразу здесь же? А то чот очень душно как-то получается. Извиняюсь, если проморгал этот момент.
Какой-то более-менее общепринятый компиляторо/платформо независимый, пусть и не самый быстрый метод для арифметических операций с целыми, как знаковыми, так и беззнаковыми, стандартных 8, 16, 32, 64 разрядностей, позволяющий избежать переполнения вообще существует? Всё что удалось нагуглить - какие-то хаки и костыли , но я не самый способный. Не очень хочется выдрачивать велосипеды. Подскажите, если кто знает, пожалуйста.
На околокачественный код потянуло. Как лучше назвать структуру окна (того, что в ОС), сам тип окна в ней и высоту с шириной? Стремлюсь к кратким наименованиям, полные порой выглядят жутко.
>>1057921 Да ты охуел! Не согласен с книжкой. Гораздо проще один раз посмотреть на структуры и комментарии к ним, а потом беззатруднительно читать весь остальной, компактный код. Конечно, есть место длинным наименованиям, но это нужно далеко не везде, я думаю. Потому скажи мне как назвать структурку и её элементы.
>>1058053 Ну у компилятора-то возможностей куда больше, он может вставить что-то типа jnc, jc, jo, jno - однобайтовая инструкция, выполняется один такт. Жалко только, что стандарт предпочитает неопределённое поведение, видать на ПДП подобной хуйни не было. >есть же специальные инструменты. Ты про какие? Те которые проверяют исходный код или которые позволяют работать динамически? Если про последние, то линкани, пожалуйста. Собственно мне нужна функция навроде __builtin_add_overflow из GCC, только что бы по-переносимей.
но вообще слабо верится в быструю проверку компилятором. ведь есть же всевозможные правила конвертации типов, неявный инт. даже если представить это без оптимизации вообще.
>>1055733 (OP) Ананасы, как вы, погромируя всякие железки, определяете оптимальный размер стека? Я вот пишу хуйню на броадкомовском говно-сдк, в котором обычному printf в uart с какого-то хуя нужно 4096 байт стека, постоянно ловлю всё новые и новые stack overflow. Размеры рассчитываю на глаз и включаю заодно runtime-проверки операционки, конечно и заебался уже так делать.
например что-то типа add eax ebx mov ax (или как там) %куда-то там
и типа это конвертация из инта в чар, по беззнаковому это стандартно, знаковому - нет. как это, например проверять, знаковый вариант? (char)((int)a + (int)b);
по идее же надо будет проверять диапазоны обоих, а потом и результат?
а например такой контекст = (int)a + (uint)b
будим считать за переполнение, когда a < 0 и скастуется к uint ?
тогда нужно проверить a на 0 =< a <= INT_MAX . хотя это вроде стандартное поведение.
просто размышляю. наверно реально, если компилируется без оптимизаций. может флаги есть в гцц?
>>1057929 > Потому скажи мне как назвать структурку и её элементы. typedef struct { GLFWWindow *physicalWindow; unsigned int width, height; } Window; Если не нравится - иди решай свои проблемы - научись печатать более чем одним пальцем, купи себе монитор с разрешением выше 640x480, найди IDE с автодополнением, если ленивый. А в комментариях пиши не расшифровку своей тарабарщины, а полезные вещи.
>>1058305 > купи себе монитор с разрешением выше 640x480 У меня 1024x768! А иды не нужны, ровно как и твойУёбищноеНазваниеПеременныхБлядь. Мне гораздо приятнее читать код состоящий из кратких переменных. Достаточно понимать принцип выбора названий и область под которую погроммист пограммит.
>>1058322 > Мне гораздо приятнее читать Если проект - твой собственный, и кроме тебя его читать никто не будет - пиши, как тебе нравится. Хоть весь юникод на однобуквенные переменные заюзай. Но помни, что если кому-то вдруг придется это читать, он будет крыть тебя матом каждую ебаную секунду.
>>1058340 > нельзя же. В C99 запилили extended identifiers. Весь юникод, конечно, нельзя, но символов, которые разрешено использовать в идентификаторах - овердохуя.
Помогите удостовериться. Массиву character[TNOCHAR] присваивается 128 имен Им присваивается каждому 0 Далее идет пересчет каждого введенного совпавшего символа ++character[c];
Запускается цикл который выводит 128 символов Тут самое важное Запускается еще один цикл который сравнивает значение j со значением Попавшихся совпадений character[Любое совпадение в character[c]] и инкрементируется значение j до кол-ва попавшихся character[c] и выводится кол-во символов '*' и символ новой строки после того как совпадения закончатся. Все верно?
>>1058426 У тебя там в ideone чуть ниже есть standard input. Введи туда свои символы и посмотри, что получится. Но хуй знает, описал ты это, конечно, коряво. 128 имен каких-то, совпадения какие-то. Гистограмму оно строит. Все блять.
>>1058206 Ну конвертация-то в более узкий тип - совсем простая операция, только границы проверяй. Тот же х86, вроде бы, имеет одтельную инструкцию проверки диапазона.
Кстати же, придётся проверять ещё и деление для случая SIGNED_MIN / (-1), ну а SIGNED_MIN % (-1) по идее аппаратно вылететь должен.
Для типов меньше 64х бит можно привести данные к более широкому, проверить и отсечь если попадают в диапазон. Вот тут https://blog.regehr.org/archives/1139 мужик пишет, что относительно шутсрый метод. Для максимальных же, один пёс придётся выполнять проверки, а для знакового ещё и пилить умножение руками. Ещё можно учесть, что некоторые компиляторы-таки поддерживают безопасные операции, в ряде случаев можно наассемблерить необходимые проверки, и по итогу получить кромешный пиздец из ифдефов. Какая же ебаная хуита, простите.
Аноны, нужно распарсить .pcap файл размером в 10 мб, на питоне это занимает около 9 секунд(!!!). Решил реализовать эту часть алгоритма на Си, а конкретней: 1. парсинг pcap файла 2. запись данных в БД постгрес Если со вторым пунктом ясно всё и нагулится, то насчёт первого не уверен. Какие будут советы/варианты вообще и по первому пункту в частности? p.s. думаю моих знаний в Си хватит для этого, более чем.
>>1058725 Это есть в стандарте. Когда ты инициализируешь один из элементов, остальные заполняются нулями. В данном случае инициализируется первый, и слегка непортабл это только когда нулевые указатели хранятся не в виде последовательности нулевых битов. Но я таких ебнутых машин не знаю.
>>1058740 В мире фей, где нет старых компиляторов может означать. Но там это может что угодно означать, что пыльца в соцветиях ноздрей хоботов голубых слонов созрела, например. Мир фей же
>>1058725 Ну не тяжело, но должно быть понимание базовое, хотя бы почему и когда это делать. Пока как говориться, велосипед поизучаю, а там уже и буду экспериментировать.
>>1058742 В моем мире поддержка хотя бы C89 есть под каждую необходимую мне железку. Если мне вдруг встретится что-то, не поддерживающее C89, я не стану называть это компилятором Си. Это будет компилятор кастомного языка с C-like синтаксисом.
>>1058748 Да, это есть в C89. А я, в свою очередь, прошу прощения за разговоры о непортабельность инициализации указателей - все там нормально инициализируется, вне зависимости от представления в памяти, а описанные выше проблемы возникают при попытке делать обнулять через memset(..., 0, ...).
>>1058426 Про массив сказал, ещё кое-что: 1) Отделяй операторы пробелами от операндов, а ещё ставь пробел справа от знаков типа , или ; -- когда будешь писать вещи хотя бы немного сложнее читаемые, чем двойной счётчик, отсутствие пробелов глаза ибат жоски будет. 2)Маловажная ремарка: каноничноъ в for-цикле пользоваться пост-инкрементом/декрементом, а не пре-. С массивами (т.к. индексация с нуля) удобнее задавать счётчик как for (i = 0; i < zalypa; i++), но во всех остальных случаях читабельность повысится при отсчёте с единицы: for (i = 1; i <= zalypa; i++). Я так-то тоже вкатывальщик, просто немного подальше закатился, оэлдэфаги, можете обоссать
Котаны, можно ли как-нибудь отличать память на стеке и память в куче? Например, у меня есть структура, несколько полей которой принимают ссылку на область памяти double(звездочка). Есть функция delete_struct, которая проходится по этим полям free(). Можно сделать так, чтобы программа не ломалась из-за попытки очистить память в куче?
>>1058874 > каноничноъ Труъ эстеты пишут с преинкрементом, потому что у него нет специального поведения в отличие от постинкремента.
>>1058876 Нет, нельзя. К тому же, есть еще вариант статически выделенных данных. Ты, конечно, можешь нагородить платформенно-зависимый костыль (ну там, регион стека детектить, с секцией данных сверяться), но сделай лучше флажок в структуре, не выебывайся.
Господа, нужна помощь. Сразу прошу, анон, не пинай нуба, мне всего ровно 18, и я пытаюсь постичь С/Спп. В общем, не понимаю я логики работы с включениями исходников - все эти заголовочные файлы и прочее. В книжках нашел только общие положения, на всяких хабрах - то же, либо какие-то рецепты для конкретных случаев. Нипанятна. А теперь суть проблемы. Допустим, есть у меня некий файл first.h. В нем мы определяем константу coeff типа int:
#ifndef FIRST_H_INCLUDED #define FIRST_H_INCLUDED
const int coeff = 5;
#endif // FIRST_H_INCLUDED
Далее создаем заголовочный файл second.h. В него пихаем определения функции:
Функцию определяем в файле second.cpp. В нем "инклудим" second.h и используем константу coeff (наверное и так понятно как должно выглядеть). В мэйне подцепляем second.h и вызываем функцию func. Типа по моим понятиям должно работать. Однако оно выдает ошибку multiple definition of coeff. Как правильно надо включать файлы, чтобы я мог и константой воспользоваться, и чтоб компилилось?
>>1058888 Не делай константы через const. Это плохо работает, не всегда нормально оптимизируется и все такое. Делай через #define как люди. Если все же хочешь, чтобы работал твой вариант, у тебя два выхода: сказать, что константа statiс или писать в хедере, что она extern, а реальное определение пихать в один из .c файлов.
>>1058890 на самом деле в реальной программе там строка const char*, мой пример искусственный и чисто модельный. А строку можно дефайном вставлять? Хм. Щас попробовал перенести строчку #include "first.h" из файла "second.h" в файл "second.cpp" и все заработало. Странно это...
>>1058891 Ну а отвечал я про примитивные типы вроде double или int. Со строками все зависит от того, зачем тебе строка (дубликаты строк не все компиляторы схлапывают). В общем и целом, лучше делать extern в .h, строку в .c.
>>1058888 const int coeff = 5; это глобальная переменная ты инклудишь в second.cpp и там это переменная, и в main.cpp и там тоже эта переменная. ты перенес инклуд, и в main.cpp больше нет объявления этой переменной
>>1058897 static ограничивает видимость модулем (объектным файлом, единицей компиляции). Если extern - это определение (definition), то его видно извне, а если это объявление (declaration), то объявление для него может быть в другом модуле.
>>1058900 >extern - это определение (definition), то его видно извне extern значит, что переменная определена в каком-то другом cpp-файле или подключаемой библиотеке. тогда во время линковки заместо этой переменной будет подставлен адрес этой другой определенной где-то переменной с таким названием
Ебашу тут Дейтелов 2009ого года. И чет у меня во второй программе сумма неправильная выходит, подозреваю что-то случилось за 8 лет. объясните что?
#include <stdio.h>
main(void) { int integer1, integer2, sum;
printf("Enter first integer\n"); scanf("%d", &integer1); printf("Enter second integer\n"); scanf("%d", &integer2); sum = integer1 + integer2; printf("Sum is %d\n, sum");
>>1058985 Отключает бугурт компилятора студии по поводу использования "небезопасных" функций. Т.е. большинства, где используются указатели в том или ином виде. Надо понимать, что Visual Studio - это не среда для разработки на Си. Это среда разработки на Managed C++. Да, в плюсах, даже управляемых, есть возможность использования сишного кода, но приходиться попердеть с директивами препроцессора или unmanaged вставками. Ты просто определись: либо ты пишешь на си, либо не на си. Майкрософтоподелия к си имеют весьма посредственное отношение. Назначение Managed C/C++ только в том, чтобы делать врапперы для нэйтивных библиотек в комовскую оболочоку, с последующим вызовом их из управляемого кода, написанного на любом языке .net семейства. Программы на нём пишут только дэбики уникумы.
>>1059004 Проблема в том, что все остальные IDE выглядят как куски говна, поэтому делаю задания из книжки в VS. Вот как-бы и все. А почему так вышло, что они небезопасные?
>>1059013 Давай спустимся с небес идеального кодинга на землю ради ответа на простой вопрос, который мучает меня: почему некоторые люди не ставят пробелы?
>>1059014 >А почему так вышло, что они небезопасные? Потому что Стив Балмер так решил. А вообще тебе нужно почитать про дотнетовский CLR, управляемый/неуправляемый код, всякую хуиту про ООП и отличия указателя от ссылки. Здесь всё же Си обсуждают.
>что все остальные IDE Может быть местные гуру меня поправят, но Си - это не "эй поцоны, я ДЭВЭЛОПЮ код на макбуке в няшной ИДЭ с дарк интефейсом". Си - это системное программирование, линукс кернел и ымбыдед. Поэтому либо пользуешься специализированными IDE вроде Keil4 или VisualDSP++, которые облегчают процесс разработки говнокода под конкретные платформы. Либо превозмогаешь себя и пишешь код в блокнотике, параллельно постигая make и gcc. В качестве блокнотика могу посоветовать VS Code, если уж так любишь майкрософтоподелия
>>1059004 >Visual Studio - это не среда для разработки на Си. Это среда разработки на Managed C++ Чо? Можно же писать на unmanaged C++, и на С89С95/АМD1 офк. А если прикрутить clang/c2, то еще и С11 будет
https://pastebin.com/FgXY3SUy Строчка 34: объясните подробно, пожалуйста, почему так передавать второй аргумент в функцию нельзя? И правильно ли я использую двумерный массив в таком случае вообще? Это задачка на моделирование "черепашьей графики".
Анончик, можеш подсказать плз написать круговой динамический массив в Си? Я знаю что простой круговой массив пишется через index % size. Но как мне его сделать динамическим?
>>1059014 > А почему так вышло, что они небезопасные? Такими сделали. Когда дизайнилась стандартная библиотека, об уязвимостях еще не думали. И "небезопасность" таких функций не в использовании указателей, как говорят ньюфаги выше, а в отсутствии контроля границ или недостаточной сигнализации о том, что данные в буфер не влезли: например, печально известная gets() пишет данные в буфер, но не позволяет ни указать его максимальную длину, ни сигнализировать о том, что буфер переполнился. А, например, какая-нибудь snprintf, сделанная позже, и, вроде бы, правильно, позволяющая указать максимальный размер буфера, возвращает не количество записанных в буфер символов, а нахуй не нужное количество символов, которое могло бы быть записано в буфер бесконечного размера. При этом, чтобы узнать, что буфера не хватило, тебе нужна явная проверка, а если ты поленишься (очень многие ленятся), то в твоей программе появляются truncation-уязвимости (приходит тебе такой аттачмент в письме foo(многобуков).exe.jpg, пишет такая программа его на диск, делает snprintf(filename, MAX_PATH, "%s/%s", temp_folder, attachment_name), а оно не влезает, обрезается, и на диск летит уже foo(многобуков).exe). И вот Microsoft для решения этой проблемы придумала подмножество _s (safer) функций, которые фэйлятся, если что-то не влезло, и даже пропихнула их в стандарт (Annex K), но оно никем, кроме Microsoft не поддерживается, и там есть проблемы с runtime constraint handlers, и, в общем, почти никто ими не пользуется, кроме самой Microsoft. И ты не пользуйся, но о проблемах стандартной либы помни.
>>1059123 commands - одномерный массив, ты не можешь индексировать его дважды. Алсо, несмотря на то, что ты там при инициализации понаставил фигурных скобок, он остался одномерным, и инициализаторы просто записались в него по порядку ([0] = 2, [1] = 5, [2] = 12, [3] = 3...). Сделай либо нормальный двумерный массив commands[COMMANDS][2], либо массив указателей на массивы int, можно с compound literals (С99) примерно так: (int *array[] = { (int[]){ 1 }, (int[]){ 5, 12 }, итд }).
>>1055733 (OP) Почему говорят, что "функция возвращает void", если на самом деле она ничего не возвращает? Как говорить правильно? Что такое на самом деле void? Как он работает?
>>1059207 Формально void это даже тип данных. Если это слово стоит перед функций, то значит функция ничего не возвращает. Т.е так и говорить, "функция ничего не возвращает", или возвращает пустоту
Кто-нибудь подскажет, как по номеру сигнала получить имя? У меня в массивe *sys_siglist[] в строках забиты описания сигналов, даже имя не вычленить. А большая часть функций, которые что-то печатают о сигналах (например, strsignal), обращаются именно к нему. Придётся делать, как в kill сделали (массив структур sys_signame)? https://github.com/karelzak/util-linux/blob/master/misc-utils/kill.c Каждый сигнал с ifdef'ом инициализировать, это же мрак.
Анончики, как грамотно переписать вот этот кусок кода? В книге написано что goto для долбаёбов, а как сделать без него не соображу. Нужно прочитать символ 'a', 'm', 'e', 's' или 'd'. На остальные вывести сообщение об ошибке. Заранее спасибо.
>>1059605 goto не для долбоебов, но и не для этого случая. do { ch = getchar(); } while (ch != EOF && ch != 'a' && ch != 'm' и т. д) if (ch == EOF) { поток ввода кончился } else { нам дали требуемый char }
>>1059692 > int pi В советской россии пи равняется трем, ага.
int - это integer, целое. Не дробь. Дроби хранят в float или double, это типы с плавающей точкой. Можно еще в фикседпоинте, или даже явно в виде числителя/знаменателя, но тебе это пока рано.
Соответственно, double pi (так как десятичная дробь), double circ (так как после умножения дроби на целое ты чаще всего хочешь дробь), и все у тебя будет.
Алсо, лучше сделать pi не переменной, а константой: #ifndef MATH_PI #define MATH_PI 3.14159265358979323846 #endif (или сделать #define _USE_MATH_DEFINES и подключить math.h, оно тебе определит M_PI в числе прочего, но это слегка нестандартная хуйня).
>>1059698 Пасиба, брат. Я когда делал просто вписал Пи ручками и все получилось. А еще такой вопрос, вот такие рисунки можно делать только если в каждый новый принт новую строку рисовать, т.е. рисовать все четыре одновременно или можно сделать по отдельности фигуры и проще?
>>1059707 Можешь создать массив достаточных размеров, а потом распечатать его: #define SCREEN_WIDTH 80 #define SCREEN_HEIGHT 24 char screen[SCREEN_HEIGHT+1][SCREEN_WIDTH+1]; // Очищаеш (плюс сразу переводы строк втыкаешь, чтобы быстрее выводить). for (size_t y = 0; y < SCREEN_HEIGHT; y++) { for (size_t x = 0; x < SCREEN_WIDTH; x++) { screen[y][x] = ' '; } screen[y][SCREEN_WIDTH] = '\n'; } screen[SCREEN_HEIGHT][0] = '\0';
// Рисуеш. screen[10][10] = '*';
// Выводиш. puts(&screen[0][0]);
Но вообще у тебя задание скорее всего предполагает именно одновременную отрисовку в едином цикле (т.е., в зависимости от Y координаты ты рисуешь звездочки и нужное количество пробелов в текущей строке для каждой фигуры, потом перевод строки, потом следующую строку так же и т. д.). Можешь тоже буфер сделать шириной с фигуру, тогда не придется ебаться с пробелами.
Котоны, помогите. Есть код на C, нужно скомпилировать под ARM архитектуру. Как это сделать? Нашел тулчейн arm-linux-gnueabi-gcc, но objdump по объектному файлу выдает архитектуру elf32-little.
>>1060346 Когда я это запускаю на целевой машине, она мне пишет not found. Поэтому я думаю что как-то не так скомпилировал. И ещё бинарник запускается на x64 убунте, это нормально вообще?
>>1055733 (OP) аноны, помогите с кодом, я нихуя не понимаю, как работают глобальные переменные, очень прошу, я заебался, уже всё перепробовал. Я думаю тут мне помогут, не смотря на то, что это кресты всё-таки..
При этом коде я всегда сосу хуи, как не модифицируй, может там какие ссылки-хуилки надо или указатели, которые я тоже пытался вставить безуспешно. А с недавних пор, если создавать пустой проект, вообще пишет unresolved external, ошибку гуглил, всё что советуют делал, безуспешно
Умоляю, анон, помоги, как сделать, чтобы переменную видел весь проект и использовать можно было из любого места, прошу, анон, вот тебе ваванджапан в реверсе и негативе авансом.
>>1060437 спасибо за ответ, анон, но не помогло. теперь другая проблема, ебучий builder c++ ругается на Unresolved external и в основном проекте, раньше только в пустом ругался, в котором я пытался разобраться в этой проблеме. решения нет, хз пока у кого спросить про эту ошибку. всё равно спасибо
>>1060443 Ты про int на отдельной строке? Или про что? Возвращаемый тип на отдельную строку лепят в некоторых проектах, где названия возвращаемых типов длинные, плюс еще атрибуты всякие прописываются типа конвенции вызова. Если писать в одну строку, декларацию все равно придется разбивать.
>>1060344 >Есть код на C, нужно скомпилировать под ARM архитектуру. Подробнее, что за платформа, какая ось. Планшет на андроиде и плата с стм32 - оба подразумевают ARM, но вот компиляция будет разной.
>>1060489 Шо ты несешь. Различия только в выборе архитектуры команд (в STM только thumb) и в доступности всяких флоатов. В остальном, компилятор - он и есть компилятор.
>>1060489 Устройство на базе процессора AT91SAM9260-QU, ось линукс с ядром 2.6.22. Пока пытаюсь просто скомпилировать простейший код, который бы заработал.
>>1060484 на _HUI который и является булевой переменной, я просто так и не понял причину этой ошибки в принципе, почему она возникает ВООБЩЕ интересно, а не только у меня, суть ошибки.
>>1060466 а вот это я не пробовал, как буду дома, сделаю. Удалить exe и obj? или еще какие? сделаю вечером и отправлю сюда скрин
>>1060592 >Пока пытаюсь просто скомпилировать простейший код, который бы заработал. Простейший код - это записать единичку в указатель на регистр, управляющий светодиодом. Скидывай сюда код и вывод компилятора. >>1060511 Устройства под линупсами поддерживают нэйтивную компиляцию. Бэйрметал - кросс онли. >This specifies the name of the target ARM processor. GCC uses this name to determine what kind of instructions it can emit when generating assembly code. Permissible names are: `arm2', `arm250', `arm3', `arm6', `arm60', `arm600', `arm610', `arm620', `arm7', `arm7m', `arm7d', `arm7dm', `arm7di', `arm7dmi', `arm70', `arm700', `arm700i', `arm710', `arm710c', `arm7100', `arm720', `arm7500', `arm7500fe', `arm7tdmi', `arm7tdmi-s', `arm710t', `arm720t', `arm740t', `strongarm', `strongarm110', `strongarm1100', `strongarm1110', `arm8', `arm810', `arm9', `arm9e', `arm920', `arm920t', `arm922t', `arm946e-s', `arm966e-s', `arm968e-s', `arm926ej-s', `arm940t', `arm9tdmi', `arm10tdmi', `arm1020t', `arm1026ej-s', `arm10e', `arm1020e', `arm1022e', `arm1136j-s', `arm1136jf-s', `mpcore', `mpcorenovfp', `arm1156t2-s', `arm1156t2f-s', `arm1176jz-s', `arm1176jzf-s', `cortex-a5', `cortex-a8', `cortex-a9', `cortex-a15', `cortex-r4', `cortex-r4f', `cortex-m4', `cortex-m3', `cortex-m1', `cortex-m0', `xscale', `iwmmxt', `iwmmxt2', `ep9312'. И это только один флажок gcc, для выбора архитектуры ARM. Про всякие хитровыёбанные платы, которые требуют BSP, я уже и не говорю.
>>1060604 Ошибки компилятор выводит в любом случае. Для варнингов есть -Wall -Wextra Кстати -Wall - флажок практически мастхэв в любых случаях >>1060608 Значит кросскомпилятор, да? Где тулчейн качал?
>>1060653 На целевой машине нет утилиты file. Там очень урезанный линукс. >>1060650 Действительно, этой библиотеки нет. Где я ее могу взять и зависит ли она от версии ядра?
>>1060675 Частная разработка завода. Плата модуля ЦП в гибком мультиплексоре. Слушай, file показывает что была использована библиотека ld-linux.so.3, которой на целевой машине нет. Может ее туда подсунуть и тогда все заведется? Только вот суффикс 3 в имени библиотеки что означает? Версию ядра?
Не совсем по теме треда, но: поставил десятку вместо восьмерки, код, который писал ранее на OpenCL, пЕрестал нормально работать. Комп зависает при первом выполнении шейдера, если в дебаге запускать, падает на clFinish. Падает только в том случае, когда в шейдере есть синхронизация с barrier - с любыми аргументами. В чем может быть проблема?
>>1060681 >Может ее туда подсунуть и тогда все заведется? Только вот суффикс 3 в имени библиотеки что означает? Версию ядра? Если ты хочешь взять ld-linux.so.3 со своей виртуалки, и подсунуть под арм платы - мне кажется это не самая разумная идея. Если ты только не найдёшь эту библиотеку собранную под твой арм.
Ты же где-то исходники для ядра линукса брал? Если ты работаешь на этом же заводе - у тебя должны быть сорцы. Ковыряй мэйкфайл, смотри с какими ключами и какой компилятор запускается. Illegal instruction - насколько я помню, означает, что файл система сожрала, но на уровне исполнения произошла ошибка. Может -msoft-float нужно указать, может уточнить -march или -mcpu.
Собирать программу с нового ядра - под старое можно, но если честно, я никогда подобным не занимался. Вангую, что одними опциями компилятора тут не отделаться.
>>1060725 Да я сам этим никогда не занимался. Работаю в конторе веб-разработчиком, внезапно шеф вспоминает что у нас есть мультиплексор, собранный на заводе в другом городе. А поскольку единственный программист в штате - это я, то и поручили разобраться с этой штукой мне. А я с железками вообще никогда не работал. Исходники ядра есть, мне это мало о чем говорит. Содержимое мейк-файла на пикрил. Все эти ключи я уже пробовал. В линуксе на самой плате нет практически нихера, так что приходится компилировать на убунте в надежде что заведется на этой железке.
>>1060731 И что, скомпилированное с -static и -march=arm9tdmi точно также вызывает illegal instruction? Можно ещё конечно readelfом сравнить то, что успешно исполняется на плате и то, что получается после компиляции у тебя.
>>1060961 malloc возвращает адрес, подходящий для любой переменной, поэтому частично можно на это положиться, если на целевой машине переменные размером более 1 байта требуют выравнивания. На x86 выравнивание не обязательное, но на 8 байт тебя все равно выровняют. В целом, тебе, конечно, никто ничего не гарантирует, но на любой 32-битной машине malloc вернет тебе адрес, который кратен минимум четырем.
>>1061017 Потому что четное число по определению - это число, у которого остаток от деления на 2 равен нулю. Ну или можешь сказать, что это 2 умноженное на любое целое число.
>>1060999 >В целом, тебе, конечно, никто ничего не гарантирует, но на любой 32-битной машине malloc вернет тебе адрес, который кратен минимум четырем. Благодарю. А что бы наверняка, нет какой-нибудь опции проверить это, типа #ifdef MALLOC_ALIGN_EVEN ?
>>1061060 В С11 можешь узнать alignof(max_align_t). alignof в stdalign.h, max_align_t в stddef.h. До C11 с гарантией никак, но можно смотреть на выравнивание структур (если до проверки на него никто не повлиял директивами или ключами компилятора). В struct test_alignment { char x; double d; }; дабл скорее всего будет выровнен до его натурального выравнивания, поэтому sizeof(struct test_alignment) - sizeof(double) скорее всего даст тебе выравнивание меньшее или равное выравниванию, гарантированному malloc().
>>1060776 Всё это немного выходит за рамки языка Си и ближе к красноглазикам. Продублируй вопрос в /s/ на всякий случай. А ещё лучше, переконфигурируй glibc под целевое ядро и будет тебе счастье.
>>1061205 Разобрался с этой ерундой. Взял с https://www.uclibc.org/ образ root_fs_arm.ext2, примонтировал его, сменил корневой каталог на root_fs_arm.ext2/bin/su используя эмулятор qemu и там бинарник скомпилировался как надо, на целевой плате все работает. Спасибо за помощь. Сам бы я хер разобрался с этим всем.
Добрый вечер, господа. Интересует такой вопрос: может ли кто-нибудь из вас написать программу, которая считывает все данные из очереди сообщений POSIX (mqueue)? Чтобы прям вторым аргументом дать ей имя очереди, а на выходе в каком-нибудь файле получить содержимое очереди. Спасибо.
>>1062031 В первом случае ты объявляешь массив чаров, заполняешь первые 4 элемента, остальные заполнятся автоматически нулями. Во втором ты говоришь, что элемент 150 равен "abcd". Но одному элементу обязана соответствовать 1 символ.
У меня проблема, аноны. Компилирую под ARM, использую функции mq_open(), mq_send(), mq_recieve() библиотеки librt. При компиляции в конце ставлю флаг -lrt. Однако все равно получаю ошибку "undefined reference to `mq_open'". Посмотрел по пути /lib, там лежат библиотеки librt-0.9.27.so и librt.so.0. Пробовал даже подключать их так -L/lib/librt-0.9.27.so и -L/lib/librt.so.0, все равно не компилируется. Под убунтой компилятором arm-linux-gnuebi-gcc все работает как надо, но он мне не подходит. А в тулчейне с компилятором arm-linuxuclibc-gcc такая херня. Может кто-нибудь помочь с этим?
>>1062214 Еще добавлю что если в убунте проверить библиотеку таким образом: "grep -r mq_close librt-0.9.29.so", то ответ будет "Двоичный файл librt-0.9.29.so совпадает". А если сделать то же самое для библиотеки в тулчейне, то ответом будет пустая строка. Будто бы эти функции не реализованы в версии библиотеки librt-0.9.27.so. Я пробовал подменять библиотку в тулчейне с 27 на 29 версию, но компилятор все равно не видит этих функций.
>>1062540 Автоматически, естественно, за тебя \0 никто не поставит (ну кроме случаев, когда у тебя строковый литерал "foo", тогда да, он, как полноценная строка, включает в себя и \0 тоже).
>>1062542 Как распределяется этот мусор? Почему-то \0 каждый раз в одном и том же месте встречается, иначе бы 20 каждый раз после введения ab не выдавалось.
>>1062854 > Как распределяется этот мусор? Да ты охуел с такими вопросами. Все, что тебе нужно знать - это undefined behavior, и его нужно избегать, а не искать закономерности. Возьми gdb и посмотри содержимое стека, если уж так интересно.
>>1062975 > J.2 Undefined behavior > The value of an object with automatic storage duration is used while it is indeterminate > 6.7.9 > If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. Ты тут новичок, да?
>>1062979 >indeterminate На деле-то оно оказалось в моем случае достаточно детерменированным. Но методом тыка я уже разобрался, от чего зависит стабильное появление \0 в определенном месте мусорной кучи, когда его явно не задали в коде.
В вузе начали С, написали вот это, не работает. Гуглил, но там все ссылки на С++ ведут. Пробовал все кавычки и скобки, писал с .h и без, ничего не помогло. Что делать? Компилятор CodeBlocks Mingw
>>1063384 Хреново если так. Ибо без статика у меня на ARM-машине бинарник вылетает с ошибкой not found. Думаю оно имеет ввиду что не найдена библиотека.
>>1063395 Сейчас в России мейнстрим - STM32, у них ко всему прочему очень удобные отладочные платы с встроенным отладчиком. Полно семинаров/вебинаров от производителя, материалы все выложены. Здесь http://www2.hitex.com/download-isg неплохие мурзилки. Также постарайся не подсесть на ломаный софт типа IAR и Keil.
>>1063645 Тебе даже номера строк указали, где ты облажался. Поставь себе линукс и гцц, там сообщения на русском специально для дебилов, не желающих учить английский. Закрывать открытые фигурные скобки за тебя кто будет? А n(<15) - это что за заклинание?
>>1063352 С этим то аноном все ясно, похапе фрилансер 300к/сек и ничего, что про стек впервые слышит, но у меня вот реально проблема. Пишу на си, начинаю скучать по шаблонам и всякому ООП, тяне к плюсам. Начинаю писать на плюсах, охуеваю от этих блядских шаблонов и всякого ООП, тянет назад к сям. Пишу на чем-то другом - хочется вернуться к сям. Это как-то лечится?
Почаны, компуклирую под мипс на гцц. Readelf показывает, что в скомплированном объекте куча разных секций и символов. Стандартные секции типа bss, rodata, text и data - с ними всё ясно. Но где можно почитать про остальные секции, которые генерируются компилятором/линковщиком? Все эти reginfo, sbss, MIPS.abiflags, pdr и так далее?
Крестовые классы действительно удобны? Я люблю Си и не люблю кресты из-за тотальной усложнённости. Но если классы полезны, то, думаю, можно перейти на кресты беря от них только классы.
>>1064124 > Игорю пишу. Оно того стоит? Да, имеет некоторый смысл. Всякие коллекции (особенно с шаблонами) не придется переизобретать по сто раз на дню, перегруженные операторы сделают математику гораздо более читаемой, а виртуальные методы и наследование действительно нужны в играх (да, на сишке тоже можно, но на сишке и прыгать вокруг этого всего нужно больше). А вот переходить только ради того, чтобы использовать ключевое слово class и методы вместо ключевого слова struct и функций с явным this в сишечке - не стоит.
Ребятки, как научится правильно собирать программы вместе с большими библиотеками , например ffmpeg, в каких книжках это подробно объясняется для сопляков???
>>1064882 Поподробнее плиз. Ну есть тут например описание, и что дальше то делать , как например собирать со своим проектом, как это дело линковать, как создать .so библиотеку из этого всего с помощью gcc
>>1064873 Мне кажется, тебе нужен cmake. В каждой папке проекта ты создаешь конфиг, в котором описываешь действия над локальными файлами и связи с другими частями проекта. Например тебе нужно собрать экзешник, так ты перечисляешь исходники, указываешь расположение хедеров и подпроектов, в которых собираются библиотеки, прописываешь инструкции по установке (что и куда скопировать после сборки). cmake на основании дерева таких конфигов генерит множество более низгоуровневых конфигов, например тех же Makefile, но не обязательно.
autoconf (configure), упомянутый в ffmpeg похож, но ебанутее
Туториалов по cmake полно, но документация написана очень специфически, нужно время чтобы привыкнуть, без примеров очень сложно.
>>1064991 У тебя здесь s = '\0'; первое же вхождение "с" заменяется на нуль-терминатор. printf выводит всё говно до первого символа '\0', а он у тебя получается на в самом начале. Замени "ccabc" на "bbabc" и он тебе выведет "bbab".
>>1065400 Ты тредом не ошибся? > Какие регистры принадлежат контексту и требуют сохранения? Очевидно, что все, которые доступны для записи. pushad, pushfd, стейт FPU/SSE тоже, отладочные, сегментные регистры тоже имеет смысл сохранять.
>>1065290 > без необходимости обмазываться крестами/жабой/шарпом/питоном А что, в 2017 существуют такие программисты, которые пишут на каком угодно языке, но только на нем одном?
>>1065407 >А что, в 2017 существуют такие программисты, которые пишут на каком угодно языке, но только на нем одном? Мой вопрос исключил лишь определенные языки, а не вообще все кроме си.
Написал тест переполнения стека процессора: https://ideone.com/ok6m10 В ideone код не работает, в Dev-C++ запускается, вызывает сигнал SIGSEGV, т.е. насколько я понимаю, признает стек переполненным и затыкается. Проблема в том, что по ТЗ тест должен выдать результат - например, число итераций, которое вызывалась рекурсивная функция или подсчитанный объем стека в байтах. То есть, после переполнения программа должна продолжаться. Отсутствие эксепшенов в Си слегка вгоняет меня в ступор. Как продолжить работу программы при переполнении?
Была мысль с помощью malloc оценивать свободное пространство, и если malloc возвращает null, сворачивать рекурсию, но такое не заработало.
Вообще такая задача вызывает у меня массу вопросов, например, есть ли смысл проведения подобного теста. Логика тут вообще такая: функция вызывается рекурсивно и на каждой итерации N создается 3N переменных. Отсюда сразу еще и такой вопрос: надо ли очищать через free память на каждой итерации?
>>1066364 > переполнения стека процессора В процессоре нет стека.
> тест Хуевый тест. Это все очень сильно зависит от ОС.
> То есть, после переполнения программа должна продолжаться. Ты слегка охуел. После подобных ошибок программа должна тихо сдохнуть. Тем более после сегфолта. Но ты можешь попробовать, во-первых, сделать свой counter volatile, во-вторых, установить обработчик SIGSEGV с помощью signal (signal.h) и всю работу делать в обработчике. Но гарантий не будет никаких. В-третьих, можешь подумать о setjmp/longjmp для возврата из обработчика сигнала в main. Это не по стандарту, но в целом работает.
Лучше зделой программу, которой ты передаешь аргументом глубину рекурсии и вторую программу, которая запускает первую и бинарным поиском выбирает максимальную глубину, при которой дочерняя программа перестает валиться. Если у тебя никсы, можешь форками обмазаться, суть одна и та же.
> Была мысль с помощью malloc оценивать свободное пространство В винде, например, есть лимит на размер стека. Т.е., свободной памяти еще гигабайты, а у тебя стек оверфлоу.
>>1065407 Многие системщики. Хотя сейчас железо позволяет портировать кресты дохуя куда, потому как правило, пишут только самые низкоуровневые вещи, потом портируют компилятор цэ2плюса и далее пишут на плюсах. Более того, тут Rust завезли, который, по слухам, пиздат до невозможности, умеет почти что в сборщик мусора, но без рантаймов (все полезности делает компилятор) и еще всякие плюшки. Думаю, если все действительно так радужно, скоро начнут писать низкоуровщину на нем. Тащемто, он для этого и проектировался, чтобы писать не на сях там, где можно писать только на сях и ассемблере.
https://pastebin.com/tH3jt3p1 Почему после ввода любой буквы начинается бесконечный цикл с default? Ведь буквы же в Си имеют и числовое представление. После ввода любой цифры больше трёх default нормально срабатывает, мне нужно, чтоб и с буквами также было.
>>1068706 > Почему после ввода любой буквы начинается бесконечный цикл Платина. 1) Потому что буквы не подходят под формат %d. 2) Потому что ты не проверяешь возвращаемое значение scanf. 3) Потому что в input при вводе буквы ничего не присваивается, там мусор. 4) Потому что после ввода буквы ты не очищаешь поток ввода, и там по-прежнему остается буква.
> Ведь буквы же в Си имеют и числовое представление Если %с скажешь, будет у тебя числовое представление буквы, но тогда и конвертировать цифры из строки в число для тебя никто не будет.
>>1068719 >3) Потому что в input при вводе буквы ничего не присваивается, там мусор. >4) Потому что после ввода буквы ты не очищаешь поток ввода, и там по-прежнему остается буква.
Тогда почему вместо мусора в бесконечном цикле отображается последняя введённая цифра, если в коде перед scanf в цикле поставить printf("%d\n",input);, затем после запуска ввести цифру, а потом букву?
>>1068762 Если после ввода буквы scanf ничего не присваивает переменной input, тогда оставшаяся часть цикла должна сработать как при предыдущем значении input. Что мешает-то?
Анон, где полную документацию изменений в С11 поискать? Из основных тезисов ничего не сказано про константы и присваивания
int a, b, m, n, z; m = n = 5; z = a = b = 0; z--, ( a = b ) = z + ( m != n ); printf ("%d %d %d %d %d\n", a, b, m, n, z); MingW последний с c11 стандартом пропускает это, C99 выдает ошибку на =(без скобок считает)
Или еще
int x; x = 5; ++ x =10; printf ("%d\n", x);
C11 меняет константу(я еще не проверял в дебагере), ну он точно выдает 10, C99 не пропускает эту ошибку.
>>1071641 Оба твоих примера не скомпилируются. Оператору = нужно lvalue слева, поэтому никаких инкрементов, никаких скобок туда втыкать нельзя. И, конечно же, ничего в C11 по этому поводу не менялось, и в дальнейшем тоже не изменится. Подозреваю, что ты, как и многие итт, перепутал Си с крестами. В крестах так можно.
>>1063703 Слушай я сам вкатился в Сишку после 10 лет опыта в С++, но по шаблонам скучал только первые пару месяцев и недоумевал почему их не добавили в стандарт, а потом понял почему и решил что правильно сделали не дай бог им там появиться. Ну ты и сам поймешь потом, просто для примера возьми и сравни исходники какого-нибудь крупного С проекта, типа ядра линукс или гцц, и сравни их с каким нибудь проектом на С++, ты охуеешь насколько С++ уебищный и непонятный язык по сравнению с СИ, во многом ( если не в основном ) благодаря шаблонам. Как сказал один мимохуй где-то в интернетах: Если ты за 2 минуты чтения хедера не понял полностью как это все работает, то можешь смело выбрасывать такой код в помойку. И это правильно сказано, хочу заметить.
Вообще, советую забыть вообще, что такое С++ и что ты когда-то что-то писал на нем, когда будешь вкатываться в СИ. Это абсолютно разные языки, несмотря на то, что типа С++ продолжение СИ, это не так, С++ это издевательство и глумление над СИ, его проектировали больные люди, возьми к примеру хотя бы создателя STL, ну а чтоб полностью убедиться в этом открой исходники Boost.
Я вот уже где-то год, пишу в основном на СИ, после тех бездарно потраченых 10 лет на С++. И до сих пор переодически нахожу вещи введеные в самых первых стандартах, куда более продуманными и логичными по сравнению с последними высерами в стандартах С и С++. Я даже не использую С11, потому что там нету ничего полезного, ну может кроме stdatomic.h которые спокойно заменяются GNU built-ins в GCC и Clang ( и мб Intel ) ( а другие компилеры и не нужны ). Даже посмотри на комментарии в стиле С++ даже они уебищны сами по себе, превращая код в кашу их каких-то пометок, будто на туалетном листе и сравни блочные комментарии ANSI C, которые предназначены для подробного описания кода цельными блоками в основном в хедерах над фунциями и структурами данных, а не пометками посреди кода, которые только ухудшают его читаемость. Еще т.к я бывший плюсовик, то естественно привык объявлять переменные по ходу надобности, прямо по среди кода. Недавно осознал что, отцы K&R все-таки не просто так это сделали и не из-за каких-то там ограничений или чего-то подобного, а потом типа появился спаситель С++ и разрешил хуярить все в перемешку, потом отупевшие от этого люди в стандарте добавили это в ISO С99. А теперь поясню почему разделение кода и данных это хорошо: Во-первых, это СУЩЕСТВЕННО повышает читаемость кода. Во-вторых, это не дает тебе лепить большие толстые функции > ~100 строк, ведь чем больше функция тем больше в ней задействованно переменных, и тем труднее за ними уследить в одной области видимости, в купе с обработкой ошибок через goto. Как говорится в linux kernel code style guide - Functions should be short and sweet, and do just one thing. .. if you have a complex function, and you suspect that a less-than-gifted first-year high-school student might not even understand what the function is all about, you should adhere to the maximum limits all the more closely. Use helper functions with descriptive names (you can ask the compiler to in-line them if you think it’s performance-critical, and it will probably do a better job of it than you would have done).
Another measure of the function is the number of local variables. They shouldn’t exceed 5-10, or you’re doing something wrong. Re-think the function, and split it into smaller pieces. A human brain can generally easily keep track of about 7 different things, anything more and it gets confused. You know you’re brilliant, but maybe you’d like to understand what you did 2 weeks from now. ...
Вот эти золотые слова, должны быть основой любого code style любого проекта. А если этих правил предерживаться, то Mixed declarations and code абсолютно не нужен, и должен быть отключен в компиляторе через -Werror=declaration-after-statement, если используется стандарт поддерживающий это.
В общем, можно еще долго дискутировать на тему, чем СИ лучше С++ и не зря все серьезные проекты пишутся на СИ, а не С++. Со временем ты поймешь все эти истины и вообще больше не захочешь видеть С++ никогда в жизни, если уж что-то надо быстро и просто накалякать что-то на коленке, то лучше взять более приспособленные языки типа явы или C#, а не С++.
>>1071874 > А теперь поясню почему разделение кода и данных это хорошо: > Во-первых, это СУЩЕСТВЕННО повышает читаемость кода. Долго держался, но все же проиграл с поехавшего.
>>1071883 Мне тоже показалось, что что-то неладно, но если там и правда >5-7 автоматическиъ переменных на фукнкцию то лучше их объявить в начале, и правда
>>1071874 > Если ты за 2 минуты чтения хедера не понял полностью как это все работает, то можешь смело выбрасывать такой код в помойку. Как по мне если ты чего то не понимаешь, скорее всего ты тупой.
>>1071947 Нет, конечно тебе будет казаться это неудобным после того как везде пихают уже mixed declarations. Но поверь опыту действительно лучших программистов в мире - разработчиков ядра линукс, в которые входят люди из разных топовых компаний типа гугла, интела, амазона и т.д с топовыми образованиями. Они то просто так не станут придерживаться такому code style, который отточен и проверен годами. Почитай исходники линукс, все функции там действительно маленькие, и с ходу понятные. Тем более, в си и с++ разные методики освобождения ресурсов, если в с++ используют RAII, шаред поинтеры и т.п. когда можно не парясь сделать return посреди функции или бросить исключение и ресурсы автоматически очистятся, то в си так сделать нельзя, в си ошибки обрабатываются обычно через goto на секции с освобождением ресурсов и представь как легко ошибиться, если у тебя в коде каша из переменных. А если у тебя код разбит на маленькие функции по несколько переменных, то начиная читать код ты сразу видишь какие ресурсы у тебя в функции есть и легко проверить все ли ресурсы были освобождены по выходу из нее. Если ты бы когда нибудь писал на ассемблере, то понимал бы как легко ошибиться даже с памятью на стеке. В общем, си это тебе не хуйня для обезьян типа крестовиков и всех остальных чернорабочих. С++, как и другие ООП языки не требует особой подготовки, поэтому на них выгодно делать проекты в коммерческих компаниях, где можно как можно с меньшими затратами заменить Васю на Петю, порог вхождения низкий.
>>1071953 Вынужден тебя разочаровать, это далеко не всегда так. Как я уже цитировал выше, Линуса: >if you have a complex function, and you suspect that a less-than-gifted first-year high-school student might not even understand what the function is all about
Твой код должен быть понятен, даже студенту школьнику, если ты конечно не говнокодишь лично для себя.
Я за 10 лет работы С++ прогером, успел навидаться такого говнокода, что приходилось иногда по нескольку часов разбираться, что там куда и откуда эти шаблоны и классы ведут. Ведь многие прогеры на с++, часто вообще полностью пренебрегают чистотой кода, и хуярят лиш бы работало. А чо? Язык позволяет и похуй.
Я считаю, единственный возможный вариант использования С++ это СИ с классами либо какие-то вариации MISRA С++, Где запрещены STL, шаблоны, исключения, виртуальные функции, и т.п и тем более полностью запрещен С++11.
Но если ты рядовой быдлокодер, не заморачивайся и ебаш как попало с шаред поинтерами и т.п. А лучше вообще возьми пыху или JS там с каким-нибудь electron'ом и вообще все будет в шоколаде.
>>1071984 Не не не, я не сомневаюсь что есть случаи когда говнокод - это говнокод. С этим ничего не поделаешь. Но заявление про 2 минуты - это уже как-то попахивает максимализмом. Да и вообще это таоке, мол мне лень разбираться в коде, лучше сам напишу всё заново. В итоге вместо 1 говнокода в конторе теперь 2.
>>1071874 >ну а чтоб полностью убедиться в этом открой исходники Boost. ... - сказал человек, ни разу не открывавший исходники STDlib. >его проектировали больные люди Почти все программисты отчасти больные люди. Плюсы проектировали, пытаясь сохранить совместимость с C, и благодаря этому язык получил развитие. Было ли это компромиссом по сравнению с чьим-то идеалом? Да. >Со временем ты поймешь все эти истины "Понять истины" - это словосочетание сроду "нырнуть в камни". Если то, что ты изрекаешь, называется истиной, то её можно познать. Чтобы познать истину, достаточно критического склада ума и того, чтобы кто-то её продемонстрировал. Считаешь, что всё сказанное тобой истина и негативно характеризует именно плюсы - вперёд, демонстрируй, мы посмотрим. >отцы K&R все-таки не просто так это сделали и не из-за каких-то там ограничений или чего-то подобного, а потом типа появился спаситель С++ и разрешил хуярить все в перемешку, потом отупевшие от этого люди в стандарте добавили это в ISO С99. Я хочу сделать две переменные, инициализатор одной я могу вычислить одним выражением, а для инициализации другой мне нужно несколько строк кода или луп. Что предлагают отцы? Олсо, что предлагают отцы, если я хочу определить функцию в функции? Ну, знаешь, такую, которая вне этой функции не понадобится, а назвать для улучшения читаемости кода хочется. >А теперь поясню почему разделение кода и данных это хорошо: Лучше поясни, почему предоставленная свобода является свойством языка, а не тех, кто на нём пишет. Никто не мешает тебе сделать свой стиль кода и придерживаться его (очевидно, что ты можешь позволить себе это, если ты перешёл с плюсов на Си), ты даже можешь написать свой анализатор, который будет тебе пинка давать в нужном месте. Либо докажи, что на Си нельзя написать нечитаемую работающую мешанину. >Ну ты и сам поймешь потом, просто для примера возьми и сравни исходники какого-нибудь крупного С проекта, типа ядра линукс или гцц, и сравни их с каким нибудь проектом на С++, ты охуеешь насколько С++ уебищный и непонятный язык по сравнению с СИ, во многом ( если не в основном ) благодаря шаблонам. Си - уёбищный и непонятный язык по сравнению со Schema. Из шаблонов мне не нравится специализация, методика разворачивания вариативного списка аргументов, следовательно, всё это я не использую. Так тоже можно. >и тем труднее за ними уследить в одной области видимости, в купе с обработкой ошибок через goto. >А теперь поясню почему разделение кода и данных это хорошо: Звучит иронично, потому что в плюсах ты и данные мог отделять (один блок определений на несколько методов), и ошибки мог обрабатывать не через гото, а вызовом методов и лямбд или даже с помощью исключений. >пометками посреди кода, которые только ухудшают его читаемость. >Еще т.к я бывший плюсовик, то естественно привык объявлять переменные по ходу надобности, прямо по среди кода. Жирными мазками эпатируешь, блядь.
>>1072029 >Олсо, что предлагают отцы, если я хочу определить функцию в функции? Ебать говноед. Дальше не читал. Если ты хочешь определять функции в функции, то тебе точно не в семейство языков СИ.
>>1072043 >лежать в единицах трансляции кучей и не быть никак связаны Не особо понял, что ты имел ввиду. У функций есть разный linkage - external и internal. Что тебе мешает связать функции из разных единиц трансляции?
>>1071874 Чот толсто >Если ты за 2 минуты чтения хедера не понял полностью как это все работает, то можешь смело выбрасывать такой код в помойку. 10 лет опыта, и в коде не разбираться, да даже если это говнокод, то это всё прекрасно разбирается.
Возникла необходимость кроссплатформенно (на уровне исходного кода) создавать окно и получать его идентификатор (пикрелейтед 1). Делать это было решено с помощью GLFW, однако тут я внезапно столкнулся с некой проблемой - линковкой. Для компиляции пользуюсь gcc из набора MinGW (пикрелейтед 2). Путь к библиотекам прописал, сами библиотеки он тоже видит (если, например, ошибиться в названии, то начинает ругаться на не найденную билиотеку), но при этом выбрасывает "undefined reference" на вызов любой функции из GLFW. Исходный код - пикрелейтед 3.
>>1072060 >Что тебе мешает связать функции из разных единиц трансляции? Конкретно мне мешает то, что в плюсах есть гораздо более удобный способ классифицирования функций и вложения их. Да, действительно, можно компенсировать отсутствие неймспейсов, классов и лямбд бОльшим количеством файлов с кодом, но ЗАЧЕМ?
>>1072210 Че за хуйню несет? Пиздец. Иди учи матчасть. Функции у него не линкуются, перменные глобальные везде, функции глобальные. Ебануться ты про какой вообще язык говоришь?
>>1072213 >Функции у него не линкуются Сам придумал, сам посмеялся? >функции глобальные В C есть "неглобальные" функции? >перменные глобальные везде Это вообще-от вопрос был. Судя по тому, как ты отказываешься на него отвечать, переменные у тебя неглобальные. Теперь объясни мне, почему переменные не должны быть глобальными, а функции должны.
И вообще вырази свою точку зрения лучше, чем "дальше не читал".
>>1072230 > В C есть "неглобальные" функции? Я не он, но предположу, что статические в некотором роде неглобальны, так что инкапсулировать можно с помощью статика.
>>1072230 >В C есть "неглобальные" функции? Представь себе. Ну ты наверняка не слышал даже о линковке символов в С, и не представляешь как выстроить программу на С. Понятие не имеешь о модульности, о заголовочных файлах, о юнитах компиляции, о модификаторе static, о формате ELF, о его секциях, о том что представляет собой бинарный файл и как система его читает. Советую ознакомиться со всеми этими вещами, тогда может быть ты перестанешь нести откровенный бред и научишься наконец-то программированию, а не макакингу.
В С есть все, что необходимо для построения самых сложнейших систем. Если даже на чистом ассемблере пишут полноценные ОС типа калибри и минует, то о чем вообще речь?
Я не собираюсь тебе тут расписывать все детали построения программ на С, потому что в инете полно материала об этом и это не описать в двух словах. Нужно понимать как вообще работает все на низшем уровне от структуры бинарника, до модификаторов видимости символов в С. Если ты не хочешь в этом разбираться, тогда С не для тебя. С это довольно низкоуровневый язык, который требует глубокого понимания предметной области, чтобы на нем писать, что-то сложнее хелоу вордов.
>>1072238 Ты уже и меня заебал своей тупостью. В си вообще нет ни глобальных функций, ни переменных, иди почитай стандарт. Но при этом мы все тут понимаем, что имеет в виду анон выше. Торчит ли при этом у тебя фунция голым задом из модуля не имеет никакого значения.
>>1072238 Ты не туда воюешь. Си я более-менее знаю и пердолить статики, указатели, маллоки, битшифты, препроцессор, рекурсивные макроопределения, хвостовую рекурсию и прочее я умею. >Ну ты наверняка не слышал даже о линковке символов в С Она такая же, как в плюсах (минус пердолинг с названиями экспортов в таблицах), так что слышал. >Понятие не имеешь о модульности В плюсах то же самое. Испугал ежа голой жопой. >о заголовочных файлах, о юнитах компиляции, о модификаторе static В плюсах то же самое. Глобальная переменная тоже может быть невидимой извне, неглобальной она от этого не становится. Все функции в Си "глобальные" (о чём я тебе и говорил). >о формате ELF, о его секциях, о том что представляет собой бинарный файл и как система его читает. К языку С не относится касательно, к стандарту языка С - никак. Нужно будет знать что-то о формате ELF или WinPE - открою спецификацию и прочту, это святыня какая-то? >В С есть все, что необходимо для построения самых сложнейших систем. Тебе для построения сложнейших систем необходимы только кнопки 0/1 и бумага с ручкой. >Если даже на чистом ассемблере пишут полноценные ОС типа калибри и минует, то о чем вообще речь? Это ты мне скажи, о чём ты ведёшь речь. Я задал дискусионный вопрос автору высера, ты из всего моего линного поста выделил именно его.
>>1072246 >Торчит ли при этом у тебя фунция голым задом из модуля не имеет никакого значения. Вот как раз это имеет огромное значение при проектирование приложений. Я вообще не понимаю, что вы тут хотите мне доказать? Что язык С не соответствует каким-то вашим ожиданиям и представлениям о локальных и глобальных переменных?
>>1072251 >Глобальная переменная тоже может быть невидимой извне, неглобальной она от этого не становится. Все функции в Си "глобальные" Блять, поясни пожалуйста тогда что ты понимаешь под локальный и глобальной переменной, потмоу что по моему у тебя об этом не правильное представление. Алсо, ты можешь сделать перменную локальной в пределах юнита компиляции, ты можешь сделать переменную локальной в пределах области видимости функции, цикла, условия и вообще любого блока видимости.
>>1072292 >Я вообще не понимаю, что вы тут хотите мне доказать? Лично я сюда зашёл для того, чтобы привнести рациональность в пост 10летнего крестовика. >>1072292 >Блять, поясни пожалуйста тогда что ты понимаешь под локальный и глобальной переменной, потмоу что по моему у тебя об этом не правильное представление. Локальное - это то, что определено в структе или компаунд стейтменте. В стандарте вообще не используются слова global (только в одном месте: http://port70.net/~nsz/c/c99/n1256.html#F.8.1p1) и local, так что по отношению к стандарту неправильным моё представление быть не может. >Алсо, ты можешь сделать перменную локальной в пределах юнита компиляции Здесь наши с тобой опыты расходятся. В моём опыте никто и никогда не говорил о невидимых извне переменных, как о локальных. В качестве пруфа моей нормальности прими ссылку на стаковерфлоу: https://stackoverflow.com/search?q=%5Bc%5D+local+variable
>>1072311 >Локальное - это то, что определено в структе или компаунд стейтменте. В стандарте вообще не используются слова global (только в одном месте: http://port70.net/~nsz/c/c99/n1256.html#F.8.1p1) и local, так что по отношению к стандарту неправильным моё представление быть не может. >>1072292 >язык С не соответствует каким-то вашим ожиданиям и представлениям о локальных и глобальных переменных?
То, что ты там себе навыдумывал про свои идеалы локальных переменных, не значит абсолютно ничего.
Я не понимаю, как по твоему должно было быть?
По моему, все очень логично. extern - глобальная переменная. static - локальная в пределах компиляции. auto - локальная на стеке. __thread - локальная в пределах треда.
Тебе этого мало? Я просто даже не представляю, какие виды локальных переменных еще могут быть По моему опыту в различныъ ЯП кроме С/С++, типа Явы, С#, D, питон, перл, луа, пхп, яваскрипт, хаскель, математика, матлаб. Нигде виды переменных особо не отличаются, ибо это то, что есть в С, это уже более чем достаточно.
>>1072358 >Тебе этого мало? Во избежание дальнейшего разговора на неинтересную мне тему я не буду напоминать тебе о том, что мой дискуссионный вопрос, дальше которого ты не читал, был не о переменных. >Нигде виды переменных особо не отличаются Бред сивой кобылы. Ты говоришь о видимости? Видимость переменных может: 1) вообще не зависеть от места их определения, а лишь от того, было выполнено определение или нет - Perl (с версии 5 скоуп управляет только хранением, а не видимостью), Шелл до какой-то версии (в баше можно приписать local. В Посиксе этого нет) 2) зависеть от скопа (функция, глобальный, суперглобальный), от static (значение совсем другое) и от того, было ли выполнено определение - PHP 3) зависеть от того, было ли объявление выше в скопе (без учёта вложенности блоков), при этом у каждой функции свой скоп - Джаваскрипт 4) версия Си - скоп на каждую фигурную скобку 5) чистая функциональщина И это я ещё про единицы трансляции не говорил: в PHP вообще нет доступа к переменным извне и нет способа определения одной переменной на всех. Что значит "не отличаются"? >Я не понимаю, как по твоему должно было быть? По-моему должно быть так, что если есть несколько функций, которые работают с одними и теми же данными, то у меня должен быть инструмент для их обобщения. Такой инструмент у меня есть. >extern - глобальная переменная. Допустим, что я понял твою криво выраженную мысль. Дай ссылку на текст, в котором под глобальностью подразумевается именно это.
Простой вопрос. Как вывести значение из двумерного массива указателей "int ✬✬arr;". По-простому "arr[num][num]" сигфолтит. Это у меня проблемы или так делать в сишке нельзя?
>>1072400 >Бред сивой кобылы. Ты говоришь о видимости? Видимость переменных может: Ладно может с пхп и яваскрип я что-то напутал ибо последний раз писал на этом еще в школе. Но говоря про С только видимость определяет тип переменной. Т.к в С нету объектов, а есть только базовые типы и структуры состоящие из них, то есть переменные при выходе из их области определения не нужно очищать, вызывать деструкторы и т.п ( кроме переменных на стеке, где память указываемая ими, может быть перезаписана после выхода из области видимости в силу специфики работы стека ). Но ты понимаешь, что С это низкоуровневый язык где предоставляющий тебе самому управление памятью, а в других языках, инициализация и деинициализация переменных может влечь за собой аллокейты из кучи и другие действия, типа сборки мусора и т.п? В С как в ассемблере, хочешь глобальную переменную, определяй ее в секции .data, хочешь локальную переменную вычитай сколько нужно из rsp, хочешь динамическую память, дергай ядро ОС.
>По-моему должно быть так, что если есть несколько функций, которые работают с одними и теми же данными, то у меня должен быть инструмент для их обобщения. Ну так и что, тебе мешает такой инструмент реализовать без глобальных переменных? Используй контекстный метод, передавай структуру в эти функции в качестве аргумента. Я сейчас работаю над одним достаточно крупным проектом на С, и у меня там нет ни одной переменной определенной за пределами функции. Вообщ,е использовать глобальные переменные не очень хорошая идея, в любом языке программирования. Глобальные переменные - это костыли для использования не очень хорошо спроектированных интерфейсов, которые не позволяют передать свой контекст во внутрь.
> Дай ссылку на текст, в котором под глобальностью подразумевается именно это. У тебя своей головы нету, чтобы без чужого мнения это самостоятельно понять? Ты когда объявляешь переменную в глобальном неймспейсе, она по умолчанию extern.
>>1072432 Хватит уже про Си рассказывать, я без тебя знаю его и до фига всего другого, и про экстерн я тоже знаю. Даже если ты очень знающий и скиластый, ты должен с собеседником говорить, а не сам с собой и своими мыслями. >У тебя своей головы нету, чтобы без чужого мнения это самостоятельно понять? Ты так и не открыл ссылку, по которой находится список вопросов и ответов о языке C, в которых люди употребляют слова "local" и "variable". Попробуй прочитать эти упоминания, держа в уме твоё личное определение глобальности. Пока ты этого не сделаешь, говорить с тобой не о чем. >Ну так и что, тебе мешает такой инструмент реализовать без глобальных переменных? Какие ещё глобальные переменные, блядь? Ты совсем охуел? Прочти ещё раз цитату >>1072042 из моей портянки, которую ты осуждаешь, слова "переменная" там нет. И это, если ты не знал, в С++ (языке семейства С++) с 11 года есть лямбды, подмножество которых совместимо с C-функциями.
>>1072480 Обсуждаем термин "глобальная переменная", который во всём мире означает "определённый вне функций", а именно у этого почтенного индивида означает "external linkage". Заодно практикуюсь в общении с людьми, которые учат меня, разговаривая сами с собой.
>>1072476 >>1072497 >"глобальная переменная" означает "external linkage". Ну так и есть. Определи ее вне функции в *.c файле со static она будет локальной на уровне юнита компиляции не будет доступна из вне, что как раз и означает локальность. Как этого можно не понимать...
>>1055733 (OP) шарю лютейшую годноту от реально гения в плане разъяснениыя. Да, он ебанный индус, да блядь его произношение это пиздос, но блядь, как же он ахуенно разъясняет и объясняет то, что вы будете читать в 1к страничных книгах.
После этого рекомендую пробежатся уже по King C.C. A modern Approach C (2008), что бы закрепить материал.
Потом советую пройтись по C in Nutshell, для более продвинутого закрепления и понимания сишечки.
Потом советую прочитать: Reese R. - Understanding and Using C Pointers - 2013
что бы варится нормально с указателями, различными динамическими структурами и всем этим самым сложным, что создает кучу проблем, но не будет создавать для вас, потому что будете понимать как это устроено.
Потом обязательно Practical C Programming 3rd Edition
И Ben Klemens - 21st Century C, 2nd Edition - 2014
Ну и к этому моменту вы будете свободно плавать в синтаксисе и понимании языка для выражения всего чего можно, вот тут и начинается само программирование, и погружение в программирование и написание годноты и чего только захотите: Principles of Data Structures Using C
Ну а дальше ищите книги по структурам данным, по различным алгоримам, и пишите алгориты, и различные реализации, паттерны и прочий шлак, и реализовывайте, реализовывайте всякие алгоритмы и прочий скам, подключайтесь к различным проектам.
Но до этого ОБЯЗАТЕЛЬНО загуглите нормальные туториалы по дебагингу, профайлингу, поиску и нахождению ошибок и так далее.
Ну а дальше уже дело практики - писать нужно дохуя и много.
=======================
Теперь что касается шапки - шапку писал отбитый нахуй долбоеб.
К&R крайне критикуемая книга, которую книгой назвать нельзя, она нахуй вообще ни на что не годится, это некий референс документ, а для референса всегда есть Prinz P., Kirch-Prinz U. - C Pocket Reference - 2002
Различные праты, и прочий скам на русском - так же не рекомендую, они перевирают кучу всего, и дохуя всего не работает. Начните с индуса выше, что бы было визуальное представление как все устроено. А только потом читайте книги, они будут даваться вам в десятки раз легче, когда уже в голове визуализацию выстроил индус.
Ну а дальше винапи, и прочий скам, можете на С++ перекатиться, можете продолжить дрочитьСи.
Самое главное к чему вы должны прийти это писание кода и тестов к нему. Не пишите тесты - значит вы хуёвый дегенерат нахуй никому не нужен, и знания ваши никчемны.
Не можете понять что такое Binary Heap - вы нахуй не нужны в программировании.
===============
касательно мотивации - к сожалению с Си без вовлечения в какой-то проект где он используется будет крайне тяжело если сравнивать например с C#
Потому что либ практически нет (вернее они есть, но не для простых инетересных и понятных вещей) плюс будете 90% времени не писать код, и фиксить баги и чужие краши. Поэтому программированию особого не научитесь.
Если хотите именно научится программированию - то питон это ваше все как первый язык, либо Go, и то, лучше всеже питон, потому что то, что вы будете писать месяц на Си, на сотнях строк кода, в питоне умещается лаконично в 20 строчек без вдавания в детали.
В Питоне вы именно программируете, и изучаете эти структуры, и прочий шлак, без траты просто пиздец какого куска времени на борьбу с указателями, памятью и прочей хуйней на которую находясь на этапе новичка - вы не должны тратить и ебать свой мозг, потому что это очень тяжело.
Это как получившего только что школьника права и категорию Б, посадить за штурвал истребителя, и показать - как взлетать, и сказать "Ну ты там в воздухе разберешься", так не бывает.
>>1072613 да я тоже проигрываю постоянно. Но согласись, все по делу, и с дельными примерами, ничего вообще лишнего и нет задач "а давайте посчитаем на нашем первом занятии факториал такого-то числа, либо единицы измерений математической формулой поизменяем.
>>1072102 Бамп вопросу. Использование конкретно GLFW вообще необязательно, сойдёт любая легковесная кроссплатформенная библиотека, которая сможет создать мне окно и дать его идентификатор.
Бля, помогите пожалста с однородными массивами https://ideone.com/MNI6wN Прога должна считать сумму всех отрицательных чисел, произведение между максимальным и минимальным значением и затем сортировать по возрастанию. Сумму и сортировку делает, а произведение делает, но не так - добавляет в вычисление либо максимальное, либо минимальное значение, смотря какое первее стоит. Что не так в коде? И как сделать так, чтоб если между максимальным и минимальным нет чисел, писало что-нибудь типа "произведение = 0"?
>>1073775 > *imin=i; Не делай так. i не инициализирована.
> добавляет в вычисление либо максимальное, либо минимальное значение Очевидно, что тебе нужно начинать цикл не с frirst, а с first + 1.
> И как сделать так, чтоб если между максимальным и минимальным нет чисел, писало что-нибудь типа "произведение = 0"? if (first + 1 >= end) { return 0; } (естественно, swap перед этим по необходимости).
думаю сейчас о такой вещи, как... например, есть приложения и есть их менеджер, всё вместе работает на одном потоке - менеджер переключает выполнение когда приложения или выходят из своего main(), или вызывают специальную функцию - для каждого делаем setjmp() и заранее отделяем стек, типа по 1К, например - ну понятно, после прыжка же стек будет смещён назад. наверно как-то нужно самому хранить верхушку стека - не очень пока вижу всю историю в целом.
как-то грустно это всё. нахуй нужны тогда эти джампы, чисто чтобы вылезти из глубокой рекурсии, ну да. но не вылезти и вернуться. хотя нет, вернуться же можно.
а что если, вызывая новое приложение, прыгать к самому последнему и из его кода делать call....
ну это тоже, не используя стек внутри функций (строго память) и не вызывая их. фигня короче.
просто я вот думаю, как сделать удобней возврат после запроса в обработчик. ну вот, допустим он вызывает опять приложение app0(void p) - где *p для значений этого инстанса. и как вот туда ему прыгать, к контексту внутри? switch ? гццшный goto массив? я не знаю.
наверно действительно проще треды. может у этого название есть, типа блокирующиеся треды в одном потоке. хер знает.
>>1074785 > может у этого название есть, типа блокирующиеся треды В нормальных ОС это есть искаропки. Называется фиберы, реализуют кооперативную многозадачность. И да, чем тебе не нравится ебля контекста ручками? Это единственный адекватный подход. И вообще, чего ты добиться хочешь и зачем? И ты заебал своим бложеком, иди-ка ты в /dr/. Или пиши нормально.
вообще я смотрю это позиксная ucontext.h мне нужна. но интересно было бы запердолить как-то вручную. и не понятно откуда берётся слово то фибр, если везде пишут про курутинс.
>>1074803 ладно-ладно. не обижайся, это было познавательно.
Если инициализировать поинтеру адрес 0, и инициализировать его значение нулем, и в рамках цикла идти дальше пока не не закончится память, инициализируя все нулем, можно ли так все данные в памяти компьютера переписать?
>>1074900 В современных ОС - только память процесса, да и то с оговорками: придется проглатывать исключения при попытке доступа к невыделенной памяти и придется как-то обойти свой собственный код. Чтобы затереть всю память (как делает, например, BIOS при проверке памтяи), нужен нереальный (flat real mode) или правильно настроенный защищенный режим, чтобы процессу была доступна последовательно вся физическая память.
>>1074949 > Будет null pointer dereference и сегфолт. NULL pointer - это абстракция из стандарта Си. В любой ОС можно сделать так, чтобы никаких сегфолтов не было. В частности, в XP (и вроде бы даже в 7 SP1 до некоторых пор) можно было выделить память по 0 прямо из юзермода, без особых привелегий.
>>1074977 При чем тут абстракции языка? Ты понимаешь, что переменная это всего лишь указатель на адрес памяти?
Если ты напишешь на С: char mem = 0; mem = 0;
То на ассемблере это будет выглядеть примерно так: mov ax,0 mov [ax],0
Что является обращением к памяти по адресу 0, что на системе с виртуальной памятью в user mode вряд ли возможно, т.к процессу назначается не нулевой стартовый адрес. В общем, такое невозможно в принципе сделать в загруженной ОС.
>>1074993 У постфиксного ++ приоритет выше всего, поэтому берется адрес из s, потом s инкрементируется, потом адрес дереференсится звездочкой, потом аналогично вычисляется левый аргумент, и = пишет в него значение из правого. Более понятный аналог: float temp = (t[0] = s[0]); // Ну или звездочки, но их макака съест. printf("%f ", temp); ++s; ++t; На свой вопрос сам ответишь.
>>1075003 > При чем тут абстракции языка? При том, что по соглашению и из-за распространенности Си операционные системы не мапят первые 4 или 64 килобайта. Чтобы говнокод с NULL падал, как и положено. Но: 1) Ты вообще читал, что я написал? Никто не запрещает тебе выделить память самому. Если не из юзермода, то уж из кернелмода 100% возможно. 2) У тебя там 16-битные инструкции, а в том же DOS обращение по нулевому офсету было стандартной практикой, а с обращения к нулевому офсету нулевого сегмента (far null pointer) начиналась печать таблицы обработчиков прерываний. Например, в отладочных целях.
>>1075010 > Если не из юзермода, то уж из кернелмода 100% возможно. Ни чего что кернел мод работает с виртуальной памятью тоже? И обычные kmalloc выделяют тебе виртуальную память?
>>1075004 Меня интересует случай, когда присваивание находится внутри printf. Правильно ли я понимаю, что раз левый аргумент вычисляется последним, то его значение и напечатается, то есть в моем случае для t?
>>1075014 Я не понимаю, что ты пытаешься доказать. kmalloc - это тупой маллок, он не позволяет указать виртуальный адрес, по которому нужно выделить память.
>>1075017 > когда присваивание находится внутри printf. От того, что оно синтаксически там находится, поведение не меняется.
> Правильно ли я понимаю, что раз левый аргумент вычисляется последним, то его значение и напечатается, то есть в моем случае для t? Последним вычисляется присваивание, у = наименьший приоритет. Но = как и все операторы "возвращает" результат, он равен присваиваемому значению, и вот этот результат становится аргументом printf.
>>1075003 > Что является обращением к памяти по адресу 0, что на системе с виртуальной памятью в user mode вряд ли возможно Вот специально для тебя наговнокодил. Требует рута, поэтому не ideone.
>>1075029 > который возращает код а не адрес памяти А я-то думал, что с тобой не так. А ты просто читать не умеешь. У тебя по ссылке черным по белому написано, что MAP_FAILED = (void *) -1. Ну и, конечно же, mmap() возвращает мне адрес, по которому я замапил страницу, а замапил я ее по 0, поэтому он мне возвращает 0. Если запущу не под рутом, вернет MAP_FAILED.
>>1075030 Нет с возвратом я понял, потом. Но ты же не знаешь точно какой адресс, тебе возвращает mmap т.к просто опускаешь возвращаемое им значение. Сомневаюсь, что там будет 0х0, тем более даже если это так, он все равно мапится на виртуальную память, так что смысла в этом не особо много, т.к. нулевой адрес в виртуальной памяти процесса, впринципе возможен, только он будет укзывать то на другой физический.
>>1075040 > Но ты же не знаешь точно какой адресс, тебе возвращает mmap MAP_FIXED же. Я ему явно указываю, что хочу именно NULL.
> так что смысла в этом не особо много > он будет укзывать то на другой физический А вот тут ты прав. Чтобы пройтись по физическим страницам последовательно, нужна другая магия. Называется /dev/mem, ее точно так же можно замапить, но оно не везде доступно, и те регионы, которые через него видно, целиком и полностью зависят от ядра. Но через кернелмод можно и это обойти.
>>1075040 >он все равно мапится на виртуальную память, так что смысла в этом не особо много, т.к. нулевой адрес в виртуальной памяти процесса, впринципе возможен, только он будет укзывать то на другой физический. и к чему это всё? кого ебёт что там в физической памяти. мы живём в мире с единорогами и радугами.
но я читал про это как-то, хотя мне всегда казалось, что NULL может менять своё значение в зависимости от платформы, на деле вроде нет. но опять же, это пространство языка, не будет тебе malloc выделять 0 и ладно.
>>1075047 >/dev/mem Ну во-первых он отключен по умолчанию. Да и потом, не думаю что из protected mode можно что-то записать в такую низкоуровневую память < 1MB. Думаю, что процессор не даст что-то туда записать и сделает прерывание.
>>1075078 > Думаю, что процессор не даст что-то туда записать Процессору абсолютно похуй, какой адрес выставлять на адресную шину. Защищенный режим защищает один процесс от другого, а не компьютер от программ.
Пожалуйста, пользуйтесь https://ideone.com/ или http://pastebin.com/ для вставки кода, если он длиной больше нескольких строк или содержит [i] или ∗.
Что читать:
- Классика от Отцов: http://www.cypress.com/file/56651/download
- Годное пособие для гуманитариев: http://web.archive.org/web/20160727235220/http://c.learncodethehardway.org/book/ (автор внезапно захотел денег)
- Немного примеров хорошего стиля: http://www.oualline.com/books.free/style/index.html
- ООП, например: http://www.cs.rit.edu/%7Eats/books/ooc.pdf
- Стандарт ISO/IEC 9899:1999 (он же C99): http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf (драфт) не драфт ищем на торрентах
- Стандарт ISO/IEC 9899:2011 (он же C11): http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf (драфт)
- man/Dash/zealdocs
Чем конпелировать:
- Очевидный GCC.
- clang: оче годно, батя рекомендует.
- Intel C++ Compiler: оптимизации, тысячи их.
- Visual Studio 2017 Community Edition: внезапно этим стало можно пользоваться, особенно с тулсетом clang/C2. Поддержка C11 на уровне "есть все, что тебе понадобится в реальном проекте плюс кривая библиотека". Анализатор кода в комплекте.
- Pelles C (шиндоуз онли): поучиться, вкатиться в C11 (стандарт полностью реализован, имеются в том числе threads.h и прочие stdatomic.h), но количество багов в оптимизаторе и редкие апдейты напрочь отбивают желание собирать этим что-то сколько-нибудь серьезное.
- TCC: очень маленький компилятор с багами и неполной поддержкой C99. С ключом -run умеет компилировать код в память и запускать его, что позволяет писать скрипты прямо на сишечке.
Что еще почитать:
Stephen Prata "C Primer Plus, 6th Edition" (2014)
Свежая знает про C89, C99, C11, описывает различия, объемная около тысячи страниц, годная хотя есть некоторые шероховатости, с вопросами, упражнениями и ответами. Читать после K&R или до.
http://c-faq.com/
FAQ из comp.lang.c. Древний, но все еще актуален.
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)
MISRA Ltd. "Guidelines for the Use of the C Language in Critical Systems" (2013)
Набор рекомендаций по написанию надежного кода на C (промышленный стандарт). Читать - однозначно, следовать - вдумчиво и без фанатизма. Также можно посмотреть https://www.securecoding.cert.org/confluence/display/c/SEI+CERT+C+Coding+Standard
Еще более длинный список: http://www.iso-9899.info/wiki/Books#Learning_C
Онлайн-утилиты:
- https://godbolt.org/ - Compiler Explorer позволяет посмотреть выхлоп компиляторов для введенного куска кода (больше полусотни разных версий компиляторов).
- http://cdecl.org/ - С Gibberish ↔ English помогает читать сложные сишные декларации.
Прошлые треды:
- №20: https://arhivach.org/thread/254158/
- №21: https://arhivach.org/thread/260316/
- №22: https://arhivach.org/thread/262491/
- №23: https://arhivach.org/thread/277223/
Шапка: http://piratepad.net/bJ1SdmkZyu