Тред, посвященный прародителю всех С-подобных языков и по совместительству единственному идеальному и всесторонне годному средству программирования как на системном, так и на прикладном уровне.
- Очевидный GCC. - clang: оче годно, батя рекомендует. - Intel C++ Compiler: оптимизации, тысячи их. - Visual Studio 2017 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 помогает читать сложные сишные декларации.
Ну, конкретно, в данном случае (JIT или загрузка исполняемого кода в память) именно логично сделать кучу асмовых реализаций int execute_code(pointer) в папке arch, чем писать кросплатформенную лапшу ифдефов в попытках наебать стандарт, вызвать через указатель на функцию, и все равно выстрелить себе в ногу.
>>1187521 (OP) друзья, не могу никак найти нормального гуида, как загрузить bitmap в 2мерный массив, как его потом обрабатывать, используя стандартные библиотеки. Подкиньте чего, позязя
>>1187806 Ну тогда выбери себе какое-нибудь подмножество .tga без сжатия, и читай себе его. Там все просто и не нужно возиться с паддингом, как в .bmp. Читаешь заголовок, считаешь, сколько нужно памяти, выделяешь память, читаешь тело. Все. Разве что с 2D-массивом может выйти промашка, потому что размерности сишных массивов определяются при компиляции (если он не VLA).
>>1188112 Да. Ну, желательно, без сторонних либ (помимо API операционки). Я вообще про общие принципы спрашивал скорее, потому как у меня кроме как функции в функции в функции (переход по менюшкам) ничего не выходит. Мб так и надо, конечно.
Платиновый вопрос: как скомпилировать K&R через GCC? Ну или как вообще обходиться с K&R в современном мире? Мне Прата очень не нравится, тонны текста. Хочу начать с K&R и потом пойти по стандартам.
>>1188867 Вкратце: да, автор пиздит. На пике row-major, в Си нативно тоже row-major, менять местами индексы нинужно.
Короче, в математике опять не смогли между собой договориться, и есть две системы нумерации элементов матриц: row-major и column-major, они определяют, какой индекс указывать первым - строки или столбца соответственно. Проблемы с нотацией приводят к путанице и странным правилам при умножении матриц (хотя если абстрагироваться от индексов, оказывается, что все очень логично, и даже задумываться о порядке умножения незачем). А вот такие авторы статей, не понимая сути, еще добавляют путаницы. Алсо, автор пика пиздит, потому что даже в книжках по математике используются оба варианта, в зависимости от предпочтений их авторов. Но для начала тебе лучше просто забыть всю эту хуйню про строки и столбцы, и считать вместо этого, что матрица - просто вектор, содержащий векторы (просто список векторов, никакой магии). После этого нотация упростится до логичного vector-major: сначала ты указываешь индекс вектора, потом индекс его элемента, а уж как там в книжках эти векторы нарисованы - столбцами, строками или вообще в окружности вписаны, тебя ебать не должно.
К сожалению, элементы матрицы нужно хранить в одномерной компьютерной памяти. Если ты сделаешь struct vector { float x, y, z; }, то компоненты структуры в памяти будут лежать один за другим. Если сделаешь массив векторов struct vector m[4] и заполнишь это данными, то векторы в памяти будут идти один за другим (т.е., m[0].x, m[0].y, m[0].z, m[1].x, m[1].y и т. д.). Чтобы достать оттуда вектор, ты будешь делать m[i], а чтобы обратиться к элементу этого вектора - (m[i]).y допустим. Если ты вместо массива структур сделаешь массив массивов float m[4][3] (4 вектора по 3 элемента), то расположение элементов в памяти не изменится, не изменится и нотация: ты продолжишь сначала обращаться к вектору m[i], а потом к его элементу (m[i])[j], и если на бумажке или в книжке у тебя row-major, то нотация совпадет: m[i][j]. Это естественно и логично. Но осознай, что это лишь вопрос нотации: ты можешь взять column-major из книжки, писать столбцы в векторы и продолжать использовать m[i][j] или наоборот, ты можешь решить, что для каких-то вычислений хранить соответствующие компоненты векторов рядом, т.е., в column-major ({{x0, x1, x2}, {y0, y1, y2}, ...} удобнее и быстрее, и в этом случае нотация для обращения изменится на m[j][i].
>>1188919 Пердачую этого. Хотел объяснить всё то же самое, но он сделал это развернуто и очень понятно, ну и первым. Правда я нихуя не понял из последнего предложения, причем тут column-major, если ты хранишь векторы группируя их по компонентам.
Смотрю исходники GSL (gnu scientific library), возникли вопросы.
1. Там регулярно попадается такая штука: for(i = 0; i < n; ++i) { ....const int a = // значение, зависящее от объявленных выше переменных; ....const int b = // значение, зависящее от объявленных выше переменных ....c = // Функция от a и b. } Пример такого в прикрепленной картиночке. Как Си создает/убивает переменные вне области видимости? Не получается ли, что на каждой итерации цикла тратится время на то, чтобы создать переменную, один раз внести в нее значение, и потом уничтожить (освободить память), итого 2 лишних действия для каждой такой переменной на каждый проход цикла? 2. Почти все вспомогательные переменные const в коде. Не константы в основном только счетчики циклов и переменные, которые считаются в цикле (например, сумма элементов массива). Зачем так делать? Это такой стиль, нужный чтобы люди использовали каждую переменную для одной задачи, или в этом есть польза? Даже переменные переданные по значению в функции const, что совсем странно: int gsl_fit_linear (const double x[], const size_t xstride, const double y[], const size_t ystride, const size_t n, бла-бла) Зачем?
>>1188928 Это тебе не ООП, и переменная здесь - не объект. Оно в "статической" памяти находится, и, единственное что происходит при входе в цикл - инициализация переменных значениями. Если что не так сказал - поправьте.
Вообще C - моя единствення любовь, великий язык. Жаль, что не приносит денег в отличии от мамкиных фронтэндщиков 300к/наносек
>>1188925 > Как Си создает/убивает переменные вне области видимости? Не получается ли, что на каждой итерации цикла тратится время на то, чтобы создать переменную, один раз внести в нее значение, и потом уничтожить (освободить память) Стандарт ничего не гарантирует, но во всех реализациях автоматические переменные лежат на стеке. Плохому компиляторе для создания переменной или целой области видимости нужна целая одна инструкция (кроме инициализации). Хороший компилятор выделяет в стеке достаточно места для любого вложенного блока кода сразу же при входе в функцию (одной инструкцией), а при выходе все разом освобождает (опять же одной инструкцией), да еще и переиспользует переменные: void foo(int arg) { int some_variable = 3; if (arg) { for (size_t i = 0; i < n; i++) { some code; } for (size_t i = 0; i < n; i++) { other code; } } } В этом куске кода на стеке может вообще ничего не выделиться: если sizeof(int) == sizeof(size_t), и у нас 32-битный x86, а arg кроме условия больше нигде не используется, то компилятор может писать i прямо в arg. И даже если нет, то i, скорее всего, все равно будет одна. Поэтому не стоит об этом думать, ты даже с -O0 почти ничего не теряешь.
> Почти все вспомогательные переменные const в коде Да, это такой стиль, чтобы люди видели константы, чтобы писать самодокументирующийся код, чтобы избегать глупых ошибок. Теоретически, оно еще может немного помочь компилятору с constant propagation. Но напоминаю, что с константами в Си нужно быть осторожным, они сломаны и означают "в этом месте я не буду изменять эту хуйню", автоматические переменные с const еще более-менее дружат, а вот глобальные вменяемо оптимизируются только в паре со strict aliasing и restrict.
>>1188932 > Оно в "статической" памяти находится Так можно, но по сути тебе все равно приходится скатываться до стека при рекурсии. Поэтому так не делают.
Правильно ли я понял: можно засрать всю программу переменными в стеке (включая vla?), выделять новую переменную под каждое действие, это (почти) не повлияет на скорость и вес программы?
>>1189042 Нет, не правильно. У стека есть ограничения зависящие от реализации конпелятора и ОС. Можно изменить эти ограничения, но это костыль. маллок-хуяллок наше всё. мимкрок
>>1189042 Ты почти правильно понимаешь. Но выделять большие массивы (сотни килобайт) не стоит, и при рекурсии нужно осторожно подумать, сколько тебе может понадобиться. Как тебе написали выше, стек не резиновый. Но если ты просто даешь имена промежуточным результатам вычислений: int foo = a + b; int bar = foo ∗ 2; return bar; ты ничего никуда не засрешь, потому что с любым уровнем оптимизации, отличным от нулевого, это почти/полностью эквивалентно: return (a + b) ∗ 2; И скорее всего, в стек вообще ничего не попадет, все в регистры влезет. Отладочные билды будут медленнее и жирнее, да. На релиз такое не повлияет.
А VLA зло. Если ты не ограничиваешь размер массива, однажды ты попробуешь выделить слишком много и свалишься. Если ограничиваешь - тебе не нужны VLA, ты можешь сразу написать, что хочешь не array[n], а, допусти, array[8192].
>>1189061 Ты забыл сказать, что чаще всего это ограничения уровня нескольких мегабайт.
Сап, аноны. Подскажите, как реализовать простейший стек на си без плюсов блядь и push/pop/peek для него. В гуле одни плюсы, которые я не знаю, либо какая-то лютая хурма. Так же сложности добавляет то, что авторы статей имеют привычку называть плюсы "си", соответственно найти что-либо рабочее не удалось. Спасибо
Имеется указатель на строку p_str Если написать (p_str++) = 6; То сначала просходит инкремент указателя, а затем его разыменование и присвоение 6? А если написать (++p_str) = 6; То сначала указатель разыменовывается, присваивается 6, а указатель увеличивается на 1?
Или в обоих случаях сначала идет инкремент, а только потом разыменование и присвоение? Тогда я не понимаю, в каких случаях и как именно работает префиксная и постфиксная инкрементация.
>>1189232 Спасибо. Понял. То есть скобки устанавливают приоритет операции таким образом, что сначала всегда p будет увеличен, а только потом разыменован. А без скобок, соответственно, приоритеты меняются в зависимости от того, с какой стороны стоит инкремент.
>>1189232 Сделал разыменование и постинкремент. Вот кусок кода: char ch = '4'; 'звездочка'p_str++ = ch; printf("p_str = %c\n", 'звёздочка'(p - 1)); То есть на экран должен выводиться символ 4. Но получаю какой-то мусор. А если написать printf("p_str = %c\n", 'звёздочка'(p)); То выводится 4. Почему?
>>1189247 Аноны, ну помогите с кодом. На таком фрагменте уже целый час потерял. Если пишу звездочкаp = ch; p++; printf ("%c", звездочка(p-1)); то все работает. В чем ошибка-то?
>>1189289 >>1189247 Бля. Сорян, я сделал хуйню. У меня есть два разных указателя p и p_str, соответственно. Второй просто является строкой-дубликатом. Я сошел с ума и инкрементировал p, вместо p_str. Проблема решена
Блять, походу потребность в OpenGL все таки загонит меня к вам в уютный загончик для бомжей. Порекомендуйте ту единственную интересную книгу, по которой я за месяц смогу вкатится в самые основы чтобы управлять апихой OpenGL позязя.
>>1189442 >OpenGL SuperBible Спасибо конечно... но это копание именно в движке. Именно с OpenGL как концепцией я думаю проблем не будет, у меня есть гайд для своей плотформы, отnуда я понял, что это клиент серверный механизм, в котором на клиенте формируется стек запросов с координатами и пуляется на сервер, который крутится на видеокарте и он всесь стек отрисовывает со скоростью звука и с нетерпением ждёт следующий вагон. У меня gроблема именно с C. Пушто я об нём ничего не знаю. Читал 5 лет назад книжицу в метро, но ничего не понял. Мне сейчас нужна тиресная книжеца по основам основ C )))
В какой области C прям мастхев? Два раза перечитывал (перелистывал) K&R, но работать над проектами уровня перевода фарангейтов в градусы было лень, поэтому и опыта никакого в C нет. Интересует что-нибудь близкое к компьютерной графике
>>1189680 В основном стримы видео, хиудео, там где надо работать с буферами. Например, пишется клиент серверная либа, которая стримит видео и звук, потом она портируется под работу на разных архитектурах. Запускается на мобильных устройствах и на линуксе. На моб устройствах поверх неё пишут на нативных фреймворках гуи, чтобы юзер мог ей пользоваться.
>>1189729 Да там одни олигофрены, джава окончательно устарела уже, это легаси ковыряние, если есть сильное требование к ресурсам то это конец, джава не потянет. Если средней сложноси алгоритм то будет полная загрузка железа, уродливый жирный тулчейн, ИДЕ почти не глючит и так далее
>>1189728 Напиши функцию ssize_t getrandbuf(void ∗buf, unsigned int nmemb, size_t membsize, unsigned short nbits, unsigned int flags) которая принимает массив buf с число элементов nmemb, каждый размеров membsize, и заполняет каждый элемент слева рандомными битами в кол-ве nbits, полученными от функции getrandom с флагами flags. От getrandom надо получать не больше рандомных битов, чем требуется (с точностью до байта). Энтропию, мать твою, надо экономить.
Дрочую. Джава-параша сейчас очень сильно устарела если сравнивать с C# например. Там многое фундаментально перепиливать придется чтоб догнать без костылей. А это гроб-гроб-кладбище.
Сравните STREAM API с LINQ (который через экстеншен методы) и все встанет на свои места
>>1190076 >Джава-параша сейчас очень сильно устарела если сравнивать с C# например. Чем она устарела? Шарпоговно еще большее днище, а на жабе есть дохуя вкусняшек хэдупы, джибосы, томкаты, солры, нутч и прочее.
уже писал тут раньше насчет этой же проблемы, но она не решилась, а сроки горят Всем привет, вопрос про написание простейшего драйвера для винды. Мне по учебе в вузике нужно написать драйвер для Windows, который будете иметь возможность: 1) получать/отправлять значение от консольного приложения в user mode 2) записывать/считывать значение в MSR регистры процессора
Для Линукс написание такого драйвера (модуля ядра) проблем у меня не вызвало. С Windows всё сложнее, не могу разобраться в сэмплах на сайте майкрософта, книги по драйверописанию уже устарели.
Короче, спасите, умираю. Посоветуйте инфы, чтобы разобраться. А ещё лучше, напишите драйвер за меня (у шарящего человека это и 30 минут не займет), а я 1500р перешлю за работу на карту. Или посоветуйте, где за деньги можно попросить такое сделать, потому что на Workzilla и Fl.ru за 1500 рублей никто не нашёлся
>>1190222 > уже писал тут раньше насчет этой же проблемы, но она не решилась Если бы ты вместо походов по биржам просто погуглил, то оказалось бы, что решишь проблему самому быстрее, чем бегать и ныть. Вот тебе твой драйвер: https://github.com/pmolchanov/legacy-driver-helloworld/blob/master/driver/driver.c _readmsr()/_writemsr() вызвать в районе 135 строки осилишь? Клиент с CreateFile/DeviceIoControl осилишь?
> книги по драйверописанию уже устарели Да ты что? Ты там видеодрайвер пишешь, может быть? Или в винде резко поменялся ядерный апи?
https://pastebin.com/SVP47M5n Объясните пожалуйста, в чем разница между 1,2 и 3 вариантом. В 3м варианте ошибка сегментации. Как static и extern связаны с выделением памяти в куче/на стэке?
>>1190442 В первом варианте ты объявляешь статический массив интов, который уже будет в теле образа программы при конпеляции и весь заполнен нулями(инициализирован). Т.е. размер софтины будет конпелированный код+ массив интов. Этот массив будет в области данных(кода софтины?), а не на стеке. Область видимости этого массива будет строго файле исходника. Второй случай отличается только областью видимости, она уже будет глобальной. В третьем случае ты запиливаешь массив во времени выполнения софтины и тупо не хватило места на стеке . Вроде так.
>>1190601 С GDI+ слегка непросто. Это изначально крестовый API, а плоский сишный API, на котором он основан, официально недокументированный (хотя все уже разобрали) и чуть более многословный, чем хотелось бы. С обычным GDI сложностей нет, есть книга www.fengyuan.com, но можно и в MSDN справку смотреть, там все просто.
>>1190634 Это статическая память, а не куча. Это память, которую программа просит у системы и куда проецирует свой код и свои статические переменные. Память из кучи - это когда ты в реальном времени просишь еще памяти всякими malloc'ами и система выдает тебе таковую.
>>1190755 >Это статическая память, а не куча. Это память, которую программа просит у системы и куда проецирует свой код и свои статические переменные. Память из кучи - это когда ты в реальном времени просишь еще памяти всякими malloc'ами и система выдает тебе таковую.
Только не программа просит, а система при загрузке исполняемого файла читает из исполняемого файла секцию и сама выделяет приложению память. И в случае неинициализированной памяти дескрипторы помещаются в секцию bss, где указывается только размер, файл при этом не увеличивается. А вот если было бы int array[] = {1,2,3,4,5....100500}, то да, размер исполняемого файла вырос.
Если я делаю небольшую прогу с интерфейсом консольным, то жестко задавать магические номера координат элементов (окошки, надписи, етц) это нормально или быдлокод? Если последнее, то как фиксить?
Бля, не бейте: не могу сделать прогу, которая переводила бы набор из 128х128 цифр от 0 до 9 из .txt в .png, придавая пикселям цвет в зависимости от значения соответствующей цифры. Вроде, простая хуйня, но никак не успеваю разобраться. Поясните, что там знать нужно? (уровень 1: едва ли работаю со строками)
>>1191364 Png суть тот же бинарник. Для того, чтобы создать этот бинарник тебе нужно передать на вход свой txt, а на выходе получить png. Но это не значит просто сменить формат, потому что png содержит в себе ещё и служебную информацию. То есть тебе надо знать как устроен PNG. А вообще если ты задаешь такие вопросы то для начала не мешало бы хоть какую-нибудь книжку дочитать. Кури на гитхабе png decoder и разбирайся.
>>1191347 Let me google that for you: https://www.lemoda.net/c/write-png/ Там в main() есть цикл вложенный по x и y. Твоя задача записать в цветовые компоненты каждого пиксела нужные значения. Например, так: uint8_t value = цифра - '0'; uint8_t intensity = (uint8_t) (value ∗ 25); // Примерно то же, что value / 10 ∗ 255, но сразу в целых числах. pixel->red = intensity; pixel->green = intensity; pixel->blue = intensity; А уж как читать цифры построчно или посимвольно, игнорируя или нет пробелы - сам.
Этих >>1191360 не слушай, очень долго будешь на текущем уровне ебаться с форматом и zlib-ом.
>>1191347 > .png А тебе обязательно png или просто нужно получить картинку? Можешь посмотреть на формат .ppm, если пока не хочешь ебаться с DEFLATE и прочей ссакой
Имеется односвязный список, из таких структур. typedef struct list { int value; struct list 'звездочка' next; } List; Обычно новый узел добавляется функцией такого вида List 'звездочка' add(List 'звездочка' elem, int val) { List 'звездочка' temp, new; new = (List 'звездочка') malloc (sizeof(List)); temp = elem->next; elem->next=new; new->value = val; new->next=temp; return new; } Можно ли приведенную выше функцию заменить функцией такого вида, если я хочу просто с головы добавить 6 новых узлов? void add(List 'звездочка' elem, int val) { elem->next = ++elem; //старому elem->next присваивается elem+1 или новому elem->next присваивается он сам же? elem->value = val; } int main () { int v = 23; List 'звездочка' head = (List 'звездочка') malloc (sizeof(List)'умножить'7); head->value = v; int addList = 6; while (addList) { scanf ("%d", &v); add(elem, v); addList--; } return 0; } Грубо говоря, мой вопрос сводится к тому, что я закомментировал в функции. Как именно там будет работать присваивание? Да и вообще, в целом, корректно ли это теоретически?
>>1191463 Почему же? Нужно просто нагуглить либку на C которая может сделать пнг. Опять же можно по пути визальнуть на каком нибудь OpenGL то что получается.
>>1191476 > Можно ли приведенную выше функцию заменить функцией такого вида Можно, но при попытке удалить один из узлов, у тебя возникнет множество проблем.
> Как именно там будет работать присваивание? > elem->next = ++elem; Хуево. Есть такие sequence points в языке, и между sequence points порядок возникновения сайд-эффектов не определен. В твоем выражении sequence-point - точка с запятой. И поэтому нельзя ничего сказать о том, когда произойдет инкремент, и какому elem->next присвоится указатель.
Алсо не совсем понятно, что ты делаешь с elem в main (откуда он берется). Ты можешь сделать в main: struct list ∗elem = head + 1; while (...) { elem->value = v; elem[-1].next = elem; // Мы в массиве, так можно. ++elem; } elem[-1].next = NULL;
>>1191531 > Просто пишешь байты в файл, следуя регламенту > Просто реализуешь битстрим > Просто реализуешь хаффмана > Просто реализуешь lz77 > Просто реализуешь дефлейт > Просто реализуешь адлер > Просто оборачиваешь дефлейт в zlib > Просто реализуешь crc32 > Просто работаешь с big-endian > Просто пишешь PNG-чанки в файл > уровень 1: едва ли работаю со строками
>>1191547 >> Просто пишешь PNG-чанки в файл >> уровень 1: едва ли работаю со строками Ну он же думал, что это просто. Вот пусть просто и пишет чанки. Потом просто напишет убийцу фотошопа.
>>1191549 Так это на самом деле просто: просто линкуешься с libpng, там вон выше и пример есть почти готовый.
А вот на код на пистоне, в котором ты одной строчкой, без import zlib или PIL сгенеришь PNG, я бы посмотрел. inb4: fp.write(b"\x89PNG\r\n\x1a\n\0\0\0\rIHDR...")
>>1191549 > Вот пусть просто и пишет чанки Ну да, там особой ебли нет, вот только IDAT сжатый и CRC надо считать, и значения в big-endian.
>>1191547 О, спасибо. Понял. В main'е узел создается очень просто. Структура же глобальная. Поэтому просто выделяю память под узел на куче. А что можно про сайд- эффекты почитать? Там все-таки unexpected behaviour будет?
>>1191574 > Там все-таки unexpected behaviour будет? If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined.
> А что можно про сайд-эффекты почитать? Accessing a volatile object, modifying an object, modifying a file, or calling a function that does any of those operations are all side effects, which are changes in the state of the execution environment.
>>1191301 @ ЗАДОЛБАЛСЯ, КАЧАЕШЬ MSVC BUILD TOOLS @ КОМПИЛЯТОРЫ ВЕСЯТ 4 ГБ, ВЫБОРОЧНОЙ УСТАНОВКИ НЕТ @ cl Main.cpp @ CANNOT INCLUDE FILE WINDOWS.H: NO SUCH FILE OR DIRECTORY
>>1192252 Можно мне, не упарываясь WinAPI, собрать что-нибудь под Винду, не реализовывая самому какой нибудь ссанный интринсик? Я ещё не хочу 40 ГБ IDE качать, я вообще имею право после этого сидеть на Винде?
>>1192390 Набор регистров, используемый для установки точек останова для аппаратной отладки (можно, например, узнать о модификации или чтении памяти). Хранят адреса точек останова, их типы и статус.
>>1192477 >функций Анонимные функции - синтаксический сахар. >>1192477 >нет дженериков Не дженериков, а шаблонов, ты откуда такой вылез? >нет промисов нинужно Рассматриваем Цэ, как удобный кросплатформенный ассамблер
>>1192549 > кроссплатформенный ассемблер >Бессмысленный набор слов. ОКЭ, область применения - сверхэффективный быстрый системный, прикладной софт и числодробительные библиотеки. Т.е. не делаем из С хипстеропарашу, а добавляем комфорта при решении текущих задач.
>> нет промисов >И слава богу. Люмпен от программирования as is. При желании можешь написать сам. Но тут нет асинхронной парадигмы, поэтому нинужно.
>>1192551 >Анонимные функции - синтаксический сахар. Это, прежде всего, освобождение глобального неймспейса от ненужного хлама. >нет промисов Можно сделать с помощью longjmp/setjmp
>>1192565 >кичится знанием базовый вещей Мань, ты задачи бизнеса-то решать сможешь? Тебе ставят большую задачу написать распределенное приложение. Что делать будешь, байтомакака?
>>1192615 Два чаю. Си сейчас меют тендецию к заниманию прослойки между сетевым/графическим хардвером и макакским апи для конечного клиента, еси мы говорим о бизнессе
>>1192751 Я на С 12 лет назад лабы делал в универе. Первая любовь. А JS - стал нужен пару лет назад сугубо из практических, но не корыстных целей (расширения браузера). Трхед незапятнан.
>>1192463 Хмм, с порядком байтов всё понятно, x86-Little-endian. Но вот про порядки битов я дохрена разного нашёл. Кое-где связывают Little-endian с нумерацией с МЗБ, а big-endian связывают с нумерацией с СЗБ.
>>1192775 Железячники с младшего нумеруют. Intel (если уж мы об x86) с младшего нумерует. Разброд и шатания начинаются, когда нужно упаковать/распаковать поток битов в байты или слова, тогда, действительно, бывает и со старшего записано, и даже задом наперед - кому как удобнее.
>>1192867 И вообще даже сама запись двоичного числа - это bitn-1×2n-1 + bitn-2×2n-2 + ... + bit2×22 + bit1×1i + bit0×20, номер бита логически вытекает из соответветствующей ему степени двойки.
Сап аноны, есть одна программа, которая сношает мне мозг, а я сношаю мозг ей. В общем суть такая, делаю имитацию оргазма функции vector на СИ, я хочу что бы пользователь вводил нужну. длину вектора, а он сам выделял под себя место и все такое. Он делает все, но данные загоняются не корректно. Я создал цикл for, самый обычный, classic, там каждый раз генерируется рандомное число, преобразуется в стринг и заносится в массив, но если вручную все это работает (когда сам забиваешь массив в вектор), то через цикл он загоняет туда последнее число цикла, хотя в том же цикле добавлен принтф и все зоебись. Надеюсь вы хоть что то поняли из моего потока сознания. На скрине сначала числа по порядку, преобразованные в стринг, а потом уже числа из вектора. Третяя группа это операции над вектором, там все ок. >int main(void)//Тестирование функций { int noe=0; int k=0; char m[10]; vector v; vector_create(&v);//Создаем вектор printf("Enter number of elements: "); scanf("%i\n", &noe); for(k=0; k<noe; k++){ sprintf(m, "%d", k); printf("%s\n", m); vector_push_back(&v, m); } /vector_push_back(&v, "1");//Добавляем данные в вектор vector_push_back(&v, "2"); vector_push_back(&v, "3"); vector_push_back(&v, "4"); vector_push_back(&v, "5");/
>>1192919 Ну все правильно, ты ведь не выделяешь память под каждый новый элемент, а кладешь каждый раз один и тот же указатель на один и тот же буфер (m), и ты в цикле его затираешь все новыми и новыми данными, в результате твой вектор содержит 6 одинаковых указателей на буфер, в котором осталось последнее записанное туда значение. Напиши себе реализацию strdup, чтобы оно работало, как ты ожидаешь.
В push_back можно обойтись только realloc(), вспомнив, что realloc(NULL, size) - это то же, что malloc(size) - тогда тебе не нужно будет городить две раздельные ветки ради одного и того же.
Можно еще не забыть проверку на ошибки: ругаться, если strdup() вернет NULL. А можно и не делать. При удалении вектора не забудь free() каждому такому элементу сделать. Хотя в твоей лабе можно и обойтись.
>>1187521 (OP) Поясните, как создать графический интерфейс на чистом Си и что для этого лучше всего использовать? Gtk+ плох для нелинукс систем, Qt объектно-ориентированный, а wxWidgets судя по всему вобще не совместим с чистым Си (если всё-таки совместим подкиньте гайдов). Толко не советуйте WinAPI.
>>1193165 Ты просишь готовую либу или как написать свой велосипед? Ты не совсем корректно выразился поэтому непонятно, что тебе посоветовать: пойти нахуй или использовать готовую либу.
Смотря для чего тебе GUI. Так-то навалом библиотек, в том числе кроссплатформенных.
Я даже не знаю, что тебе посоветовать. Qt и gtk+ в общем-то просты. Остальное не имеет дезайнера форм и поэтому придется ебаться в «слепую» с дизайном.
>>1193189 Возможно ли создать GUI на чистом Си с использованием Qt? Я знаю, что это объектно-ориентированный фреймворк, а в Си нет ни классов, ни поддержки ООП. Оно разве будет работать?
сап двочеры, подскажите где скачать чистый unix, хочу искупаться в этом дерьме. Раньше ни разу не использовал ОС с интерфейсом командной строки, а теперь понимаю что пора бы и попробовать. Также подскажите отличается ли принцип установки от установки той же винды или убунту или придется попотеть. Будет ли дистрибутив и как записать на флешку образ ОС.
>>1193404 Ебанашка, ты доски попутал. Гаврюша, пиздуй в /s.
ставь дебиан net install без ДЕ и прочих пряников, будешь в голой сосноле пердолиться. Не так страшно на самом деде, зависит от задач. Что-то даже проще будет делать, чем сидеть в GUI
>>1193252 Пиши либу на Си, а интерфейс на Qt на крестах. Кроссплатформенных UI для Си нет. То, что есть - выглядит отвратительно. Лучше всего использовать Gtk на линуксах и Windows API на винде. Да, пилить два интерфейса. Да, долго и сложно. Зато не будет выглядеть как 99% опенсорса.
>>1193428 Пиздеж и кукареканье. Tcl/tk, gtk, qt — все кроссплатформенное. Есть еще немного маленьких библиотек с тем же функционалом. 2 уже выше приводили.
>>1193436 > Пиздеж и кукареканье Научись посты целиком читать.
> Tcl/tk Тормоза и буэ на любой ОС. И это не считая тикля в комплекте.
> gtk На Linux отлично, зато все то же самое выглядит как говно на Windows.
> Qt Не для Си. Лучше из сортов говна, но: не только GUI, куча ненужных возможностей (CSS, JS и прочие квики), медленно, ненативно, поведение приводится к общему знаменателю для всех реализаций, из-за чего везде выглядит чуждым, лицензия. Не говоря уже о том, что эта либа подталкивает писать не интерфейс на Qt, а целиком софт на Qt, используя их собственные аллокататоры, работу с файлами и сетью.
Алсо, в Windows не поддерживается фирменное движение наискосок для перехода в подменю, из-за чего Qt-шным меню пользоваться просто невозможно. И это никогда не починят, потому что нехуй кастомные меню рисовать, когда есть системные.
> Есть еще немного маленьких библиотек Либо кастомная отрисовка со всеми возможнными недостатками (ограниченно подходит для игр, не подходит для приложений), либо очень ограниченные возможности уровня окна/кнопки/поля ввода.
>>1193442 Qt есть минимал или как-то так. На этом движке пилят lxqt продолжение lxde.
> ограниченно подходит для игр, не подходит для приложений Охуительные истоии уровня /зк. Игры, блядь, пишут на юнити и анрил энжин, а не на gui либах.
>>1193446 > Игры, блядь, пишут на юнити Да ты что, никогда бы не подумал! А интерфейсов в играх нет, и кнопка "Выйти из этой индипараши и удалить ее нахуй" появляется магически?
>>1193459 С юнити почти не знаком, но слово "индиговно" должно было тебе намекнуть, что кроме игр на крупных движках есть еще и поделки, в которых из чужого кода максимум SDL. И вот они используют всякие nuklear, потому что нормальный UI писать долго, а кнопочки нужны. Итт достаточно давно обитаю, больше десяти лет пишу на Си.
С чего начать изучать тему, если я хочу написать свою либу уровня graphics.h или curses, используя WinAPI? Ну или просто маленький фреймворк для менюшек консольных.
>>1193464 Опровергни тогда. Ах да, примером из этого тысячилетия. Чтобы и УИ и все прочее на С без всчких сторонних библиотек. Ну давай, удиви кукаретик ебаный, с 10 годами стажа. Ха ха врунишка.
>>1193476 >начали Тебе только кажется, потом что ты сам недавно набижал. Я вот не заходил в пр и в частности в Си тред года 4, зашел - то же самое - пару продвинутых олдфагов, и куча >помохите лабу сделать >привет слесарюги >лучше уж кресты
>>1193490 > но индустрия давно уже держится на других слонах Так и я этого не отрицаю. Мы с тобой говорили о мелколибах для гуя. Nuklear и последователи востребованы только в таких единичных проектах, ну и еще во всяких редакторах для этих же проектов и прочих визуализациях, т.е., там, где у тебя канвас с графической либой, что-то рисуется, и хотелось бы рядом рисовать еще и кнопочку. Больше оно нахуй никому не нужно, о том и речь была.
>>1193516 Ну, это попутно будет изучено. А вот как вынести все это в dll, например, чтобы оттуда дергать все более высокие самопальные функции? Короче, хочу написать обертку над апи.
>>1193518 > А вот как вынести все это в dll __declspec(dllexport) или в .def-файле экспорты перечисли.
>>1193520 В смысле, ты хочешь, чтобы за тебя написали? Или книжку о том, как написать меню? Пишешь эту инициализацию, городишь свою структуру для меню с колбеками, курсор обрабатываешь, рисуешь, в чем проблема-то? Можешь в FAR посмотреть, как там диалоги сделаны.
Ох бляяяяядь вы только посмомтрите на него. Ну спасибо за разрешение. Чмоня тебе корона не жмёт? Хули ты такой высокомерный? Тебе ебучку что ли всерыть? Попроще я сказал будь, мразота ебаная блядь.
Нормально же спросил к чему это высокомерие хуесос ты четырехглазый.
>>1193539 >>1193540 >>1193541 "Символ новой строки прекращает работу функции fgets, но он считается допустимым символом, и поэтому он копируется в строку string." При вызове fgets(str, sizeof str, stdin) пишу '4' В строке получаю 4\n\0 Если пишу '-4' В строке получаю 4\0 Что за хуйня?
>>1193538 Ты выбрал крайне хуевый тред для таких вопросов. Не нравится fgets - напиши свой. Я тебе больше скажу, просто возьми реализацию и просто чутка подправь.
>>1193559 > у меня система 8-битная Так, это что значит? Размер чара 8 бит? И що? sizeof(char)=|Def|=1, пусть он даже 10 бит. Размер типа считает, да. Но указатель как правило long.
>>1193554 Ну даже так у него все должно быть нормально в случае "4" и "-4" (на ideone например нормально, потому что размер указателя там 8), хотя он и долбоеб. Если только он не конпелирует какой нибудь устаревшей хуетой типа Турбо Си, где инт - 16-битовый (я знаю что есть преподаватели ебанашки которые не признают современных сред)
Сейчас делаю дипломную для шараги, пишу консольную программку на си для своего роутера на openwrt. Мне это дико нравится и вставляет. Но проблема в том, что в этом суровом, жестоком, несправедливом мире байтоебы никому нахуй ненужны. Есть другой вариант. Учить javascript и становиться фулстак макакой, задрачивать ноду. После того как отбатрачу на галере и наберусь опыта, открывать свой наебизнес, или по крайне мере буду сеньор помидором с деньгами в хипстеротусовочке. Но меня дико тошнит от слов html, css, photoshop и все что связано с версткой заставляет мой пукан нагриваться до такой степени что в нем можно заваривать воду для доширака. Блять, что делать? Задрачивать после си кресты?
Как можно выводить динамическое дробное число полностью, без лишних нулей? Если в printf использовать %f, то будут выводиться лишние нули в дробной части. Если использовать %g, то число с большим количеством символов, выводится в %e формате. Так с помощью printf'а это никак не реализовать? Может быть можно как-то принудительно заставить %g всегда отображать число в %f формате? Или единственный вариант - сначала переводить число в строку, а затем печатать его fputs'ом?
>>1193618 Я так понимаю, что у него постоянно меняется число, и ему надо выводить его без лишних нулей >>1193616 Нет, так чтобы компилятор за тебя думал, нельзя. Либо строкой, либо округлять до необходимого количества разрядов
>>1193625 > Писать %.100g - это ведь не решение. Не решение. Но можно добавить символов, и будет норм. Вот тебе крайние случаи из старого треда, посчитай циферки и используй: https://ideone.com/JyE5Qp А так, зависит от задачи. Для показывания человекам округленное значение или %g с достаточной точностью - вполне норм (и пусть оно экспоненту показывает, если не хватило). Для передачи текстом между двумя машинами есть %a.
>>1193611 Значит байтоёбство - всё? Низкоуровневое погромирование больше никому не нужно? А я только вкатываться собирался ну и подумываю о том, что бы в битки начать вкладываться
Вы заебали смотреть на веб-макак. Прыщи/спермятина на ноде что ли уде стали работать? С и кресты там в почёте, микроконтроллеры, всякий настольный софь типа эдоуб, да куча направлений, где «байтоёбство» пригодится.
Не драматизируйте. Сами же не хотите участвовать в разработке каких-нибудь БД, ядер и т.п. Остальное уже отдано на растерзания стервятникам скриптоводчиских языков программирования. Да и там в принципе есть ниша с диез. Без работы уж точно не останитесь.
>>1193731 О рили блядь? Открыл нахуй омерику ебана в рот. Я написал в ироничном контексте про нищу, если уж совсем прижмет, то мложно будет окунуться в этот пиздец, если кресты не осилите.
>>1193791 >За 50 тысяч Примерно. Сильно дохуя платить не будут. > невыездом из России на 10 лет? Такое не очень часто бывает. И не всегда знание гос.тайны влечет невыезд.
Научите меня управлять паматью в С. Полгода назад пришлось написать небольшой сервер SOCKS4 с плюшками. Долго ебался с неблокирующими сокетами и libev пока не понял как сделать. Добавляя новый шаг к протоколу приходилось прогонять прогу с валгриндом для того, чтобы найти утечки. Серьезно, шаг влево, шаг вправо, пропустил один return и получай лопату дерьма в лицо. Как вы, блядь, ебетесь с этим всем?
>>1194945 > Добавляя новый шаг к протоколу приходилось прогонять прогу с валгриндом для того, чтобы найти утечки. Значит хуевая архитектура. Теперь у тебя есть понимание задачи, попробуй спроектировать все с нуля.
> пропустил один return А что, в других языках, если у тебя код с багами, программа все равно магически работает?
>>1194995 А как называется та хуйня, когда есть несколько ядер и часть программы (например, цикл) одновременно считается на каждом из них? Это тоже свойство системы или низкоуровневые языки имеют команды типа "эту ерунду считает процессор номер n"?
>>1194977 > многопоточность удел ОС Не только. Например, до С11 по стандарту весь рантайм был не thread-safe. Всякие errno и прочие strtok были одни на всю программу. Модель памяти не предусматривала никакой синхронизации (нет, volatile - не то). Понятно, что реализации стандарта это все фиксили, но не было никаких гарантий, что на такой-то ОС и с таким-то рантаймом все будет работать.
>>1195001 Ты имеешь в виду (полу)автоматическую параллелизацию вроде OpenMP. Для нее должна быть поддержка в языке (чтобы обрабатывать аннотации и дергать библиотеку), и в Си (в виде расширения, конечно) эта поддержка есть, гугли #pragma omp.
Где почитать, как битки двигать? Такие нубские вопросы типа "А как установить в char val i-ый бит в значение k=0,1?" Ведь одной И или ИЛИ не обойтись. Там много комбинаций из двух действий можно придумать с этими вот ^, &, |, ~. Какая считается лучше?
>>1187521 (OP) Сап, бояре. Очень мало писал на си, в основном на крестах. Но тут внезапно вяли на работу, написание драйверов под сетевые адаптеры на linux/windows, чтобы такого можно почитать, чтобы хоть чуть-чуть что-нибудь понять? в си не углублялся, в крестах чувствую себя более-менее
>>1197058 > Книга есть где-нибудь? Где-нибудь есть. > Или самому поискать? Поищи. А вообще, стоит знать, что существуют примерно два крупных сайта с учебниками, ели там нет, с большой вероятностью нигде нет.
Вот такой чек на byte order: unsigned long endian=1; unsigned char isbigend=(!∗((char ∗)&endian)); Но это не будет работать, если sizeof(unsigned long)=sizeof(char). В C89 есть тип, который гарантированно больше, чем char. ЕМНИП, там везде неравенства нестрогие.
Аноны помогите дураку, начал читать классику в лице K&R, ну и возник затык, почему этот код не делает что должен? По идее должен считать количество символов/строк, но этого не происходит. линукс, компилирую tcc При этом на ideone все компилируется и работает как надо, в чем проблема? В компиляторе? В эмуляторе терминала? Что я делаю не так?
>>1197575 > В C89 есть тип, который гарантированно больше, чем char. Теоретически нет. Но так как ты все равно детектишь байт-ордер, то тебе, вероятно, хочется свопать байты, а если sizeof(char) == sizeof(long), то свопать тебе нечего, и можешь считать endianess любым. А если у тебя все же настоящие восьмибитные байты, то завези себе stdint из C99, хотя бы частично. Работы по портированию на новую архитектуру - пара минут, удобство зашкаливает.
>>1197576 > но этого не происходит. А что происходит? А Ctrl+D в конце ввода ты тыкаешь, чтобы сказать терминалу, что завершил ввод и получить EOF в программе? Алсо можешь делать ./govnokod < filename (собственно, ideone нечто подобное и делает).
Помогите студенту Есть ASP.NET и DataGrid c данными из SQL 1)Как изменить вывод данных, то есть вместо N выводится N/5 или N+5. 2)Как добавить колонку, созданную из значений двух колонок, например Column1 = Column 1 + Column2 3)Как привязать графики к значениям колонки?
В общем треде проигнорили, поэтому соре, дублирую здесь.
Уважаемые опытные программистеры, помогите выбрать. Хочу заниматься разработкой (gamedev в идеале), но все мы прекрасно знаем, что без опыта нахуй кому нужен. Есть возможность поработать скриптизером на C (нагрузочное тестирование), стоит ли тратить время на получение хоть какого то официального опыта или продолжать попытки самообразования в надежде найти работу потом?
>>1198965 Тащемто даже компилятор не нужен, достаточно написать транслятор в си, а уж сишечку чем угодно компилировать. Ранние кресты так и делали. но да, написать что то отличное от говна надо неибацца скил иметь, а то выйдет по типу котлина
>>1199054 Ну я чисто пример привёл, все таки писать компилятор будет сложнее, даже сейчас есть пара неплохиххоть и хипстерских языков транслируемых сначала в си.
>>1199060 > Ну я чисто пример привёл А я просто почему-то вспомнил. Вроде ко второму изданию они компилятор уже пофиксили. И нет, я с тобой не согласен. Для кодогенерации есть LLVM, а лексер/парсер все равно писать так или иначе.
>>1199573 > в .txt парсер Лолшто? Что ты там парсить собрался?
> стоит ли мне strtok() юзать Ну strtok умеет делать токены только по разделителям. Если у тебя нет четких разделителей, то очевидно свой, а если есть, то все равно свой, но внутри strtok() можно заюзать.
>>1199582 >Если у тебя нет четких разделителей В смысле чётких? Я могу слова в качестве шаблонов для разделения задавать? >Что там парсить Ну, велосепидирую тут частотный словарь. Интересно получится или нет. Но чтобы в начале не обосраться решил погуглить, а не набивать шишки. Ну, в примерах нет слов в качестве разделителей.
>>1199593 > Я могу слова в качестве шаблонов для разделения задавать? Нет, только список символов, любой из них будет разделителем. Ты можешь по пробелам разбить на слова strtok()-ом, а дальше велосипедить.
Привет ананасы. Объясните как можно подробнее про библиотечные файлы в языке си мне(изучающему язык). Расскажите про то где на самом деле находится определение функций(таких как принтф сканф или геткэр путкэр и тд), что еще помимо прототипов находится в библиотечных файлах (таких как stdio.h, stdlib.h) и зачем оно там. Почему в 1 издании книги брайана кернигана и денниса ритчи в примерах с кодом не подключались заголовочные файлы(пример на картинке) и почему в ос убунту мне приходится прибегать к танцам с бубном при подключении библиотечного файла math.h и вызове функции (sqrt() например), прога не компилится и приходится прописывать дополнительные команды вроде -lm(зачем она вообще нужна я хз). В общем вопросов много, выручайте, очень интересно
>>1199902 > Почему в 1 издании книги > не подключались заголовочные файлы(пример на картинке) Потому что старое говно. Во-первых, был (только в С11 окончательно убили) неявный int - если для функции не указан или не известен тип возвращаемого значения, считается, что она возвращает int (как main() у тебя на пике), если для переменной не указан тип (static foo = 1), то она опять же считается интом. Дальше для аргументов: если скобки в декларации пустые (как в main() на пике), считается, что функция может принимать любое количество любых аргументов (которые подлежат default argument promotions >>1187393, пока не смыло). Поэтому в отсутствие всяких деклараций твой printf на пике означает "функция, которая возвращает int и принимает любые аргументы". Проверка типов не производится, поэтому если облажаешься, компилятор тебе об этом не скажет.
> Расскажите про то где на самом деле находится определение функций Определения (точнее, уже скомпилированные в машинный код реализации) лежат в объектных файлах, лежащих внутри библиотечных файлов (которые на самом деле просто архивы с индексом), объявления в заголовчных файлах.
> зачем оно там Чтобы не писать объявления вручную каждый раз.
> почему в ос убунту мне приходится прибегать к танцам с бубном при подключении библиотечного файла math.h Потому что в math.h написано лишь "сап, гцц, есть где-то в природе такие функции, которые называются так-то, берут такие-то аргументы и возвращают значения такого-то типа". А откуда реализацию брать - не написано, это вне компетенции компилятора, это ты должен сказать линкеру.
> приходится прописывать дополнительные команды вроде -lm(зачем она вообще нужна я хз) Обычно существует какой-то вариант libc - библиотеки, в которой содержится реализация стандартных сишных функций. Существует механизм, который позволяет передать из компилятора в линкер директиву "при линковке этого объектного файла самостоятельно подключи эту библиотеку". И при компиляции сишных файлов с помощью этого механизма подключается libc без каких-то дополнительных телодвижений с твоей стороны. По идее, в libc должна лежать и математика тоже, но по техническим причинам (в том числе из-за разнообразия реализаций математических функций в зависимости от платформы) в Linux она лежит отдельно, и компилятор не подключает ее неявно, и поэтому тебе приходится говорить линкеру, чтобы он подключил библиотеку (-l), которая называется libm.a (-lm).
>>1200083 чел, ты охуенный, но я, например, тоже все это знаю просто не пиши и не отвечай ньюфагам irl надо будет, сами будут грызть книги и копать вглубь а так ты им за 5 минут объяснишь то, на что потратил недели лютого задротства, сидения под отладчиком и чтения манов это то же самое что и продавать бананы по 5 рублей, когда они стоят 45
>>1200102 Нет, long - это синоним long int, unsigned - синоним unsigned int, это просто сокращенные формы записи. А неявный int используется, когда ты по каким-то причинам вообще не указал тип, как тут тип bar и типы возвращаемых значений у printf, foo и main, например: foo(bar) { printf("%d\n", bar); } main() { foo(1); }
>>1200663 > В какую сторону копать, чтобы кодить многопоточные программы на C?
1) структуры данных (для многопоточности тебе обязательно понадобятся очереди) 2) примитивы синхронизации 3) непосредственно само api дл создания потоков. 4) сосание хуйцов с классическими многпотокопроблемами и размышления "как же я докатился до жизни такой" 5) переосмысление сути работы с данными в многопоточных приложениях, появление понятий о Thread Pool (делать потоков больше чем ядер процессора - бессмысленно), понятий о джоба=х и командах (оппа, если мы разобьем все системы нашей софтины на мелкие задачки, которые будем скармиливать пулу потоков, то мы и от многих проблем избавимся и получим турбо-производительность, правда чтобы оба сразу думать над архитектурой придется дольше) 6) Придти к понятию акторов как вершине пройденых пунктов.
Я мамкин оптимизатор, и всегда, когда можно сэкономить пару байт, пару инструкций, я это делаю. В последнее время я всё больше задумываюсь над целесообразностью этого. Например, вместо enum я сую варианты в define, а саму ячейку делаю char, правильно ли это, или я слишком сильно оптимизируют и можно всё в инт сувать и ок?
>>1200950 > вместо enum я сую варианты в define Все так делают. Typed enum из крестов нам не завезли, а иначе какие-нибудь битовые флаги не создашь, будет ругань, что в int не влазит.
> саму ячейку делаю char Выигрываешь по памяти (возможно), проигрываешь по инструкциям, потому что для манипуляций потребуются всякие лишние movzx/movsx.
> или я слишком сильно оптимизируют С возврастом это проходит.
>>1200737 Если ты говоришь про плагины IDE (среды разработки, в которой ты пишешь код, нажимаешь Run и т.д.) - пользуйся, почему бы нет? Но НЕ для контроля версий. Для этого в твоей среде должна быть всего одна кнопка, аналог Run Command Prompt в Visual Studio, ты должен нажимать ее и делать git add -A git commit git push и всю эту херню.
А если ты про расширения компилятора, то вот почему: твой код портируют с одной популярной системы на другую, а там внезапно нет твоего компилятора или есть, но хуевый, и тогда твой код летит в пизду.
>>1201137 Обращается к arr2[count], увеличивает count на 1, обращается к arr1[arr2[count]], <- здесь значение то, что было в начале, то есть обращение к arr2 не происходит снова грубо говоря.
>>1201001 >А если ты про расширения компилятора, то вот почему: твой код портируют с одной популярной системы на другую, а там внезапно нет твоего компилятора или есть, но хуевый, и тогда твой код летит в пизду. Двачую, испытываю анальные боли из за того что в коде используют расширения от gcc, потом хуй клангом скомпилируешь
>>1201559 Во-первых, почему ты спрашиваешь про питон здесь? Во-вторых, раз уж ты спрашиваешь здесь, то да, есть, можешь взять любую IDE, зайти в отладчик, зажать F7 или F11 и смотреть на что-то похожее.
>>1200950 > Я мамкин оптимизатор, и всегда, когда можно сэкономить пару байт, пару инструкций, я это делаю. В последнее время я всё больше задумываюсь над целесообразностью этого. Например, вместо enum я сую варианты в define, а саму ячейку делаю char, правильно ли это, или я слишком сильно оптимизируют и можно всё в инт сувать и ок?
В современных дохуяскалярных дохуяугадывающих процессорах экономить на спичках бессмысленно. И байтоебская оптимизация, если до неё дошло, состоит в двух вещах.
1) По максимуму загрузить АЛУ независимыми арифметическими командами. То есть конкретная такая лапша, разворачивание циклов, одна команда SSE/AVX, следом арифметические команды вообще из другой оперы, вот это вот всё.
2)Ликвидировать промахи кеша. Самая главная проблема современного кода не в коде, а в доступе к данным, при котором в кеше данных не оказывается и процессор превращается в тыкву. Избавляемся превращением множества жирных структур в одну структуру, каждое поле которой - массив.
Короче простым избавлением от жирных структур (жирная - это когда размер больше кеш-линии) и превращения многомерно-иерархических структур данных в линейные достигается самая охуенная производительность. В ассемблер сегодня есть смысл лезть разве что для явной SIMD-арифметики, если таковая тебе нужна.
оптимизаторы сверху, вот типа создаешь структуру, в зависимости от разрядности между полями будут пробелы какие-то, тобиш условно структура будет весть не n байт, а n*x байт. Что мешает выравнивать структуры шоб меньше памяти занимали?
>>1200950 Смысла выбирать более узкие типы с переходом на 64 бита нет никакого. Добьёшься своим char-ом только того, что у тебя в регистре будет 56 лишних, неиспользованных бит и всё. Работа со старшими битами регистров не трогая младшие в машинных кодах достаточно сложна, и компиляторы обычно не заморачиваются. По памяти тоже не выиграешь - выравниваются переменные все равно минимум по границе машинного слова - тех же 64 бит. Убавишь выравнивание - будет алиасинг, когда у тебя несколько переменных в одном слове памяти и обращение к одной тормозит обращение к другим.
Самая лучшая оптимизация, которую стоит применять по ходу дела - недопущение неоправданной вычислительной сложности, например, выделения памяти или склеивания строк в цикле.
В остальном просто расслабься и пиши понятный код.
>>1201627 > Избавляемся превращением множества жирных структур в одну структуру, каждое поле которой - массив Ты и сюда это принес? Это сильно, очень сильно зависит от данных и характера их обработки. Но в общем случае, если структуры не слишком большие, элементы-структуры в массиве лучше, чем структура параллельных массивов.
>>1201684 Там указатели макаба скушала. А какая тут опасность-то? И есть толк все переменные выделять динамически, чтобы удалять их по мере использования?
>>1201687 > А какая тут опасность-то? malloc() вернет NULL, ты упадешь.
Ты все тот же мамкин оптимизатор? Ты знаешь, что такое куча? Ты правда веришь, что если ты сделаешь free(), то программа будет занимать меньше памяти? В чем смысл "удаления" переменных, если указатель все равно останется, пока ты не выйдешь из его области видимости? А еще ты можешь забыть free() и протечь памятью. Зачем все это?
>>1201689 Вернулся мамкин оптимизатор Разве malloc возвращает NULL не тогда, когда новую память выделить не реально, и вероятность того, что у юзера не будет новой памяти на столько мала, что можно и не проверять?
>>1201732 >вероятность того, что у юзера не будет новой памяти на столько мала, что можно и не проверять? Ну если у того анона сверху тип - не структура на несколько мегабайт - вероятность мала. Но в целом, и память, и своп вполне могут кончиться, если что-то ее выжрет и/или протечет.
>>1201732 Вообще — нет. Пример линукс: https://linux.die.net/man/3/malloc > By default, Linux follows an optimistic memory allocation strategy. This means that when malloc() returns non-NULL there is no guarantee that the memory really is available. In case it turns out that the system is out of memory, one or more processes will be killed by the OOM killer.
Проверять всё равно нужно, потому что NULL может прилететь, даже если в ОС ещё не кончилась память, например если память фрагментирована, а тебе нужен большой кусок.
Использование NULL'а не обязательно приведёт к немедленному падению проги, а так же ведёт к дырам в ней.
Хелло. Есть несколько регистров, мне нужно выбирать их в зависимости от порта. Хотел бы сделать макро, чтобы работал так: макро(идентификатор нужного регистра) |= пин; идентично строчке нужное_имя_регистра |= пин;
Насколько реально такое сделать и, если это реально, то как?
>>1201894 Но ты спастил отрывок со случаем, когда malloc() возвращает non-NULL но памяти нет, т.е. противоположный случай. Но это не отменяет того, что то, что ты сказал - верно
>>1202010 Пример написал бы, как оно должно выглядеть. Возможно, ты хочешь приклеивать к имени порта аргумент: #define PORTA_REG1 0x10002000 #define PORTA(reg) PORTA_##reg
>>1202130 Дело не в том, что все работает. Дело больше в том, что проблемы в Си часто связаны с undefined behavior, а обнаружить многие такие случаи тестами сложно, поведение может поменяться на противоположное на другой машине со слегка отличающейся версией компилятора. Поэтому на Си популярный ныне подход "напишем говно, покроем тестами и будем править баги" получается себе дороже, лучше сразу нормально писать.
>>1202154 Windows API вполне вменяемый API. Ненормально там обилие ненужных дублирующихся типов, тонны легаси и неконсистентное поведение некоторых функций (типа NULL vs. INVALID_HANDLE_VALUE), но в целом оно вполне юзабельное.
двач у меня горит lde под линукс codeblocks отказано в доступе при коомпиляции еклипс в жопу эклипс cilon тормозит пиздец и тоже сука нихуя не коомпилирует неужели придется как ввинде делать все в ручную через консоль я понимаю что линукс это консоль
>>1202991 Да. Но если ты какой-нибудь сервис, который может упасть относительно безболезненно, ты можешь сделать обертку для malloc() с if (!ptr) exit(1) внутри, а снаружи не задумываться. Так, например, происходит в крестах, где operator new бросает исключение, которое очень редко кто-либо пытается ловить.
Если новая функциональность приводит к ошибкам, тесты, если они, конечно, есть, сразу же это покажут. При работе с кодом, на который нет тестов, ошибку можно обнаружить спустя значительное время, когда с кодом работать будет намного сложнее. Хорошо протестированный код легко переносит рефакторинг. Уверенность в том, что изменения не нарушат существующую функциональность, придает уверенность разработчикам и увеличивает эффективность их работы.
>>1202996 Если память нельзя выделить, то вернутся NULL, и когда я к нему обращусь - получу segfault и аварийный выход. Segfault на столько нежелателен, что лучше добавить if ()?
>>1203138 да я там иронизировал, просто бесит что многие опенсорсные решения вообще нахуй без тестов, тупо на хомячках ошибки вылавливают, на юзерах по сути конечно тесты и сишникам нужны тупо регрессию проверять (что ты и расписал) другое дело что все же статически типизированный язык и процесс компиляции есть, плюс утилиты стат и дин анализа есть, это очень помогает, сокращает собственно объем тестов ну, да, тоже в роли капитана очевидность выступил, да ладно хорошо, например, организованы тесты в sqllite, если кто не знает, как организовать у себя покрытие тестами чистого сишного кода, может туда глянуть
>>1203324 > и когда я к нему обращусь - получу segfault и аварийный выход При обращении к нулевому указателю возникает undefined behavior. Undefined - значит может произойти все что угодно, не обязательно сегфолт. Даже если ты понимаешь, как реализована стандартная либа и как ОС выделяет память, предположения об undefined behavior нужно делать крайне осторожно или лучше не делать никаких предположений вообще. Особенно если ты считаешь, что лучше всех все знаешь. Вот тебе крайне надуманный пример с кучей "если", который, тем не менее, отлично иллюстрирует сабж: https://ideone.com/QepQ2j
>>1203495 А можешь объяснить, что происходит в функции? В чем суть битового сдвига и как вообще мы аллоцируя память в куче изменили статическую переменную, которая вообще в регионе данных должна быть?
>>1203548 > А можешь объяснить, что происходит в функции? Переделал на массив байтов, чтобы было понятнее. Обращение к элементу массива ptr[index] - это синтаксический сахар для ∗(ptr + index) (используется арифметика указателей, но теперь, с байтами, это просто сложение), а учитывая что ptr == NULL, т.е., 0, то происходит ∗(0 + index), т.е., просто ∗index, т.е., так как начало "массива" у нас по адресу 0, мы просто пишем по адресу is_admin и перезаписываем его.
> В чем суть битового сдвига Бессмысленное деление на два, ни на что уже не влияет (все равно NULL прилетит), убрал. Но вообще, есть аллокаторы, которые по техническим причинам не могут выделить больше, чем SSIZE_MAX (знаковый), а это как раз половина SIZE_MAX.
сап ананасы. Если скомпилированный код на языке си преобразуется в инструкции на машинном языке то почему я могу запускать .exe файлы на одной и той же ос но с разным железом? ведь вроде как инструкции у каждого процессора разные?
>>1203973 >разным железом Под разным железом имеется ввиду очень разное железо. Например, разные архитектуры процессоров в целом или разные поколения одной и той же архитектуры, если приложение использует какие-то инструкции под конкретное семейство (вот у меня так сейчас).
>>1203973 >сап ананасы. Если скомпилированный код на языке си преобразуется в инструкции на машинном языке то почему я могу запускать .exe файлы на одной и той же ос но с разным железом?
Потому что они компилируются по-дефолту, если флаги не указывать для 386 - 32х битные и для Athlon 64 (максимум SSE2) - 64 битные. Добавь -mavx2 -O3 и попробуй какой нибудь числодробительный код написать вроде умножения матриц, а потом запусти на процессоре, который все это дело не поддерживает - получишь ошибку времени выполнения.
По заданию надо реализовать две "базы данных" и ГУИ (консольный) для манипулирования ими. Сами "базы" в принципе есть, как двусвязные списки. Саму консольную гуишку навасянить тоже не проблема. Но вот вопрос - а как между ними данные-то гонять? Вот, например, получить из одной "базы" некие данные и в нужном месте вывести. Мне их функцией вытаскивать из списка в виде строки? Или сразу структурой, чтобы удобно выводить, редактировать и обратно упихивать?
>>1204162 Писал довольно долго на плюсах на уровне "немного лучше залётного ньюфага", потом по работе понадобилось писать на чистой сишке — тогда-то я и понял, что ооп нахуй не нужно само по себе как стандарт, а только в тех случаях, которые этого требуют. И когда пишу на сишке , то прям очень открыто и чисто понимаю, почему в плюсах те или иные вещи сделаны/переделны/добавлены.
>>1197576 дядь про скобки не забывай фигурные. все что должно выполняться в цикле обязательно должно быть в фигурных скобках. да это си а хули ты хотел, чтоб компилер по табуляции тебе определил что входит в тело а что нет? программа подсчета символов содержит ошибку после скобки в for не нужна точка с запятой. Если не шаришь в точках следования то лучше читай прату для начала.ВДУМЧИВО
>>1204688 > все что должно выполняться в цикле обязательно должно быть в фигурных скобках Если в теле одна строка, как в примерах дяди, то скобки не нужны для тела условия и тела цикла. Всё у него правильно.
>>1204816 Особенно когда там вокруг пачка #ifdef, затем после условия скобкок нет, но есть else, после которого блок уже в скобках. Получается полный пиздец, по три раза перечитываешь.
>>1205869 > никому дела нет в этом языке вообще никогда Есть sizeof. В scanf() можно указать максимальный размер буфера: %4s запишет в буфер не более четырёх символов (плюс пятый \0).
>>1205784 у тебя массив из 5 симовлов, ты гарантировал системе, что эти 5 байт - твои и ничьи. Потом ты указал scanf, что можешь принять строку произвольной длины, а можешь только 5 символов, но вот в чём проблема: каждая строка на конце должна иметь \0, т.е. ты сканируешь не 5 символов, а 6, из-за чего последний шестой начинает храниться в следующем байте, который как-бы не твой. Чтобы такого говна не было, нужно написать %4s где 4 - длина массива - 1
>>1206126 > 2ch, правильно ли я понимаю что если процессор 3ghz, то он может выполнить 3 миллиарда ассемблерных инструкций в секунду?
Нет, неправильно понимаешь.
1) Если говорить про современные процессоры x86 - то в них машинный код уже не машинный - он такой же байткод как и сишарпный или жабовский - в потрохах процессора он в зависимости от типа инструкции и комбинации с другими инструкциями преобразуется в различиные последовательности микропераций, которые уже выполняются на потрохах. Этих потрохов несколько и может несколько инструкций выполниться за один такт, может и что одна инструкция займет пару тысяч тактов (если мы в кеше проебались и гриузим данные из оперативы).
2) Вытекающее из первого - современные процессоры дохуя суперскалярны (могут выполнять несколько инструкций одновременно, если хватает ALU-блоков и если они друг-от друга не зависят) и могут выполнять инструкции не в той последовательности в которой они скомпилированы.
3) Оператива (а не код) является главным тормозом современных процессоров - если процессор не находит данные в своих кешах и обращается к оперативке, то он превращается в убертыкву в этот момент и его мегагерцы в этот момент можно смело делить на 100. И именно поэтому интел победил своих конкурентов - за счет внедрения сложных предсказателей загрузки данных/ветвления/индексации в железо.
>>1206154 > сложных предсказателей загрузки данных/ветвления И породив 1000 и 1 дыру в своих ЦП. И кого он подебил именно? Ты имеешь в виду, что x86-64 подебила конкуретнов?
>>1206161 >Вот армы могут, да, но пока им силенок в мире блоатварного говнокода не хватает.
Вот кстати главный грех интела - он приучил людей, что можно писать блоатварный говнокод на языках высокого уровня и не париться - волшебный "приборчик" порешает.
>>1206175 >Там программатор выглядел бы как механический орган, а программа бы была бы типа перфокарт вставляемых в него.
Ты имеешь в виду терминал? Ну как у эвм на дискретных элементах он бы был. Пневмонику как бы достаточно компактную можно сделать - размером с pdp11 за вычетом компрессора. с ячейками раземром 5х5мм.
>>1206177 >размером с pdp11 за вычетом компрессора. с ячейками раземром 5х5мм. Клево и еще механический дисплей, как раньше в аэропортах табло расписаний было.
>>1206176 >Это обычные цифровые устройства. Сами эти девайсы можно на том же верилоге писать спокойно. Ну у тебя часть на пневмо, а часть электронная, а я имею ввиду полностью все без электроники, механика и пневматика.
>>1206181 >Ну у тебя часть на пневмо, а часть электронная, а я имею ввиду полностью все без электроники, механика и пневматика.
Тоже можно, только придется больше с кульманом заморачиваться при проектировании железа.
А так - все так же как и в эвмах допекарной эпохи - тумблерами/галетой (пикрил) пишем первый компилятор ассемблера, на ассемблере уже с помощью печатающего терминала пишем на ассемблере макроассемблер, на нем пишем все остальные языки высокого уровня. Никаких принципиальных/технических отличий от древних каменных эвм, кроме производительности, обусловленной механическими свойствами рабочего тела не будет.
>>1206373 Хз, OpenMP-зазывалы его позиционируют как кроссплатформенный. Синтаксис, конечно, уродский. Трясет просто от этих прагм. Зато переносимо, причём в некоторых случаях собрать можно будет даже на компиляторе без поддержки OMP, ибо прагмы проигнорируются (это если сама структура программы позволит, конечно)
>>1206373 > threads.h в glibc не завезли Есть 3rd-party обертки вокруг pthreads. Используй их, а когда в гцц, наконец, реализуют стандарт полностью - выкинешь.
Посоны, в сишечке есть дефолтный пакет для разреженных матриц? "Дефолтный" в смысле как лапак для обычных. То есть любой человек, занимающийся матричными вычислениями, почти наверняка будет использовать его и блас.
Пожалуйста, пользуйтесь https://ideone.com/ или http://pastebin.com/ для вставки кода, если он длиной больше нескольких строк или содержит [i] или ∗.
Что читать:
- Классика от Отцов: http://www.cypress.com/file/56651/download
- Stephen Prata "C Primer Plus, 6th Edition" (2014): относительно свежая, знает про C89/C99/C11, описывает различия, объемная (около тысячи страниц), годная, с вопросами, упражнениями и ответами. Читать после K&R или до.
- Zed A. Shaw "Learn C the Hard Way" (2015): годное пособие для гуманитариев для гуманитариев!
- Немного примеров хорошего стиля: http://www.oualline.com/books.free/style/index.html
- ООП, например: http://www.cs.rit.edu/~ats/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 умеет компилировать код в память и запускать его, что позволяет писать скрипты прямо на сишечке.
Что еще почитать:
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 помогает читать сложные сишные декларации.
Прошлые треды:
- №27: https://arhivach.cf/thread/325831/
- №28: https://arhivach.cf/thread/339326/
- №29: https://arhivach.cf/thread/347271/
Шапка: http://piratepad.net/bJ1SdmkZyu (иногда лежит)