Это копия, сохраненная 21 октября 2019 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
Пожалуйста, пользуйтесь https://ideone.com/ или https://pastebin.com/ для вставки кода, если он длиной больше нескольких строк или содержит [i] или ∗.
Что читать:
- Brian Kernighan, Dennis Ritchie "The C Programming Language": 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://web.archive.org/web/20190213011655/homepages.inf.ed.ac.uk/dts/pm/Papers/nasa-c-style.pdf
Еще более длинный список: http://www.iso-9899.info/wiki/Books#Learning_C
Онлайн-утилиты:
- https://godbolt.org/ - Compiler Explorer позволяет посмотреть выхлоп компиляторов для введенного куска кода (больше полусотни разных версий компиляторов).
- http://cdecl.org/ - С Gibberish ↔ English помогает читать сложные сишные декларации.
Прошлые треды:
- №44: https://arhivach.ng/thread/444396/
- №45: https://arhivach.ng/thread/448906/
- №46: https://arhivach.ng/thread/461169/ >>1415970 (OP)
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2385.pdf
Не, там зацикливание бесконечное. Прога первые данные переварила и ожидает из пайпа еще данные, а их нет. Но правильную работу можно наверное реализовать, только я не знаю пока как.
Спасибо.
Конечно нет
Не ипу как автоматически сделать. Сделал пока так: если прогу вызвать с аргументом, то одно выражение читается, а если без аргументов то зацикливается.
То есть если вызвать так:
echo 2+2 | math -pipe
То будет работать нормально вроде бы.
Разбирайся. Не ленись. Убери этот сраный банер.
Я б на твоём месте не стал бы ключ писать, а проверял аргументы на вход. Если аргументов нет, то запускаешь интерактивный вариант, иначе пайп.
Ну вы поняли. Звездочка должна быть у типа или у переменной или между ними через пробелы?
Почему? Тогда наглядный смысл теряется. Звездочка у переменной это же содержимое указателя в этой переменной. Получается мы не объявляем указатель такого-то типа, а объявляем тип содержимого указателя. А если бы звездочка была у типа, то сразу понятно что мы объявили указатель такого-то типа.
Ух ты, bc автоматически определяет пайп. Сейчас буду смотреть его исходный код, как он это делает.
А че спрашивал? Пиши int∗ a, b; и наслаждайся тем, что b "сломался". Логика объявлений на Си не такая, что при типе вся непрямая херня задается. Поясню не примерах.
int (∗a)[12];
означает, что если разыменовать a, потом индекисроваться в пределах 0..11, то получится int (скобки для приоритета). То есть a - это указатель на начало массива 12-элементных подмассивов указателей на int. a[3][7];
первый индекс возвращает указатель на начало четвертого подмассива (по сути &a[0][36]), а второй индекс уже выбирает восьмой элемент в подмассиве (a[0][43]). Таким образом, можно автоматизировать составную арифметику указателей, чтоб не писать a[n∗i+j] внутри функции, принимающей многомерный массив.
Следуя твоей логике, эта штука должна работать вот так
int[12]∗ a;
но нет, лол.
Ну, и еще пример напоследок
int (∗f[10])(void ∗);
означает, что если индексироваться по f в пределах 0..9, затем разыменовать, то получим функцию, которая принимает void ∗, возвращает int. Иными словами, массив указателей на такие функции.
Если начинаешь мыслить от имени, воспринимая тип слева, как конечный результат операций над именем, то все становится просто. Я раньше сам ломал голову над всякими указателями на функции.
Да, это кажется немного странным, ведь логично разнести по-отдельности объявления int и указатели на какие-то там конструкции из int, чтоб воспринималось "тааак, тут у нас все int, тут у нас укзаатели..", но даже в других языках есть такая логика, в тех же объявлениях функций. Нигде ведь не пишут
rettype(type1 arg1, type1 arg2) funcname { ... };
Нет, мы тоже объявления будто просто переменную типа rettype, лишь при имени описываем, какое место в дороге к конечному значению занимает это имя. Можно до абсурда довести:
double=12.5 val1, val2;
double=-4 val3;
Вместо double val1 = 12.5, val2 = 12.5, val3 = -4;
Кривая это дорожка, короче. Логика от имени рулит.
>указатель на начало массива 12-элементных подмассивов указателей на int
вот тут я обосрался слегонца, 12-элеметных подмассивов ПРОСТО int
фикс
Не парься, я хуёво объясняю, просто)
Как получить список всех файлов в папке, желательно рекурсивно?
Как удалить папку со всем содержимым?
Это все нужно проделать в шинде.
https://github.com/PolazhinetsA/algo/tree/master/arx
От ОС зависит, на Linux можешь взять opendir и readdir
>пытаются прошу с посикс либой и посикс шелом компильнуть на шине
Блять, с кем я сижу в одном треде...
Ну, можно упростить, чтоб исходные пути не запоминались. Там функция fopen_mkdir автоматически создает недостающие папки для нового файла. На винде другой API файловой системы и бекслеши везде, через #ifdef кроссплатформность можно замутить, если бы шарил, как это non-UNIX-like системах делается.
Есть ли простой пример как мониторить сокет через kevent?
Дергай WinAPI.
https://github.com/PolazhinetsA/algo/tree/master/lzwarc
Молодец. А теперь собери с -Wall, чтобы тебе рассказали, какой ты мудак. Что возвращает bopen()? Бонус: почему у тебя работало и так?
>bopen()
Ох нихуя проеб!
Та по ходу потому что this попадает в rax. Собсно, это скорее ответ на вопрос, почему не работало с -O3.
>-Wall
unsigned вместо int, char ∗ вместо void ∗ в объявлении функций сделал, чтоб не кастовать внутри. Ну и const кое-где не проебал. Мудак, согласен)
Меня больше занимает, почему, несмотря на побайтовую логику bput/bget, после цикла кодирования-раскодирования в конце насрано какими-то 2-3-мя лишними байтами.
Конпеляторы немного недовольны, но компиляют. Сжал ради интереса пару тестовых файлов - сжатие для начала неплохое, практически в два раза на средних текстовых данных. Хотелось бы конечно же более лучшего сжатия, не алгоритм бабушкина, но хотя бы на уровне zip/7z. Разжать архив правильно прога не смогла - выплюнула только начало первого файла.
Какая же ты няша.
Ну не знаю, я прям весь проект пропускал, и даже собралось. Ругалось, правда, на null-char в конце исходников, но с этим еще разберусь. На Шинде new_dir надо самому создать перед запуском распаковки, иначе крашнется. Сейчас затестю...
ух бля, и чому це..
Короче, это все ваш Windows хуевый, в Microsoft матерей всех ёб! Другого объяснения, почему fseek() двигает позицию втрое дальше, чем ей сказано, я не вижу. По аналогичной причине ломается, собсно, и распаковка. Что-то не так с типом size_t. В пизду такие проблемы, пойду погуляю.
Таким же долбоебам, как я, на будущее...
> Хотелось бы конечно же более лучшего сжатия
У тебя размер кодов фиксированный. Осиль правильные - начинаешь с 9-битных (256 байтов и STOP/FLUSH), заканчиваешь 13 или 14-битными. Опционально сбрасываешь таблицу, если чувствуешь, что начало плохо сжиматься. Алсо, у зипа дефлейт (хафман + LZ77), сделай LZ77/LZSS отдельно попробуй, они простые.
>>47985
Только хотел написать про "b" у fopen(), а ты уже исправил. Алсо, просто писать size_t в файл нельзя, потому что есть 32-битные системы (uint64_t еще туда-сюда, но есть еще и big endian, поэтому правильные посоны читают n байтов и из них сдвигами собирают значение, то же и с записью).
Надо использовать инты фиксированного размера... stdint.h
Первый тест на винде другой анон делал. Кодированием займусь еще. Это основная тема, которая меня интересует, ради которой весь мини-проект начал пилить.
>32-битные системы
Та да, сам над собой проигрываю за это. Сейчас возьму stdint, ну нахер.
>big endian
Как насчет htonl/ntohl?
Еще сделай как у 7зипа, вместо "-arx", "-ext" и "-lst" - "a", "e" и "l", а то непривычно.
Идея следующая. Взять опенсорс-драйвер и переписать таким образом, чтоб он заставлял железку делать хотя бы 1280x960i_60Hz и 2048x1536i_40Hz. Первое, чтоб адекватно работать без вреда для монитора и для глаз, а второе, чтоб просто поугарать с 3 миллионов пикселей на 17" без мерцания. Собсно, вопрос, насколько это сложно, если вообще возможно? Неужели я так многого хочу, СУКАНАХУЙБЛЯДЬ?!?!
>предпредпоследняя буква алфавита
ну все, теперь jump-table для switch-case раздуется до файла подкачки
> Как насчет htonl/ntohl?
Посмотри направо: https://godbolt.org/z/cGBQh1 Ты не платишь (используя гцц и шланге для x86, x86-64 и ARM64) за то, что у тебя безопасный секс. В MSVC платишь, лол. Тащить для этого левый (сетевой) хедер достаточно странно.
macros one love
вопрос лажа, только что качнул powerstrip и осознал абсурдность своих пожеланий
>начинаешь с 9-битных (256 байтов и STOP/FLUSH), заканчиваешь 13 или 14-битными
ох как хорошо стало
И еще вопрос: есть ли способ заставить компиль проверять число аргументов функции при вызове? Потому что у меня получается вызывать функцию объявленную как abc(int, int) с любым количеством аргументов типа такого abc(1,2,3,4,5). Естественно в рантайме все идет по пизде.
Попробуй компилировать с флагами -Wall -pedantic -std=c17 или вроде того.
Если в хедере определена какая-то структура или макрос, то сосешь хуй. А прототипы функций... Ну, ты ведь не хочешь с дебагером играться, чтоб обнаружить, что просто порядок аргументов попутал?
>И еще вопрос:
а, ну все понятно. Басня про подтирание жопы вилкой (или чистку зубов ножом, не помню, так или все ебало в крови, или жопа).
точка входа в процедуру _time32 не найдена в библиотеке DLL msvcrt.dll
И давно Geany стал компилятором? В MSVCRT нет time32, есть просто time, и он, кстати, с 32-битным time_t.
>>49083
Передать функции указатель на массив, скопировать туда. Или выделить malloc()-ом память, скопировать туда и вернуть указатель. Или, в крайне редких случаях и с большой осторожностью, можно сделать массив static и вернуть на него указатель.
>Передать функции указатель на массив, скопировать туда.
Так и сделал. Но не очень удобно так.
>в крайне редких случаях
В каких?
гавна и нинужна
>В каких?
Когда алгоритм не предполагает одновременное использование нескольких результатов этой функции, потому массив один. В смысле, на уровне отдельно взятого алгоритма. Многопоточность-то возможна, есть thread-local static data...
Да. Если у тебя выделено очень много мелких объектов, то так может оказаться даже быстрее, потому что менеджеру кучи не нужно будет заниматься всей этой бессмысленной возней из-за free(), и он просто дропнет всю память целиком. Главное не привыкнуть и не забывать закрывать/освобождать в других ситуациях.
Классно. Теперь буду привыкать не писать.
А если программа 100500 раз использует один и тот же функционал, который каждый раз malloc под временные нужды? Наслаждайся утечкой ресурсов.
ой, мои пардоны, обосрался
В Сишке нет невидимых if-ов. float переведется в int (это процессорная инструкция), но если кастовать char, то просто младший byte от соответствующего int будет.
Анон, работаю в Code::Blocks. Подскажи, как можно проверять кучу? Хочу удостоверится -- правильно ли я реализовал сборщики мусора, а заодно понять есть ли утечки
Посоветуйте веб макаке что писать на сишке для грамотного развития? Сам подергал день синтаксис, ничего сложного не увидел, всё классно и понятно, писать хочу для себя
Куда двигаться, что писать чтобы правильно развиться?
Ну вот, я даже тебя понять не могу.
Что ты пишешь вообще? Оно тебе надо? Может, лучше, сайтик?
Напиши простой веб сервер для себя. Можешь заодно посмотреть исходник какого-нибудь nginx-а, в качестве примера.
Почему?
Если ты хочешь в прод что-то запустить, то да, лучше взять готовое решение. А если хочешь набить руку на СИ, то можно запилить свой сервер. Тем более реализацию всегда есть где подсмотреть.
Скажем так, будет весьма неудобно. Бери нормальный скриптовый язык (лучше всего дефолтный питон). Вот если упрешься по производительности во что-то, и не найдешь под это готовой либы (что очень маловероятно), тогда можно эту часть написать на Си.
Короче, есть необходимость юзать компилятор крестов, потому что пидорскую библиотеку, которая, надо заметить, нихуя из удобных крестовых фич не юзает, просто так решили сделать под кресты, соответственно, чистая и непорочная сишечка ее .h уже не переварит. Но пишу я, как на Си, естественно, я же не пидор. Стало быть, от крестов мне одни неудобства. Например, malloc() надо КАСТОВАТЬ, потому что void ∗, видите ле, уже нельзя просто так вхуячить. И это самый простой пример. Мне подобные "-Werror из коробки" доставляют гораздо больше неудобств.
В связи с этим, такой вопрос... Можно ли вежливо попросить майкрософтовский cl, чтоб он закрыл глаза на всю эту implicit хуету? Если нет, то я желаю создателям стандарта нестандартной смерти, БЛЯДЬ!!!
Все, уже нахуй надо, рот я ебал вашего С++. Обмазался кастами, обожрался даже, пойду чаем запивать.
> пидорскую библиотеку, которая, надо заметить, нихуя из удобных крестовых фич не юзает, просто так решили сделать под кресты
Так портируй, поправь .h.
Мучительно. Большую часть времени потратишь на написание кода, а не на анализ данных. Бери питон, там куча готовых движков для такой лабуды.
А GNU R?
>malloc() надо КАСТОВАТЬ
Его же и так надо кастовать в почти любом случае. А если не нравится, пиши на джаве, там все в дженерики можно завернуть, и сишные хедеры к проекту прилепить. А хейт ерестов — ну это ты просто маленький ещё.
Тебе не похуй? Openpdn открывай и смотри, вряд ли они что-то кардинальное в могли напиздячить в hsl алгоритм.
Впрочем берёшь последнюю версию пынянет и прогоняешь деобфускатором/анпакером/декомпилятором и читаешь исходный код. На дотнете это делается легко, инструментов навалом.
Нашел как там меняется насыщенность. Довольно оригинально. Надо попробовать себе подобное закодить.
https://github.com/rivy/OpenPDN/blob/master/src/Core/UnaryPixelOps.cs#L854
Вот и весь алгоритм. Оказался гораздо проще, чем в моделях HSV/HSL и результат работы выглядит офигенно.
Я не автор XnView, а пилю крохотную программку для проявки raw, которая еще далека до совершенства. Раньше она делала насыщенность как в XnView, а теперь как в Paint.Net.
Ну покажи. Выше же выложил результат своей работы.
Анон, выделяя память с помощью calloc, ее обязательно нужно высвобождать, или же это произойдет автоматически при завершении программы?
Довольно неопределенный хули. Но, спасибо за пояснение.
Ну если найдешь на гитхабе можно и там. Я вообще имел ввиду сайт разработчиков. Вот. например: https://hg.nginx.org/nginx/file/tip
Листаю статейки, но общего понимания что эта за хуйня и как она работает так не получить. Чо это такое та, как хоть называется? Что читать?
>Чо это такое та, как хоть называется? Что читать?
Ассембоер, плюс формат исполняемого файла ОС
Короче, .data - это, грубо говоря, инициализированные глобальные переменные/массивы, значение/содержимое которых занимает место в бинаре (.exe-шнике). Ты прям там же пишешь значения, строки, и т.д., и т.п., и оно все там напакуется, где надо. Под .bss память выделяется тоже в сегменте данных при запуске и заполняется нулями (могу ошибаться), короче эта хуета не составляет вес бинаря. .text - это сегмент кода, он readonly. Ну а дальше там сегмент кучи идет, и с потолка адресного пространства растет стек, но это другая история. Короче, ассемблерный код - это практически 1 в 1 содержимое бинаря, только с удобствами вроде буквенных меток, из которых линкер потом циферки сделает, и мнемоник вместо кодов инструкций.
Открой любой экзешник в графическом отладчике типа x64dbg, там есть закладка memory map, в которой наглядно видно что находится в памяти процесса, твой экзешник с сегментами и другие дллки которые он использует, подписаны названия модулей, сегментов и их атрибутов.
Это секции. Для чего и почему так сделано кури форматы приложения.
Не знаю, что там у тебя фэйлит, недавно ставил на виртуалку XP и MinGW. TCC возьми, лол.
Нафиг cd? В проводнике, в нужной папке: Шифт+пкм, открыть окно команд.
Вощем заработало, только окно закрывается сразу, а что там в настройках жать я что-то не помню
Оно и должно закрываться, у тебя же программа отработала и завершилась. Если ты хочешь, чтобы консоль оставалась открытой, попробуй запускать программу не двойным кликом, а также через консоль, как ты компилятор запускаешь. Либо добавь getch в конце программы, чтобы добавить задержку. Но лучше первый вариант.
Немного не в тему. Читаю сейчас код одного FTP-сервера, который написан, конечно же, на С. Начав с определенного момента в коде, который мне интересен (а именно того, где клиент подключается к серверу и получает приветственное сообщение) я изучил внушительное такое дерево функций. Я все.
Годно, спс, интересно на кого же расчитан в моем случае кериган и ричи, если там нет этой инфы в начале
Что скидывать? Мои комментарии к нему могут вызвать лютый кринж, как и зарисовки дерева в блокноте. Я вообще надеялся на то, что смогу уязвимость найти.
>могут вызвать лютый кринж
>могут
Какие мы оптимисты :3
Скидывай все, хочу кринжироваться полчаса.
Насмешил прям, от души
Пидора ответ.
> на кого же расчитан в моем случае кериган и ричи
На людей, которые обладают базовыми навыками работы в ОС. Особенно если у них винда.
Эмм.. наверное, на людей из 80-х, которые и не в курсе, что кроме консоли может что-то существовать.
Хватит всяких хуесосов советовать. Упрощая себе жизнь, ты обкрадываешь себя. Керниган и Ритчи - годный курс для аудитории с мозгами, а Прата - ньюфаг и вообще муслим.
Сначала прочитает Прата, а потом твою древноту, если захочет.
ALSA API
Никак. Звук генерируется операционной системой, её апи и библиотеками.
> Как генерировать звук
for (j = 0; j < 44100; j++) sound[j] = sin(2 ∗ M_PI ∗ (j / 44100.0) ∗ 440) ∗ 32767; бззз
fwrite(buf + pos1, 1, pos2 - pos1, fout);
fwrite(&buf[pos1], 1, pos2 - pos1, fout);
Первый вариант: проще читается
Очевидный kaitai struct или вариации на его тему, если ты хочешь машинно-читаемое описание и простые сишные структуры, если не хочешь. Все умеют читать сишные структуры, а питонисты пускай сами в свой unpack ебутся.
Но я никак не могу понять как подключать рейлиб.
В архиве с библиотекой был нотапд++, через который можно execute делать.
Но как конпелировать через минигв или сигвин, чтобы эти биоблитеки програма видела?
Прямой путь казывал - не работет.
И еще вопрос - какая ИДЕ? Или лучше забить и самому научиться шел-срипты писать?
что-то представил его авторов юзающих cmd.exe и проиграл
> Прямой путь казывал - не работет.
Где скриншот сообщения об ошибке?
gcc -Iraylibpath/include -Lraylibpath/lib filename.c -lraylib -o filename.exe как-нибудь так.
>gcc -Iraylibpath/include -Lraylibpath/lib filename.c -lraylib -o filename.exe как-нибудь так.
Спасибо, Антош. Попробую.
Монжо ли типобезопасно int представить как char[4] (считаем, что инт - 32) без цикла заполнения со сдвигами?
Мне в голову очевидно приходит только char x = (char )&int_name;
Ну конечно двач звёздочки как курсив переделал, после char звёздочка в обоих случаях
>считаем, что инт - 32
Ты считаешь? Инт может быть 64 битный. Выбивай биты маской и ложи по соответствующему индексу в массив
...0
char[1] = int & (11111111 << 8)
...2
...3
>Ты считаешь? Инт может быть 64 битный
Я имел ввиду, что в моём случае инт 32 и это точно
Предложенный тобою способ как раз со сдвигами + копирующий массив, а мне нужен указатель в то же место с другим представлением
Мне сейчас в голову ещё union старый добрый пришёл
как насчет чего-то вроде функции, делающей строку задом наперед, но не по нуль-терминатору, а по заданной длине?
void memflip(char ∗ptr, size_t nbytes)
{
for (char p = ptr, q = ptr + nbytes - 1; p < q; ++p, --q)
swap(∗p, ∗q);
}
Ну, swap - это типа макрос.
А юзать просто memflip(&n, sizeof(int));
трохи обісрався з зірочками
как насчет чего-то вроде функции, делающей строку задом наперед, но не по нуль-терминатору, а по заданной длине?
void memflip(char ∗ptr, size_t nbytes)
{
for (char ∗p = ptr, ∗q = ptr + nbytes - 1; p < q; ++p, --q)
swap(∗p, ∗q);
}
Ну, swap - это типа макрос.
А юзать просто memflip(&n, sizeof(int));
Это аналогично strrev или std::reverse в плюсах
Как развернуть я знаю, проблема именно в типобезопасности, вроде и хочется забить, потому что размеры всё равно выставляю не числами, а sizeof, но и мысль покоя не даёт
https://github.com/PolazhinetsA/algo/blob/master/lzwarc/diter.c
Как сделать подобную лобудень (рекурсивный итератор файлам в папке) на Windows? Я с гуглом так себе дружу. Запрос "Windows File System API" что-то по low-level выдает.
FindFirstFile/FindNextFile/FindClose, но лучше не рекурсивно (рекурсия вообще почти всегда неправильное решение проблемы), а с явной очередью/стеком, в которые ты будешь складывать дочерние директории. Не забывай о FILE_ATTRIBUTE_REPARSE_POINT, ты и в своем коде симлинки не обрабатываешь, а это хороший способ зависнуть нахуй.
> while (dent && dent->d_name[0] == '.');
/home/user/.config ты тоже пропустишь?
Вот это, кстати, оч интересно
Но как именно собрать в bswap? Просто именно так и скопировать функцию, а конпелятор типа умный? (если это cc)
Ну вот есть у тебя: /foo/bar -> /foo, что получится, если ты будешь рекурсивно /foo обрабатывать?
>>55366
> а конпелятор типа умный
https://godbolt.org/z/U-nIbM а еще у гцц интринсики есть.
>/foo/bar -> /foo
это понял. Не понял, как у меня симлинки пройдут проверку s.st_mode&(S_IFDIR|S_IFLNK)
>/foo/bar -> /foo
это понял. Не понял, как у меня симлинки пройдут проверку s.st_mode&(S_IFDIR|S_IFREG)
обосрался с константой
я там максимально делегировал проверки на часто вызываемые функции, чтоб не дублировать исключения в коде высшего порядка
> как у меня симлинки пройдут проверку s.st_mode&(S_IFDIR|S_IFREG)
Потому что это &, а не ==. И еще потому, что S_IFLNK = (S_IFREG | S_IFCHR). Страдай.
Оце так туебень. Поленился значения глянуть. Ок, понял, не буду выделываться, обойдемся без s.st_mode&(-1<<9)==, примем помощь S_IS макросов...
Аноны, помогите. Программуля то работает нормально, то возвращает статус 255, причем набор входных параметров всегда один и тот же. В чем может быть проблема?
Заметил одну вещь, если программу запускать каждый раз, после ее выполнения, то есть, долбить по значку левой кнопкой сто раз в секунду, то сразу же, на второй раз она крашится с кодом 255, но, если подождать пару секунд и снова запустить, все в порядке.
Работаю в Code::Block, он не отлавливает никаких SEGFAULTов во время возникновения 255.
Анон, с чем может быть это связано?
Похоже, что пытаюсь освободить с помощью free свободную область памяти
Кто чем форматирует/разукрашивает логи полученные в различных форматах?
Я пробовал lnav, но чет он или я какой-то слишком тупой и не может нормально работать когда в файле с логами есть строки, которые отличаются от базового формата. Да и форматировать вывод (т.е., например, автоматически выравнивать поля) он не умеет.
Всякие консольные sed+colorize и т.п., конечно, хороши и умеют всё, но я не хочу пердолиться с regex-ами.
Если они логически связаны друг с другом (например, абсцисса и ордината точки на плоскости), то struct.
Если нет, то несколько параметров-указателей, ничего страшного в этом.
Сделал через параметр-указатель. Вроде костыльно, но работает хорошо.
объединить три участка без запросов к памяти?
даже если они все троём на стеке, у тебя не выйдет
Пока вижу только по 10 бит на fixed point. Получается 1/1024 точность. А лучше есть?
>по 10 бит
Флоат ты туда никак не запихаешь.
Смирись разве что это зависимые значения - но тут уже математика
в смысле не (((float))) а вещественное число.
Похуй, точности хватит я щитаю.
https://ideone.com/zW2r6Y
Доставьте, пожалуйста, парсер консольных параметров от несосунов (suckless soft). Помню, что у них была клевая библиотечка на макросах.
Динамические многомерные массивы нельзя. Или у тебя указатели (лишняя память), или ты сам считаешь индексы (лишние умножения). Для статических вполне используют массивы массивов, никто не жалуется.
Не делает, т.к. там используется тот же самый mul порт. Но умножение в современных процах - операция 3-5 тактов, и таких портов там обычно не меньше двух, считай умножение очень дешево.
Это не те умножения. Чтобы проиндексировать элементы в одномерном массиве, может быть достаточно lea, но я имел в виду представление двумерного динамического массива в виде одномерного. Например, image[height][width] как image[height ∗ width] с доступом вида image[y ∗ width + x]. Здесь у тебя width - переменная, ее нельзя сократить ни до каких эффективных адресов или сдвигов со сложениями, как было бы сделано для статических двумерных массивов.
>>58050
> умножение очень дешево
Пара лишних инструкций для вычисления индекса у тебя все равно есть. А еще может быть алиасинг, заставляющий индексы и измерения каждый раз заново грузить.
>Пара лишних инструкций для вычисления индекса у тебя все равно есть. А еще может быть алиасинг, заставляющий индексы и измерения каждый раз заново грузить.
Это проблемы тех, кому надо писать много-много отдельных точек по рандомным координатам, т.е. долбоёбов с их laba01. Обычно всё сводится тупо к row-major обходу одного или нескольких слайсов массива с прибавлением высчитанной этим самым умножением константы. Посмотри, как делаются софтверные растеризаторы - там тупо обходятся все точки, но ненужные игнорируются. И так оно работает с 90-х по наши дни.
Ошибка вот такого вида:
Ошибка вот такого вида: "a.out: malloc.c:2406: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed."
> pas[i] = (char ∗) malloc( (strlen(buffer) + 1) ∗ sizeof(char ∗));
Ты вводишь "foo", длина строки 3 (+ 1) = 4, потом зачем-то умножаешь на sizeof(char ∗) хотя должен бы либо на sizeof(char), либо вообще не умножать, потому что sizeof(char) всегда 1. (3 + 1) ∗ 8 = 32 байта выделяешь. Дальше ты делаешь:
> strncpy(pas, buffer, 80);
Во-первых, тебе не нужен тут strncpy, достаточно было обычного strcpy. Во-вторых, ты пишешь 80 байтов, а выделил, как мы выяснили, только 32. И ты портишь память, которая тебе не принадлежит. На следующей итерации malloc() в эту память лезет, а там мусор. Он охуевает и падает. Такие дела.
Алсо, я не совсем понимаю, зачем тебе clean_buf_str(), если ты можешь просто один раз положить \0 в write_string после завершения while. Это быстрее и очевиднее, чем полагаться на предыдущее содержимое буфера.
Спасибо за советы. Исправил теперь эту ошибку. Просто, если честно жопой смотрел, что умножал на тип указатель на char, а не на обычный char.
>clean_buf_str()
Я использовал для того, чтобы очистить буфер после того, как я проивзеду копирования слова в массив указателей. Т.к. мне нужно по заданию вывести каждую строку отдельно в массиве строк, то буфер надо очищать после каждой записи слова, ведь тогда, следущее слово может быть короче предыдущего, и 'мусорные символы' запишутся в следующую строку.
> слово может быть короче предыдущего, и 'мусорные символы' запишутся в следующую строку.
> и 'мусорные символы' запишутся в следующую строку
Я именно это и имел в виду. Не похуй ли тебе, что у тебя там в неиспользуемой части буфера? Смотри:
char buffer[16];
strcpy(buffer, "abcdef");
strcpy(buffer, "foo");
// buffer = "foo\0ef\0"
printf("%s\n", buffer); // "foo"
Анончи, русские символы в дефайнах поддерживаются?
Юникод поддерживается в идентификаторах в виде escape-последовательностей (\u04xx р) везде, а просто так - в основном не поддерживаются, ибо нахуй никому не нужно. Можешь поиграть в -fextended-identifiers в gcc/clang, может сделали.
int C; C = (int )malloc(sizeof(int)); sscanf(buffer, "%d", C);
Затем, в другой подпрограмме происходит следующее:
int value; value = (int )malloc(sizeof(int));
value = (int *)pointer;
Так вот, значения указателя C и значения указателя value всегда сука равны. Как такое может быть-то?
Быстрофикс:
Так вот, значения указателя C и значения указателя value всегда сука равны. Как такое может быть-то?
Эти две строчки расположены в разных функциях, которые поочередно вызываются в еще одной функции. Но, полагаю, это не должно играть роль.
Оберни malloc вот таким макросом
https://stackoverflow.com/questions/50120115/calling-malloc-from-within-a-wrapper-macro
Оттуда печатай себе инфу - файл, строка, параметры, ret.value в stderr
быстрофикс: попробую
блин, точно, гениально и просто. Я просто забыл, что функция будет читать до первого '\0'.
Алсо где можно прочитать про хедер файлы нормально? Я нихуя не могу понять чому я не могу сделать #include "smth.c" в нескольких файлах, зачем городить эти хедеры?
В K&R написано "просто ебаште один хедер-файл на всю программу)))", это и есть бест-практис?
Мне что-то шапка треда не доставляет. Вроде список литературы есть, но что-то не вяжется.
Вот у пайтон есть Марк Лутц, который подробно расписывает что к чему и как реализовать ту или иную функцию.
Я ранее писал на С++ в вузе, но именно на Си не писал. Подскажите учебник, чтобы не сильно тупо разжёвывал, но и не для мидлов.
Прата у меня есть, К и Р у меня тоже есть, но старые (1982 и 1988 годов соответственно) . Их можно читать или взять что-то свежее?
Из чего выбрать :
0. K&R
1. Кочан Вуд.
2. Стивен Прата
3 . Дейтл и Дейтл
4. Столяров
5. Head First C
Кто с чего начинал?
Задачи какие - писать всякие полезные программы для себя чтобы не делать рутинную хуйню. Писать хочу под freeBSD и Windows.
> Я нихуя не могу понять чому я не могу сделать #include "smth.c"
Можешь. Делают. Посмотри, например, на tinycc.
> в нескольких файлах
Допустим, у тебя в smth.c есть функция foo и массив uint8_t array[104857600] (100 метров). Если ты заинклудишь его в нескольких файлах, то во-первых, ты очевидно продублируешь код и данные, и размер твоей программы (или размер программы в памяти, зависит от деталей) вырастет в n раз. Во-вторых, линкер скажет тебе, что ты мудак, потому что у него будет две функции foo и два массива array. Поэтому ты говоришь в одном .c файле, что вот она функция и вот он массив (определяешь их, у тебя definition), а в остальных ты говоришь, что в программе существует вот такая функция и вот такой массив (объявляешь, у тебя declaration). Линкер эти две вещи свяжет вместе, и вся программа будет использовать одну копию функции и одну копию массива. Хедеры сами по себе для этого не нужны, ты можешь копипастить объявления в каждый файл. Но гораздо удобнее положить все объявления, относящиеся к какой-то части программы, в одно место и втыкать все разом. И в случае необходимости править их в одном месте на самом деле в двух, нужно еще определения править, а не искать по всей программе. И вот именно в хедеры их и кладут.
> просто ебаште один хедер-файл на всю программу
Для программ и двух-трех файлов, если ты не собираешься использовать код где-либо еще - вполне норм. Если программа крупная, или ты хочешь переиспользовать ее части, группируй функциональность в "модули", "подсистемы" или "библиотеки" (это может быть один .c-файл, может быть несколько, может быть директория целая) и, соответственно, для каждого вот такого модуля ты делаешь хедер, которым пользуются другие модули (остальная часть программы).
>>60751
> Из чего выбрать
K&R если хочешь страдать и насыщаться духом старой школы, свежее издание Праты, если хочешь просто качественно выучить современный Си.
спасибо. тогда прата мой выбор
Сегодня нашел задачку с собеседования на си разраба и решил.
Когда собеседовался не мог, затупил от нервов или я со временем поумнел (врядли).
Кстати, работу я так и не нашел, сейчас вкотываюсь в жаваскрипт.
дай линк на зодачи
Спасибо, анончик :3
> ты очевидно продублируешь код и данные
Хотя вот это всё равно немного не понял. В высокоуровневых языках я могу делать импорт какого-то модуля/пекейджа в нескольких местах, и это всё разрулится, главное чтобы не было циркулярных зависимостей.
Что мешает линкеру только один раз включить файл? Или так определено в стандарте, что инклуд должен копипастить?
Вот пробовал GCC обыкновенный, смотрел утечки и прочее, вроде бы все норм (без учета утечек), собрал ту же программу с Cygwin -- бинарник в два разам меньше, но помимо утечек добавились какие-то:
Error #1: UNINITIALIZED READ: reading register eax
# 0 KERNELBASE.dll!FindNextFileW+0x109 (0x74ea24c9 <KERNELBASE.dll+0xf24c9>)
# 1 KERNELBASE.dll!FindNextFileA+0x2f (0x74ea0500 <KERNELBASE.dll+0xf0500>)
# 2 .text [../../../src/gcc-6.3.0/libgcc/config/i386/cygwin.S:184]
# 3 __mingw_glob [../../../src/gcc-6.3.0/libgcc/config/i386/cygwin.S:184]
Не пойму из-за чего это так
Компилятор отдельно компилирует каждый .c (вместе со всем, что ты туда заинклудил) в .o, и если был инклуд ОПРЕДЕЛЕНИЙ функций и чего-то еще, а не только ОБЪЯВЛЕНИЙ, то они тоже скомпилятся по экземпляру в каждом .o, который делался с инклудом этой штуки. Линкер же не занимается "включением файлов". Работа линкера, грубо говоря, сделать из символов адреса. Даже компилятор, как таковой, этим не занимается. #include - препроцессорная директова. Чтоб заголовочный файл можно было безопасно инклудить везде, где он используется, не задумываясь, не инклудит ли его другой уже инклуднутый файл, делают:
#ifndef FILE_H
#define FILE_H
содержимое
#endif
Препроцессор не умеет, и не должен, в собственную логику с условиями. Он на то есть, чтоб делать все буквально, даже самую странную дичь, если ТЫ знаешь, что делаешь.
Checking file dependency...
Compiling C:\Documents and Settings\Мои документы\C-Free\Temp\bookinfo.c...
[Error] C:\Documents and Settings\Мои документы\C-Free\Temp\bookinfo.c:1: error: stray '\239' in program
[Error] C:\Documents and Settings\\Мои документы\C-Free\Temp\bookinfo.c:1: error: stray '\187' in program
[Error] C:\Documents and Settings\\Мои документы\C-Free\Temp\bookinfo.c:1: error: stray '\191' in program
[Warning] C:\Documents and Settings\Мои документы\C-Free\Temp\bookinfo.h:11:3: warning: no newline at end of file
[Warning] C:\Documents and Settings\\Мои документы\C-Free\Temp\bookinfo.c:36:2: warning: no newline at end of file
Complete Make bookinfo: 3 error(s), 2 warning(s)
Подскажите, почему в ANSI кодировке работает но кириллица в коносле не отображается когда сохраняю в UTF-8 вылазят эти ошибки? IDE Cfree/
> Или так определено в стандарте, что инклуд должен копипастить?
Да. #include не магия. Это просто вставка содержимого одного файла в другой, ничего больше.
>>61248
С кириллицей в винде вообще большая жопа. По-хорошему надо делать свои обертки вокруг printf, которые будут делать MultiByteToWideChar и WriteConsoleW для вывода нормального юникода. Либо ты мог бы использовать павершелл, в котором можно chcp 65001, но у тебя XP, лол.
> кириллица в коносле не отображается
Потому что по умолчанию консоль в винде использует CP866. Ты можешь сохранить файл с кодировкой 866, можешь сохранить как UTF-8, но сказать компилятору, чтобы он сам текст конвертировал: -fexec-charset=cp866 (лучше всего), либо можешь пердолиться в SetConsoleOutputCP и SetConsoleCP, чтобы твои ANSI (cp1251) строки отображались.
> сохраняю в UTF-8 вылазят эти ошибки
Сохраняй без BOM (UTF-8 without signature). И вообще никогда с BOM не сохраняй, это абсолютно нинужное, вредное говно.
> IDE Cfree
А почему нам должно быть не похуй? IDE не занимается компиляцией.
Шёл 2к19, ОС Ш1ИДОШ5 так и не научилась в нормальную работу с кириллицей.
>IDE Cfree
Там в настройках сохранения есть выбор ANSI, UTF8, UTF8-BOM, UTF-16 тоже с BOM в ANSI все запускается при других ошибки. Какие настройки нужно смотреть?
Винда нормально не умеет в UTF-8 (в основном в консоли, и только если использовать стандартную оболочку - во всех нестандартных починено), а вот в юникод она научилась еще раньше линукса, в ядре NT юникод от рождения.
UTF-8 сам в себя не умеет. Это сжатый формат с которым нельзя работать нормально. Так же как нелепо придумать вместо нормального .txt пожатый по какому-нибудь алгоритму, чтобы потом парсить на каждый пук. Просто нелепо.
Ну он имеет в виду, что нельзя перейти к символу n, не распарсив предыдущие n - 1. Хотя на практике такое никому не нужно.
З.ы. а зная какой язык, то никакой разницы с 1 байтовой нет.
clang -I "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.22.27905\include" -I "C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt" -c -v hello.c -o hello.exe
Получившийся бинарник вываливается с ошибкой "Unsupported 16-bit application". Если передавать дополнительно ключ --target=x86_64 вываливается сраная простыня ошибок, в основном из vcruntime.h. В интернетах пишут, что если убрать ключ -c, это помогает. У меня без этого ключа жалуется на отсутствие линкера. Я немного в фрустрации.
> Unsupported 16-bit application
Ты обозвал объектный файл exe-шником и пытаешься его запустить, а винда не может его распарсить и считает, что у тебя .com-файл с именем .exe, а у тебя десяточка без NTVDM, которая и .com тоже запускать не умеет.
На самом деле объектные файлы надо еще слинковать, компилятор либо сам вызывает линкер (без -c), либо ты должен явно сказать clang -c file.c -o file.o и потом ld file.o -o file.exe (плюс-минус пути и либы).
> Установлена студия 2019
Непонятно, каким местом связаны студия и шланг. Шланг под виндой вроде бы всегда хотел binutils из MinGW (в том числе, например, линкер, который оно у тебя найти не может). Ставишь MinGW, кладешь в %PATH%, clang-ом компилируешь, ld из MinGW линкуешь. Или оно само линкует: clang hello.c -o hello.exe.
Но если у тебя есть студия, зачем тебе шланг вообще? Из этого самого: cl /c hello.c /Fohello.obj && link hello.obj /OUT:hello.exe. Или даже просто: cl hello.c и всё (инклуды студии в переменные окружения сам Developer Command Prompt должен был положить).
> Ты обозвал объектный файл exe-шником и пытаешься его запустить
Хех :) Хелп к clang ввел в заблуждение, там ключ -o описан просто как "Write output to <file>", я ожидал там готовый экзешник.
> линкер, который оно у тебя найти не может
Не могу понять, почему. Линкер лежит в той же папке, где и сам clang, она прописана в %PATH%. Ну да и линкование вручную не сработало (скриншот аттачед).
> Но если у тебя есть студия, зачем тебе шланг вообще?
Вижла жирноватая, я ставил только нужные мне по работе фичи. Поддержку плюсов не устанавливал, только какой-то SDK. План был просто читать книгу, писать примеры в саблайме и компилять их легковесным шлангом. Я еще попробую MinGW поставить, как ты сказал, но что-то мне уже подсказывает, что если столько проблем возникает, проще уже какой линукс в виртуалке поднять. В любом случае спасибо тебе большое за дельные советы, а не обкладывание хуями.
Ставь msys2 и не мучайся. Там накатишь mingw64 нужные тебе либы, IDE и т.д Можешь еще conemu поставить(эмулятор термила). Годная вещь, на шинде рекомендую
Спасибо тебе, анон! Наконец-то можно учиться, а не сражаться с окружением.
С понимания архитектупы ПК и ОС, ты несешь дичь, ты должен не с ядром, а видеодрайвером взаимодействовать. Гугли framebuffer.
>There was also a windowing system called FramebufferUI (fbui) implemented in kernel-space that provided a basic 2D windowing experience with very little memory use.
https://github.com/8l/fbui
Ну, во-первых "++" не просто икрементит, а изменяет значение переменной, т.е. [code]size++[/code] то же, что и [code](size += 1)[/code] или [code](size = size + 1)[/code] это так, к сведению.
Во-вторых [code](p+array + size)[/code] значит то же, что и [code]p_array[size][/code] или [code]size[p_array][/code];)
и указывает не на последний, а уже на следующий за границей массива элемент (контроля границ в сях обычно нет, тем более для динамических массивов), потому что индексация массивов в Си и многих других языках начинается не с единицы а с нуля, т.е. по индексу 0 будет первый элемент, по индексу 1 - второй, ..., по индексу (size - 1) - последний, по индексу size будет уже кусочек памяти лежащий сразу за последним элементом и т.д. Если тебе нужен был последний элемент, то выше тебе вместо [code]size++[/code] надо было написать [code]size + 1[/code] или вместо [code](p_array + size)[/code] надо было [code]p_array[size - 1][/code]
Ну и в-третьих в цикле также ошибка с индексацией, надо было начинать с нуля.
В-четвертых, т.к. ты скинул картинку вместо текста, то иди нахуй исправляй и проверяй сам.
ну так уеюывай на
Да, ты прав, дело оказалось в индексации. Получается, я записывал в невыделенный блок, который только на следующем цикле "захватывался". Однако всё равно не могу понять, почему косяк при выводе массива происходил только с четвёртым элементом? Наверное потому что после этого блока realloc просто не находил свободный соседний и брал другой из ебеней.
Вообщем бобров тебе
Ради интереса попробовал притащить шланг (64-битный инсталер с официального сайта) в винду (64-битная семерка) без MinGW, но со студией. Если запускать не из developer command prompt, все просто работает, оно само пути ищет (clang hello.c и все), из developer command prompt: clang --target=i686-pc-windows-msvc hello.c, и опять же все работает. Или 64-битный билд и developer command prompt: сначала vcvars64.bat и потом опять же clang hello.c. Что же касается твоего пика, то это сложный способ, но у тебя ведь почти получилось, тебе только рантайм нужен был: lld-link hello.obj libcmt.lib. Но msys2 двачую, если лень возиться с настройкой и думать.
тут просто есть 1 (один) умный дурачек который любит объяснять новичесам очевидные вещи
Да мы так просто, чтоб мозги не засыхали.
Из простого command prompt не собиралось, не могло найти stdio.h. Да и варнинг выдавало, в котором явно было написано, чтоб попробовал через developer command prompt. Сейчас я не хочу тратить время и разбираться, чего шлангу не хватает. Как вы оба сказали, msys2 крутая штука, все завелось с первого раза. Возможно, стоит добавить в шапку.
Да мне нахуй этот С не всрался работать на нём, лол, как и большинству, я думаю.
Мне чисто по фану с лоу-левелом поиграться.
Я про него и говорил, ебушка
Простенькую демку к примеру
Мозги для микроволновки
Главное, что я не могу понять, так это, что функция вроде как прочитала файл, но те значения, которые она прочитала совсем не те, что я ожидал.
Толсто
Ты берешь строчку длиной sizeof(int) и считываешь ее в int. Все равно что написать "0010", привести к указателю на int и взять значение, это полный бред. Хочешь считать числа в своем файле - бери fread на весь файл в один char буфер, потом иди по нему функцией strtol.
Окей, но я если честно все равно не догнал почему мой вариант не работает. Асло я писал по этому примеру: http://www.c-cpp.ru/content/fread . Можешь, пожалуйста объяснить более подробно?
У тебя в файле числа текстом. Ты читаешь текст, интерпретируя его как целые числа. Если бы ты хотел читать целые числа, тебе и записать их туда нужно было как целые числа (fwrite из подобной же программы или хекс-редактором, например). Если же ты хочешь читать именно числа текстом, то как тебе уже посоветовали, тебе нужно читать fgets/fread в текстовый буфер и потом парсить strtol или strtok/atoi.
Алсо, ты говоришь, что читаешь в бинарном режиме, а флага "b" в fopen у тебя нет.
ах. Я кажется понял теперь, спасибо(чтобы прочитать их как целые числа, то нужно было использовать функцию fwrite для начала, так?). Да, я пропустил флаг, тоже потом заметил.
> нахуй он нужен
В целом extern тебе нужен, чтобы сказать, что где-то есть такая переменная (обычно в другом файле, поэтому и extern - внешняя).
Да, спасибо, я уже вроде как разобрался.
Все равно у тебя большой пробел в знаниях. Посиди и подумай, почему так:
https://ideone.com/R8541f
Такое число получается в val из-за того, что мы интерпретируем указатель на char * как указатель на 4 байтный инт(в твоём случае это uint32_t) и сразу разыменовываем его и в итоге он итерпретирует 4 байта строки str как 4 битное число (т.е. возьмёт номера 4 символов из таблицы ASCII и интерпретирует их). Я прав?
4 байтное число*.
Примерно так, только вот номера символов ни откуда никто не берет, строка так там и лежит, в памяти всегда все в виде чисел и хранится. В >>63183 допущена именно такая ошибка, fread читает сырые данные в буфер, и ничего с ними не делает и в массиве numbers получаем в итоге мусор, если смотреть на него как на массив интов. Чтобы получить числа тебе нужно либо использовать вместо fread scanf, либо как-то самому парсить считанные данные, например sscanf'ом.
Спасибо тебе большое анончик. Добра тебе. Да, я заменил fread на fscanf.
Что, уже смотрел расписание?
Есть n элементов, среди которых нужно найти наименьший. Если искать линейным поиском, то нужно сделать n-1 сравнений очевидно, т.е. n-1 итераций. А если сортировать по Шеллу, то проходов будет n/2, т.е. почти в два раза быстрее, и в конце запись одного из крайних элементов. Однако элементарных операций (вроде обменов данных между регистрами) намного больше при сортировки Шеллом. Что в итоге будет быстрее и почему?
бля, уже нашел
int fd_test;
char *fd_test_path = "/mnt/cache/test";
mkfifo(fd_test_path, 0666);
fd_test = open(fd_test_path, O_RDONLY);
char c = 0; printf("\n");
while(c != '.')
{
if(read(fd_test, &c, 1) > 0) printf("%c", c);
else printf("?:%02X ", c);
}
printf("\n");
close(fd_test);
unlink(fd_test_path);
Тестирую так:
echo -e "message." > /mnt/cache/test
Ждёт ввода. Далее нормально печатает и завершается. Но если в исходящем эхо нет точки (условный терминатор), то бесконечно читает последний байт, как сумасшедшая:
?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A ?:0A .
echo -e '.' > /mnt/cache/test
Мне нужно, чтобы программа транслировала входящий поток байт-к-байту, пока не поступит байт завершения.
Если проанализировать бинарник собраной либы утилитой nm
nm libSDL2.a | grep "_SDL_COREMOTION_SensorDriver"
такой символ там находит
U _SDL_COREMOTION_SensorDriver
Тип U как я понял это символы, которые определены в других местах. Вот нашел исходник файла, в котором определяется
переменная с нужным названием и действительно она extern
https://github.com/spurious/SDL-mirror/blob/17af4584cb28cdb3c2feba17e7d989a806007d9f/src/sensor/SDL_syssensor.h#L100
По логике проблема должна быть в том что не подключен фреймворк CoreMotion, но он подключен. И вообще не очень понимаю как работает код, где в итоге подключается/присваивается/определяется значение этой переменной
https://github.com/spurious/SDL-mirror/blob/17af4584cb28cdb3c2feba17e7d989a806007d9f/src/sensor/SDL_sensor.c#L40
Т.е. как в сигоспода ищут откуда берется какая-то глобальная переменная, если видят ее обявление?
В чем может быть проблема?
By definition, the char type uses 1 byte of memory to represent a character. Historically, this character byte has most often been 8 bits, but it can be 16 bits or larger, if needed to represent the base character set.
Не могу вкурить, как байт может равняться 16 битам, если он вроде как по определению 8.
>все равно при компиляции выдает ошибку линковки о том что не может найти символ _SDL_COREMOTION_SensorDriver", referenced from _SDL_sensor_drivers in libSDL2.a(SDL_sensor.o)
https://github.com/sdl/sdl-ios-sampleapp - этот проект?
>откуда берется какая-то глобальная переменная, если видят ее обявление?
https://github.com/spurious/SDL-mirror/blob/17af4584cb28cdb3c2feba17e7d989a806007d9f/src/sensor/coremotion/SDL_coremotionsensor.m#L217
Отсюда берется.
Прочти ещё раз.
Обычно char - это байт. Но на некоторых платформах он может быть любым, аффтар рекомендует перепроверять, когда пишешь под что-то редкое.
>Не могу вкурить, как байт может равняться 16 битам, если он вроде как по определению 8.
Байт по определению минимально адресуемая ячейка памяти, и в эмбеде поныне есть 16- и 32-битные байты.
Не читай Прата, читай K&R или стандарт.
byte
addressable unit of data storage large enough to hold any member of the basic characterset of the execution environment
NOTE 1 It is possible to express the address of each individual byte of an object uniquely
NOTE 2 A byte is composed of a contiguous sequence of bits, the number of which is implementation-defined. The least significant bit is called thelow-order bit; the most significant bit is called thehigh-orderbit.
Обрати внимание на NOTE 1. С точки зрения си, байт в машине - это то, что минимально адресуется имплементацией си в этой машине. Т.е. char* yoba = 0; while(yoba++); пройдется по всей памяти этой машины, без скипов.
> как байт может равняться 16 битам
Дополню, что если у тебя на машине 16-битные байты, у тебя есть гораздо множество более серьезных проблемы, чем какие-то там названия (алсо, в таком случае они обычно равны машинному слову и называются словами даже в родной документации).
> по определению 8
По определению 8 в октете, но все называют октеты байтами, и это нормально.
>>66665
Лучше конечно K&R читать, в котором половина кода давно с предупреждениями собирается, новых стандартов нет, важных мелочей нет, и вообще нихуя нет, и даже ричи умер.
Ты определись, или вкатываешься в Си, не зная элементарных вещей, без которох рано думать о нюансах стандарта, или компилятор разрабатываешь.
ой бля, не ты вкатываешься
>Лучше конечно K&R читать, в котором половина кода давно с предупреждениями собирается, новых стандартов нет, важных мелочей нет, и вообще нихуя нет, и даже ричи умер.
Исторический подход в изучении вещей вообще самый правильный. Чтобы начать разбираться в политике, тебе нужно начинать с Платона и Аристотеля, а не читать их краткие содержания, или, тем более, современный учебник политологии для вузов.
В том числе помогает и то, что ты читаешь устаревшую книгу, а значит заранее настроен на то, что она 100% истиной не будет, и нужно при чтении думать головой.
Конечно, не всегда тебе хватит времени изучать какую-нибудь математику, начиная с греков. Но вот си не изучать с K&R, это совсем тупым куда-то спешащим мудаком надо быть.
> Исторический подход в изучении вещей вообще самый правильный
PL/1 выучил уже? Или хотя бы B?
Попробуй прочитать последний абзац прежде чем предлагать какую-то высосанную из пальца хуйню.
>>66658
>>66660
>>66676
> если у тебя на машине 16-битные байты, у тебя есть гораздо множество более серьезных проблемы, чем какие-то там названия
Аноны, спасибо за ответы. Вспомнил то забытое ощущение, как когда тебе всю жизнь говорили, что нельзя делить на ноль или брать квадратный корень из отрицательных чисел, а потом в какой-то момент говорят: "Забудь то, что учил в школе".
>>66700
> Но вот си не изучать с K&R, это совсем тупым куда-то спешащим мудаком надо быть.
Я не спешу, мне наоборот показалось, что раз в K&R 200 страниц, значит там многое скипнуто и не разжевано.
>не разжевано
А вы, однако, тупенький-с. Я вообще считаю, что некоторые темы противопоказано разжевывать в гуманитарном стиле. Один хуй, не вывезешь потом при таком раскладе. В K&R все дается, но чтоб это взять, надо напрячь извилины, тем самым лучше усвоив. И именно так, сука, надо писать все книги по программированию, а не всякое говно по 1000 страниц, от которого у нормального человека опускаются руки учить что-то современное.
> так, сука, надо писать все книги по программированию
И потом человек считает, что a[k] = k++; - это нормальный код. И пишет его.
Оказывается это баг, в новых версиях либы забыли добавить SDL_coremotionsensor.m в билдскрипт для гейоси.
https://bugzilla.libsdl.org/show_bug.cgi?id=4357
Я потом грепнул вывод утилиты ar и убедился что объектного файла с таким именем нет, но в репозитории есть еще xcode проект для ios в котором уже все нормально и в архиве есть SDL_coremotionsensor.o
Про откуда берется переменная я имел ввиду что если встречаю в коде что-то extern то могу ли я как-то без боли проследить по коду что "подставится" в этот символ, но как я понял простого способа нет и нужно пидорить билдскрипты в надежде понять что именно из линкующегося добавляет нужный символ. Причем с динамическими библиотеками все еще сложнее.
Надо будет тоже осилить K&R и Linkers and Loaders в придачу, а то чувствую что слабо представляю как это работает и постоянно спотыкаюсь на таких моментах.
>И потом человек считает, что a[k] = k++; - это нормальный код
Что в этом коде кажется тебе ненормальным?
>как байт может равняться 16 битам, если он вроде как по определению 8.
Ахахахаха
Определений не читал, чем байт отличается от октета не знает.
Добро пожаловать в программисты, сынок. Одним больше, одним меньше...
>>Что в этом коде кажется тебе ненормальным?
>Да ничего
Зато пришел и насрал в треде какую-то хуйню.
Когда будет, что сказать, тогда приходи, унтерменш
швитая толштота
> где взаимосвязь?
Анон предлагает читать >>66734 короткие устаревшие книги, в которых о важных вещах либо упоминается вскользь, либо не упоминается вообще. Я вспомнил распространенный подводный камень, на который часто наступают вот такие читатели K&R как он. В Прате это разжевано. И таких моментов овердохуя.
Прикрепи, пожалуйста, сам, картинку, где я ебу твою маму в рот.
Ну окей, этот конкретный пример там есть, но сколько подобных вещей туда не влезло?
Туда влезло, например, написание менедежера памяти.
Вкатываться так, чтоб со всеми подводными сразу, только долбоебы рассчитывают. Охуели вообще, хотят одну книжку прочитать и быть готовыми к написанию промышленного кода. С Сишечкой это не канает в принципе. Есть множество граней скилла, и нет смысла ставить что-то в приоритет, потому как ты один хуй никто, пока не выдрочишь несколько полных кругов по всем пунктам в течение лет - не месяцев. В начале пути равноценен любой прогресс, а K&R, имхо, дает незаменимый стартовый буст при условии, что читатель не унтерменш. А нежданчики с UB... ну хз, по-моему, опять таки, не будучи обделенным генетически, эту тему можно вскрыть с меньшим оверхедом от вторичности источников, чем оверхед от проеба вначале фундаментальных ништяков, потому что кто-то говно на стол положил и сказал, что это настольная книга. Под фундаментальными ништяками я имею ввиду все те живые знания, которые не привить разжевыванием, а лишь гениально построенным курсом "додумай сам" для ЦА, умеющей в отдачу за книгой.
хуету какую-то настрочил, лень редактировать
Более-менее так.
Если с твоей точки зрения
>листинги на полебла и разжёвываются слабовато
То твой навык отладки в уме недостаточен и нужно его развивать. Можно принтов нахуячить, если совсем все плохо.
А не искать блядь книгу, автор которой пытается заработать денег на даунах. Разжевывание программного кода в книгах - большое зло. Код самодостаточен, и если ты его читать не можешь, как ты его писать собираешься.
K&R не обломишься и целиком пройти. А что до разжевывания... ну, щас бы забраковать шедевр, пушто авторы не предсказали, как гцц на бубунте запустить, лол
По моей практике работы со стажерами, минимум это пикрил. После этого можно о чем-то разговаривать.
Что за говно справа? Почему оно мне не понадобилось? Жонглирую указателями хуем, прекрасно себя чувствую.
>a[k] = k++;
>Undefined Behavior
Схуяли вдруг там будет UB?
Ты точно ничего не напутал?
Не мог бы ты привести какие-то пруфы?
В принципе, есть стандарт. Там написано. В разделе Expressions, что ли.
Но тот анон его не читал, пересказывает по каким-то мудовым книгам, которые принимает за основополагающие.
Кто-то слышал звон, просто.
Undefined behavior выглядит так:
a[i++] = i++;
И даже ньюфаг поймёт (интуитивно), что так писать не надо.
https://www.nayuki.io/page/undefined-behavior-in-c-and-cplusplus-programs
> какой-то говносайт
Тем временем в стандарте: 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.
Чем тебе не value computation?
Давай пруф (с любого говносайта, кроме мейлача) с примером выражения типа a = i++;
Блядь, в первой строке должно было быть i в квадратных скобках.
Очевидно что речь идет об объеме знаний, как именно они получены значения не имеет, конкретные общеизвестные книжки предлагаются для ориентира.
заголовочный файл
<iframe src="https://pastebin.com/embed_iframe/wyrjWrpx" style="border:none;width:100%"></iframe>
Объясните долбоебу почему цикл при вводе нормально только первый проход делает а потом пропускает строки.
потсавь на тлефон сололеарнну или какие другие курсы, выбирай курсы на английском там абзацы не большие читаешь неаонятные слова в словаре смотришь, потом переходи на freecodecamp там курсы объемнее потихоньку нахватаешься по крайней мере читать научишься.
Хуй знает, анончик, но если у тебя Windows, то вчера я с такой же залупой столкнулся. Ломается ввод, когда читаешь char, будь то ch=getchar(), будь то scanf("%c",&ch). Пиздос какой-то. На твоем месте я бы просто не выебывался с оптимизацией puts/gets и все 4 раза проделал printf/scanf. scanf сама пробелы пропускает, так что можно обойтись без getchar.
a [ i ] = i++;
что в какой последовательности выполнится?
1. i++?
2. определение адреса a [ i ]?
3. присвоение i?
4. присвоение результата i++?
ссылку на стандарт (а не на говносайт) дать?
или сам найдешь?
Windows, там ещё мусор какой то вместо price пишется.
Убедил, лол.
Однако, я ебал такое си.
На мой взгляд, тут вообще всё очевидно и defined.
Если такие вещи неочевидны создателям компиляторов, то нахуй такие компиляторы.
Я, всё-же, думаю, что со времён K&R многое изменилось, и теперь такое должно нормально работать везде. Т.е., слева и справа будет взято i, а инкремент будет потом, после присваивания и перед точкой с запятой.
Не должно. потому что оператор присваивания не гарантирует что все, что справа от "=" будет вычислено раньше, чем все, что слева.
После некоторых размышлений и прочтения куска из K&R, вынужден согласиться.
Характерно, что на простой вопрос ты так и не ответил, специалист.
>Я, всё-же, думаю, что со времён K&R многое изменилось
Вот же ж ебаный мудак.
Думает он.
Тебе сказали русским языком: ЧИТАЙ ЕБАНЫЙ СТАНДАРТ.
А ты все думаешь
Тебе нечем
Стандарты для разработичков компиляторов и форумных аутистов. Нормальный человек просто не пишет плохо пахнущий код.
Можно ли отключить stack protector в clang только для одной конкретной функции?
Через #pragma или __attribute__ как-нибудь? Или только вырубать во всей программе?
если английский для тебя не человеческий, то ты какой-то червь-пидор с венеры
любой перевод будет ущербным. потому что согласовали все именно в английском оригинале
Точно.
Нормальный человек вообще ничего не читает. Сразу пишет. Сразу охуенный код. Стандарты для пидоров и хуесосов
Так держать!
Вроде бы нет, но ты можешь просто положить функцию в отдельный файл.
Мда, начало сентября и тред по Си внезапно и неожиданно взлетел. Интересно, с чем же это может быть связано?
Вот это ты открыл всем глаза.Мы то не знали что в си и асмо треде чаще всего сидят студенты и ебутся с лабами
Да грустно это всё. Такой мощный язык, столько всего можно на нём замутить, очень быстрый, очень производительный, очень ресурсоёмкий, можно писать очень близко к железу, при этом он максимально прост и прозрачен. А в итоге получается, что он нужен только школоте с laba1.c.
как пример я не студент и не школота, начал изучать си, хотя в свое время был курс и в том числе лабы, о которых я вообще ничего не помню.
>начал изучать си
>в свое время был курс и в том числе лабы, о которых я вообще ничего не помню
Кек, вся суть отечественных шараг.
курс был не большой, специальность все таки связанна с программирование опосредованно
Почему тогда решил вк4атиться, если твоя специальность
>связанна с программирование опосредованно
прост0))))
Нет. Я пришел к выводу, что даже если Си не самый удобный язык для всех задач, он является единственным НЕзашкварным языком.
static char ×
concat (s1, s2)
char ×s1, ×s2;
{мясо функции}
Листаю стандарт кодирования GNU, и тут такая хуйня. Это чо эта такое та? Какое то хитровыебаное определение типов у аргументов функции?
Это синтаксис из 80х
Ну мне нужен! Пишу только на нём в основном, точнее на крестах как си с классами. Только спрашивать нечего, язык-то простой.
спасибо,няш
> зачем нужен прототип, если вызываемая функция расположена в том же файле, что и вызывающая, просто чуть ниже по тексту
У Си старый однопроходной парсер, поэтому если вызываемая ниже вызывающей - компилятор о вызываемой на момент вызова еще не знает, информации о типах у него нет. Вызвать-то он может (в старых стандартах для этого всякие неявные инты есть), но ничего хорошего без прототипа не жди.
> если вызываемая функция определена выше вызывающей, все работает
А тут компилятор функцию уже распарсил, запомнил, информация о типах есть, поэтому все ок.
Поэтому чтобы избавиться от прототипов в пределах файла часто просто располагают все функции "снизу вверх" (main внизу, нужные ей функции повыше, всякая мелочь в самом начале файла, прототипы только для рекурсивных функций).
Спасибо, анончик. Добра тебе!
int count_one_bits(int n) {
int count = 0;
while (n) {
if (n & 1) { ++count; }
n >>= 1;
}
return count;
}
Задание 1) что делает этот код не запуская? 2) найти проблему в коде
Тебе кажется, что тут викторина для альтернативно одаренных?
Если ты знаешь, что в коде есть проблема, то на хера тебе знать, что этот код делает?
Вот когда исправишь проблему, приходи, мы тебе ответим, что он делает.
Кстати, если ты склонен писать иф блаблабла в одну строку, то на хуя ты там скобочки вкрячиваешь?
Какое-то особое извращение.
Что делает? Неправильно считает единицы в двоичном представлении числа. Где проблема? В том, что если старший (знаковый) бит - единица, он будет копироваться в младшие биты до бесконечности, и условие всегда будет истинным.
Я себе так мозги разминаю по 40 в неделю
ЗА ДЕНЬГИ!
А ты даже не догадался функцию переименовать.
>>> в вашем древнем языке есть?
Потому что 10-е правило Гринспена. Как ты динамическую типизацию без войдов запилишь?
Желательно, чтобы она умела раскидывать выходные данные в заданную структуру, автоматически выделяя память.
А брат не умрет?
Это для новичков на самом деле. Для программистов есть справочник Шилдта и стандарты.
C джуны вообще существуют, или все, кто профессионально пишет на c рождаются с 10-летним стажем?
ломают матрицу ещё у бати в яйцах, че хотел то?
Ребята, не стоит вскрывать эту тему. Вы молодые, шутливые, вам все легко. Это не то. Это не Чикатило и даже не архивы спецслужб. Сюда лучше не лезть. Серьезно, любой из вас будет жалеть. Лучше закройте тему и забудьте, что тут писалось. Я вполне понимаю, что данным сообщением вызову дополнительный интерес, но хочу сразу предостеречь пытливых - стоп. Остальные просто не найдут.
На самом деле, всю низкоуровневую инфраструктуру создают сущности не от мира сего, но чтоб у людишек не возникало слишком много вопросов, придумали Си, на котором что-то эдакое можно худо-бедно закосплеить и смириться, что просто не осилил.
В embedded существуют, я был им де факто, работал за еду в продуктовой электронной компании, меня выпиздили потом.
С любой нетолстой и неновой книжки, K&R там или даже прости господи Бочков-Субботин.
Тебе будет просто - си это макроассемблер (если есть в этом сомнения, включи у компилятора трансляцию C в ASM и поизучай выдачу).
В строке 6 у тебя кавычка стоит перед скобкой, а должна стоять сразу после последнего %f.
Вводить правильно так:
1 8 10
Само уравнение вводить нельзя, можно вводить только коэффициенты.
Большое спасибо за помощь) Теперь это работает. Вот только при других цифрах иногда выводит пустую строку.
Пофиксил. В строке с puts надо было поставить кавычки.
К примеру:
struct t challoc (void) {
return (struct t) malloc (sizeof(struct t) * n);
}
в мэйне после каста "поинтер = challoc ()", указатель точно не будеть указывать на NULL (т.е. типа память точно дали), но записать что-либо на его структуру нихуя не получится.
Зачем тебе это? Лепи как получается.
Code complete?
вонючее веб-чмо решило вкатиться на досуге в Сишечку. Прочитал учебник, пожонглировал указателями, хотел бы какой-нибудь проект мини запилить, чтоб вкинуть на гитхаб и порадоваться, какой он нужный и скачиваемый. Что можно запилить? За полвека существования С разве не написали на нём все либы, какие вообще можно представить только?
напиши игру на SDL
Хз что за у тебя компилятор, но в майне можно ничего не возращать даже если он инт. А можно вообще поставить войд)) и оно скомпилируется. Всё там работает, перепроверь что правильно скопировал код.
Что-то не припомню глобальных проблем. Даже если они и есть, то только вначале. Вкатился в среду - идешь по книжечке и радуешься жизни. Эти минутки гуглежа ни в какое сравнение с часами гуглежа для неумеющих мыслить, кто начал Си с современной говнолитературы.
ПыСы сам уже с добрых полгода под Linux сидел на момент вката в Си. Ибо нехуй. Там в конце еще интересное про системные вызовы UNIX, read/write, brk/sbrk, хуё/моё.
Не долго. Достаточно выучить язык, потом освоить нейросетки, потом вывод графики и можно начинать пробовать. Язык осваивается за три дня, нейросетки за день, а графика и прочий гуй за два, плюс еще день на запил прототипа. Неделя всего.
Это если ты сеньёр-помидор, который уже всё повидал и новые технологии осиливаешь с пол-пинка. У новичка же уйдут годы.
Бда бда бда, а потом у таких мегамозгов через допустим все работает и дальше примитивного прототипа не уходит.
>(см. 1473028)
Эмм, я рофлил вообще-то. А за всамделишную ситуацию не шарю.
мимо студент-не-бейте-лучше-абассыте
>автокоррекция
Сидит на борде со смартфона, стало быть, не достаточно уважает наш тред, чтоб соблюдать культуру капчевания за настольным ПК. Мы ему не фастфуд! Обоссым его!
Ахаха, отошёл от сычевальни на кровать, и сразу попался.
Двачеры, ответьте: есть ли компилятор Си для Sublime Text 3? Если есть, как его установить?
А просто через gcc собирать, не? Честно говоря не шарю за этот редактор, но обычно в подобных редакторах можно открыть консоль, и собирать через консоль с помощью gcc.
Сердце обливается кровью за любимый тредик...
Есть тут спецы по pthread?
Правильный ли это код для корректной работы pthread_cond?
Может ли тут случится deadlock?
>спецы по pthread
Сап двач, в моей мухосрани нет такой вакансии, переквалифицироваться западло, еот бросила, реквестирую способы ркн.
Спасибо большое, всё работает!
>функция
Алё, DIV/IDIV оставляет целую часть в AX, а остаток - в DX. Если с float, то или кастами, или floor().
>функция
Алё, DIV/IDIV оставляет целую часть в AX, а остаток - в DX. Если с float, то или кастуешь в int (поддерживается на уровне архитектуры), или floor().
сука Абу, нахуй косплеить возможность отмены отправки, когда оно не працюет?!!
Добрый день.
У меня возникло пару вопросов.
1) Как оформлять библиотеку в Си?
В .c файле писать тела функций, а в .h файле - заголовки, переменные, массивы и макросы, верно?
А если сделать библиотеку полностью в .h файле, не будет ли это быдлокодом?
1)Зачем вообще нужны inline функции(фактически макросы).
Увеличить быстродействие? Но пару дополнительных тактов на вызов никак особо не повлияют на быстродействие, если там не частоты, сравнимые с частотой процессора.
Только больше проблем доставляет тем, что их нужно объявлять только в .h файле, как макрос, и увеличивает вес программы.
>полностью в .h файле
Охуенно ты придумал. Вот у тебя скомпилированы .o, использующие одну библиотеку. Функции же библиотеки не находятся в отдельном .o, а продублированы в каждом из твоих .o. И откуда линкеру-то, блядь, знать, что они идентичны, и какие копии можно выбросить?
>те же макросы
Нет, макросы обрабатывает препроцессор, который без задней мысли тупо заменяет текст(текст1,текст2,...) на то, что в дефайне, подставляя содержимое скобок. Ему похуй на типы - это уже проблемы конпелятора, которому скормили развернутые макросы. inline же позволяет компилятору не делать call/ret, полностью сохраняя при этом поведение, определенное для вызова функции, копируя что надо, и т.д. и т.п.
(uint64_t)vptr++ компилируется как addq $1
(uint64_t)(vptr++) компилируется как addq $1
(uint64_t)(vptr)++ компилируется как addq $1
Как писать-то? Вариант который использую я (типа vptr += 8, например) кажется мне некрасивым.
Звездочки сожрало. В приведении типа, где (uint64_t) конечно же я имел ввиду указатель на 64 битное беззнаковое
Да, с точки зрения компиляции есть, так как по стандарту выражение рассматривается справа налево, скобки меняют этот приоритет.
Дополню. Лично я, когда непроходимо просто инкрементировать на 1, пишу так:
(uint64_t)x++;
Если больше чем на единицу, то:
(uint64_t)(x + 3);
В данном случае мне нужно инкрементировать УКАЗАТЕЛЬ, а не число.
Да, это так. Но в данном случае, как при компиляции может поменяться выражение?
Или речь не только об сложении?
Ну так, если я инкрементирую указатель на uint16_t, к примеру, то в памяти значение куда указывает указатель должно сместиться на 2 байта, а в случае указателя на uint64_t на 8 байт.
Вот я и спросил, можно ли это как-то написать в случае в void-указателем, или только так как я и делаю сейчас - прибавлять sizeof(type)?
Моча все звездочки трет, но там везде указатели.
void нельзя инкрементить\декрементить по стандартну. Там где это можно (данное расширение в вижуал студии есть точно) - там void инкрементится как char*
Хз,как ты эти функции вызываешь и где...
Спасибо за ответ
Ну это если только тебе нужно инкриментировать на размер какого то типа. А если нужно инкриминтировать на n размеров какого либо типа?
vptr += sizeof(uint16_t) * n; // Я не осилил адресную арифметику. Извините.
исправил, не благодари
Че это? Компилятор раскроет sizeof(uint16_t) как 2 и умножит его на n , если это неизвестная то в рантайме умножит, если я его введу в виде константы то во время компиляции.
vptr += sizeof(uint16_t) * 6 раскрывается как addq $12
Ну чорт знает, операция умножения вродь больше тактов занимает, да и постоянный вызов sizeof(), ну хз хз.
Так там не будет умножения если n является константной. Sizeof точно так же на этапе компиляции раскрывается (или препроцессора? Не уверен), это не вызов.
А если n не является константой, то там в любом случае будет runtime вычисление
Ааа, кажись понял, ты про то, что компилятор эту переменную еще в препроцессоре посчитает? Ну да... это если обе константы.
А в Runtime вычислении, сложение выиграет sizeof()*n
Потому-что в случае если на месте n константа, то компилятор производит вычисления во время компиляции, так как они всегда будут неизменны.
Пример:
x = 6 2. Компилятору нет смысла это компилировать как sall $1 (сдвиг влево на 1), или тем более как mul $2 (умножение на 2), потому-что значение можно вычислить во время компиляции.
Так и в случае
vptr += sizeof(uint16_t) 6
Компилятор из этого сделает
vptr += 12
Это как же ты в runtime неизвестное количество n посчитаешь без умножения?
Алсо, на godbolt проверил - что vptr += sizeof(uint16_t) n, что vptr = (uint16_t) + n компилируются одинаково.
Ой бля, точно, cast же rvalue...
Это копия, сохраненная 21 октября 2019 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.