Вы видите копию треда, сохраненную 22 июня 2021 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
Пожалуйста, пользуйтесь https://ideone.com/ https://wandbox.org/ или 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 (драфт)
- Черновик стандарта ISO/IEC 9899:202x (C2x): http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2479.pdf (декабрь 2020, с диффами)
- Последний черновик ISO/IEC 9899:202x (C2x): http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2596.pdf (октябрь)
Чем компилировать:
- Очевидный GCC.
- clang: оче годно, батя рекомендует.
- Intel C++ Compiler: оптимизации, тысячи их.
- Visual Studio 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://github.com/kozross/awesome-c
Онлайн-утилиты:
- https://godbolt.org/ - Compiler Explorer позволяет посмотреть выхлоп компиляторов для введенного куска кода (больше полусотни разных версий компиляторов).
- http://cdecl.org/ - С Gibberish ↔ English помогает читать сложные сишные декларации.
Прошлые треды:
- №65: http://arhivach.net/thread/637465/
- №66: http://arhivach.net/thread/637469/
- №67: http://arhivach.net/thread/667170/ >>1904954 (OP)
Первыйнах
signal(SIGSEGV, sosatб_handler)
char istr = strstr("foo bar 123", "bar");
printf("istr pointer: %.s, 3, istr);
В веб-эмуляторе всё на ура. В реале - через раз пашет, даже очень редко; при этом ни ошибки, ничего: просто часть текста и никакого результата по формату. Всё остальное работает штатно.
Что за херня? У меня уже крыша едет.
Ты забыл двойной кавычкой закрыть, странно, что она у тебя в вебе скомпилировалась, скорее всего бракованный компилятор под компотом, попробуй накатить Linux, там вроде годные компиляторы под компотом
Агент шишки-ёлочные-игрушки передаёт, что все в порядке, отставьте преждевременную мобилизацию эскадр
)))
>переменная N
прасти братиш, я обосрался. вот тебе как нужна порометризировать форматированый аутпут:
снпринтфэ(пук, "%%.%us", N);
принфэ(пук, истр);
А то тут какая-то клоунада.
ну ставь сайз вторым аргументом я ебу ващь, ты такой конч чо не можешь загуглить в консоле "ман снпринтфэ"?.
я гашиш не курю если чо
Кое-как вкатился на поз. data engineer, уже почти накапал год опыта
Собственно вопрос, мне нравится сфера embedded, стоит ли перекатываться? Учитывается ли мой текущий опыт хоть как-то? Есть гайды по развитию в данном направление? Всякие там Roadmap'ы C++ обязателен? Какого уровня хватит для начала работы ждуном?
Гуглить умею, не тупой, просто хочется послушать мнения и советов анонов, которые уже разрабатывают под железки
Нет
Нет не умер, просто на дваче мало кто уже сидит, а еще тут есть пидор который всех банит
Нет, в твоем случае будет вызвана функция hide_signal, даже если она будет состоять из одной инструкции выхода из процедуры. SIG_IGN это определенный константный адрес (например, 1), вызвав функцию signal с таким аргументом ось пометит сигнал как игнорируемый (если возможно) и не будет передавать управление никакому коду из пространства пользователя.
Мелкоборды, конфочки.
Планирую вкатится в си, до этого дел с программированием не имел....
Если Прата окажется говном - посоветуйте чтива по пуре си пожалуйста...
И еще, что можно будет прочитать после Праты?
>до этого дел с программированием не имел
Тогда лучше начни с видеуроков на тему c/c++/c# на ютубе, с полного нуля в прату не вкатишься.
бля, бля.
знакомый программист посоветовал именно Прату новичку..
Я уже прочитал первую и вторую главу и сделал упражнения(по второй, в первой там хуйня а не упражнение) меня пронесло чтоли? я теперь Довакин в мире программистов?
Ну, если доходит, то ок.
Дак и читай прату, единственный нормальный учебник, прочитаешь будешь хоть ориентироваться уверенно. А как Прату прочитаешь, советую не переходить к более углубленным учебникам, а хорошо попрактиковаться, сделай какую нибудь игры на файлов 10-15 с применением различных либ. И поверь, практика даёт такой ахуенеший буст скиллу, который никакие книги тебе не дадут, но про них тоже забывать не стоит.
Я бы этот справочник нихуя не понял на вкате. Да и упражнений там нет.
ыа трусы ыаааа )))))0)
понял, бля... практика звучит сейчас страшно(учитывая то что я прочитал всего 2 главы) в том плане что это будет трудно, но отступать не хочу и буду пробовать пока пальцы не отпадут
спасибо, анон
Цепляешься отладчиком к нужному процессу. Профит. По крайней мере в gdb так можно, думаю и VS так должна уметь.
Чего? Хоть Си и ущербен, но придумывать какой-то костыльный нейм манглинг, учитывая типы это было бы суперплохо для такого приближённого к машинам языка как Си. В том-то и дело, что написал функцию на Си и можешь вызвать её из ассемблера и наоборот.
У меня вопрос - нужна ли математика для программирования на СИ?
И просьба - посоветуйте курсы на ютубе на русском желательно.
Да, нужна, матан, функан, линейная алгебра и дискретка - это минимум для условного джуна, дальше идёт теория типов и гомология, без них любой хардварщик и яйца выеденного не стоит. По курсам и по книгам ты этого никогда не осилишь, по первым потому что слишком мало инфы, по вторым не хватит усидчивости и практики. Так что для этого нужно идти в вуз на 5 лет, иначе дальше хелоу ворлд не продвинешься.
У меня есть учебник по гомоморфофобии, подойдёт? Я смогу по нему вкатиться в разработку на Си?
Надо проконсультироваться у гомоморфофобоведов.
Тимофея Хирьянова на ютубе канал посмотри у него есть по си лекции.
А то и два.
Если что вывести нужно первый и последний элемет, а также длинну оставшихся элементов между ними.
Да, все правильно.
>>1966594
Чуть не подавился, благо что сразу понял, что ты имеешь ввиду.
>>1966512
Общение с пастой иногда полезно, помогает выявить неочевидные вещи в очевидных.
>>1966018
Не просто читай главы, записывай, стенография и т.д Там дается хороший бэкграунд по компьютерной науке, хоть и немного. В основном всё нужное покрывается по мере надобности. Я щас на 16 главе, сегодня 4 часа её читал. Уже пишу игрули и прочее, смотрю на другие языки как на игрушки.
Еще заметил, что на Си приятней писать, чем на любом другом языке, не понимаю почему, ведь этот язык сложнее.
Чего?
Какие-то. Берешь и цепляешься. Быстро и четко. Твердо и осторожно.
Тыкаю микроконтроллер. Экран в общем то. И возникла следующая проблема.
Есть функция которая отправляет строку на экран. Пусть будет LCD_send()
Но она отправляет только строку, а мне нужно что бы она отправляла все что мне захочется. Насколько я понял для этого нужно предварительно конвертировать данные в строку. Для этого я использую sprintf(). С ним разобрался все удобно. Но получается лишняя ебала с конвертацией. По этому хочется как то все это обьединить. Хочется получить что то вида:
void LCD_print(???, ???)
{
char buff[100];
sprintf(buff, ???, ???);
LCD_send(buff);
}
Что бы в итоге рабочий вариант был напримет такой:
LCD_print("%d", 10);
Надеюсь поняли что я собираюсь сделать. Так вот не врублюсь как передать то, что обозначено вопросами. Может ссылки хуилки, указатели еще какая то поебень. Тупой пока.
Или можно как то вообще по другому реализовать мою задачу хуй знает.
Получится так что ле?:
void LCD_print(char , ...)
{
char buff[100];
sprintf(buff, char , ...);
LCD_send(buff);
}
Не, сам вижу что хуйню какую то написал.
Анон выручай. Вижу что там указатель, но хуй знает как определить на что он указывает. С троеточиями вообще в первый раз сталкиваюсь.
Кажется разобрался.
void LCD_print(char* format, ...)
{
char buff[128];
va_list args;
va_start (args, format);
vsprintf(buff, format, args);
lcd_send_string(buff);
va_end (args);
}
Вот это работает вроде как. Не до конца вдуплился что за va_list и как он работает. Насколько я понимаю это возможность впихивать разные параметры вместо определения одного. Но хуй знает. Буду читать дальше.
В любом случае спасибо анон что намекнул где искать. Гугл на закрос "троеточие СИ" начал выдавать что то осмысленное из того что меня интересовало.
Вроде я всё более менее понимаю в самом С, но когда дело доходит до указателей на функции и прочего пиздеца, или указателей на указатель (зачем это вообще существует), у меня немного не хватает знаний кажесят.
А еще какие-нибудь есть книги желательно на русском. Хоть я английски и знаю но читать на нём тяжко по Си программированию более продвинутому, именно стиль и приёмы, хорошие практики того как пилякать код на нём?
>Гугл на закрос "троеточие СИ"
Гугли Variadic functions
>vsprintf(buff, format, args);
И на будущее, используй лучше vsnprintf(), особенно если пердолишься с микрухами. Для ограничения максимальной длинны форматируемой строки.
А также, если на ARM пишешь, то можешь использовать _vsnprintf() когда тебе не нужно выводить вещественные числа. Сэкономишь дохуя места в памяти.
Че ты смехуечки кидаешь, уебище?
Сам понял что спросил?
Нет не прохожу.
Более менее в финтаксисе разобрался но одну вещь не понял.
Когдау нас есть указатель на данные это ещё более менее понятно, но когда у нас есть указательно на ФУНКЦИЮ я немного не понимаю, как и где в указателе на функцию указывается какие данные функция принимает и что возвращает, а также чем технически является тип void* и его свойства. Это в его книге есть?
В дочернем процессе scanf как будто падает в какой-то бесконечный цикл и на нём всё зависает, однако с ReadFile всё нормально, но ReadFile может считать только чары, а мне инты нужны. Если попытаться в scanf принять не число, то поведение как при обычном консольном вводе.
parent http://cpp.sh/2usoa
child http://cpp.sh/5calw
Помогите, я в отчаянии. Нужно сделать такое именно под виндо, линуксоиды идут лесом.
Указатель на функцию объявляется так же, как функция, только слева от имени указателя звезда и все это в скобках:
int main(int, char@@);
int (@ptr)(int, char@@) = main;
Да, это я уже понял. по сути такая функция может использоватьтся как переопределяемый интерфейс. просто не понятно КАК это работает и какие у этого метода свойства
> как
Просто ячейка памяти, где лежит адрес функции. Содержимое можно менять - получается как бы функция с произвольной реализацией.
Ну хорошо, а какие возможности у C с танцеванием вокруг этого, функции будут работать ТОЛЬКО если их сигнатуры (принимаемые параметры и возвращаемое значение) одинаковы или тут есть некоторая свобода?
Можешь засунуть туда адрес функции другого типа. Так иногда делают. Что будет происходить - смотри ассемблер. Например, указатель типа void (@)(), a ты засунул туда struct bigstruct f(). Она упадёт при вызове, т.к. большие структуры возвращаются через скрытый аргумент, но в нем будет мусор .
>Не просто читай главы, записывай, стенография и т.д Там дается хороший бэкграунд по компьютерной науке, хоть и немного. В основном всё нужное покрывается по мере надобности. Я щас на 16 главе, сегодня 4 часа её читал. Уже пишу игрули и прочее, смотрю на другие языки как на игрушки.
Еще заметил, что на Си приятней писать, чем на любом другом языке, не понимаю почему, ведь этот язык сложнее.
Не, ну я это делаю. Трудные темы(понятия) я конспектирую и гляжу на досуге
Хорошо пояснил, я всё понял, благодарствую
У Праты всё расписано детально.
Указатель на функцию указывает на начало функции, где она находится, пространство в памяти т.к у неё есть адрес как и у любого элемента, а еще у неё есть возвращаемый тип.
Указатель на функцию используется в основном как аргумент другой функции, т.е ты говоришь функции какую использовать функцию.
Т.е представляем, что функция это такая же нормальная переменная как и все -
int sqrt(int number);
Тут у нас виден тип, имя функции, и параметр который передается. Мы берём и создаем соответствующий указатель.
int (ptr)(int number);
Всё должно совпадать с оригинальной, ибо компилятору нужно знать, с какой памятью работать, и какие значения принимает функция. Как у любой другой переменной, имя функции это её адрес. Поэтому мы можем взять прошлую декларацию -
ptr = sqrt;
И присвоить функцию указателю, чтобы использовать её в дальнейшем.
ptr(12); или (ptr)(12) тоже самое что и sqrt(12); Но использовать можешь что хочешь, потом поймешь зачем разные синтаксисы.
(ptr)(12) это помечает, что ты используешь указатель. Где-то это надо, где-то нет.
В некоторых языках есть такая реализация (если хочешь можешь попробовать сам написать, но для этого знания малока нужны) как функция где перебирают массивы и делают над ними операции с указанной в параметрах функции, на Си это вот так может выглядеть:
void array_map(void (ptr)(void), void array, int n);
Тут говоря про указатель void , это означает нулевой указатель, т.е он может указывать на какой угодно тип, но ему нужно динамически выделить память. Т.е передаем в параметры любую функцию которую будем использовать, выделяем память функции соответствующего типа массива и запускаем цикл, в котором запускаем указатель, на любую функцию.
Если непонятно, посмотри как работает qsort().
Мне сайт один нравится, там всё объясняется:
https://www.geeksforgeeks.org/function-pointer-in-c/
https://www.geeksforgeeks.org/void-pointer-c-cpp/
Забыл про разметку, понятнооо
ОО кайф, я обожаю когда прямо так подробно хуячат текст, моментально в голове всё по полочкам раскладывается прямо ух бля. Прату почитаю раз ты говоришь что расписано детально. Еще раз благодарю за такое мощное пояснение
Ну ей богу.
Ты должен знать, что программа на C компилируется в машинный код, и исполняется именно в этом виде в реалиях архитектуры компьютера.
Т.е. в этих реалиях есть процессор(ы) со своей системой команд, регистрами. Есть память, есть другие внешние устройства с портами ввода-вывода.
И вот в этих реалиях, указатели по сути своей содержат адреса памяти. И в этой же памяти лежат данные и код программы. Указатель может быть на данные (скажем int), может быть на функцию.
Если на данные, то в указателе содержится адрес, где эти данные лежат в памяти. Если на функцию, в указателе лежит адрес, где в памяти лежит код этой функции.
В самом указателе ничего не указывается, какие данные функция принимает или возвращает.
Для этого, у указателя есть тип. А тип, как известно, это чисто такое явление, фигурирующее в исходниках программы. Оно не проникает в машинный код.
И вот у указателя на фунцию есть тип, показывающий какие у функции аргументы и возвращаемое значение. А так, во время исполнения программы, это всё тот же адрес памяти.
Ещё, сами указатели также являются данными. А значит, они тоже лежат в памяти, и у них есть адреса. Т.е. можно образовать указатель на указатель, который представляет собой адрес, где лежит другой адрес чего-либо в памяти.
Тип void же - это просто указатель (т.е. адрес в памяти), про который неизвестно на что же именно он указывает.
Это дело программиста - проследить, что указатели void используются без ошибок. Их всегда кастуют в нужный тип. И можно например указатель float перекастовать в int.
Что из этого получится - тебе, как программисту виднее. Язык такое позволяет, а дальше дело твоё.
Ещё есть такой момент. Существуют архитектуры компьютеров, где данные и код программы лежат в разных адресных пространствах. Это т.н. Гарвардская архитектура.
Это даёт свои тонкости. Например, там может получиться, что по одному и тому же адресу в разных адресных пространствах лежит и код функции какой-нибудь, и данные какие-нибудь.
>Тут говоря про указатель void , это означает нулевой указатель, т.е он может указывать на какой угодно тип, но ему нужно динамически выделить память.
Ты, сука, бред не говори, и не путай человека, коли не знаешь.
Указатели void, это именно то, что я написал выше, и никак иначе. Он нихуя не указывает на какой угодно тип, а просто указывает неизвестно на что.
И как их использовать - решать тебе. Выделять там память динамически, хуически, или ещё как. Как хочешь, так и поступай.
Можешь взять void* у глобальной переменной, если хочется.
Ну ей богу.
Ты должен знать, что программа на C компилируется в машинный код, и исполняется именно в этом виде в реалиях архитектуры компьютера.
Т.е. в этих реалиях есть процессор(ы) со своей системой команд, регистрами. Есть память, есть другие внешние устройства с портами ввода-вывода.
И вот в этих реалиях, указатели по сути своей содержат адреса памяти. И в этой же памяти лежат данные и код программы. Указатель может быть на данные (скажем int), может быть на функцию.
Если на данные, то в указателе содержится адрес, где эти данные лежат в памяти. Если на функцию, в указателе лежит адрес, где в памяти лежит код этой функции.
В самом указателе ничего не указывается, какие данные функция принимает или возвращает.
Для этого, у указателя есть тип. А тип, как известно, это чисто такое явление, фигурирующее в исходниках программы. Оно не проникает в машинный код.
И вот у указателя на фунцию есть тип, показывающий какие у функции аргументы и возвращаемое значение. А так, во время исполнения программы, это всё тот же адрес памяти.
Ещё, сами указатели также являются данными. А значит, они тоже лежат в памяти, и у них есть адреса. Т.е. можно образовать указатель на указатель, который представляет собой адрес, где лежит другой адрес чего-либо в памяти.
Тип void же - это просто указатель (т.е. адрес в памяти), про который неизвестно на что же именно он указывает.
Это дело программиста - проследить, что указатели void используются без ошибок. Их всегда кастуют в нужный тип. И можно например указатель float перекастовать в int.
Что из этого получится - тебе, как программисту виднее. Язык такое позволяет, а дальше дело твоё.
Ещё есть такой момент. Существуют архитектуры компьютеров, где данные и код программы лежат в разных адресных пространствах. Это т.н. Гарвардская архитектура.
Это даёт свои тонкости. Например, там может получиться, что по одному и тому же адресу в разных адресных пространствах лежит и код функции какой-нибудь, и данные какие-нибудь.
>Тут говоря про указатель void , это означает нулевой указатель, т.е он может указывать на какой угодно тип, но ему нужно динамически выделить память.
Ты, сука, бред не говори, и не путай человека, коли не знаешь.
Указатели void, это именно то, что я написал выше, и никак иначе. Он нихуя не указывает на какой угодно тип, а просто указывает неизвестно на что.
И как их использовать - решать тебе. Выделять там память динамически, хуически, или ещё как. Как хочешь, так и поступай.
Можешь взять void* у глобальной переменной, если хочется.
Ох сука, как же эта разметка заебала. Всё поехало из-за звёздочек.
Заебись пояснил, пасибо
>Можешь взять void* у глобальной переменной, если хочется.
А это что значит?
То и значит. Взяв указатель на void от глобальной переменной, ты, очевидно, получаешь в указателе адрес, где эта переменная лежит в памяти.
>Можешь взять void× у глобальной переменной, если хочется.
А можно создать указатель типа воид? Или имел ввиду взять адрес и привести к типу void×?
Это что, троллинг тупостью? Попробуй разобраться в этом вопросе самостоятельно.
Хуйню несёшь.
Никогда не видел такого сложного пояснения простого концепта, еще и запутал ненужной информацией. Мда.
>Тут говоря про указатель void , это означает нулевой указатель, т.е он может указывать на какой угодно тип, но ему нужно динамически выделить память.
>Он нихуя не указывает на какой угодно тип, а просто указывает неизвестно на что.
Ну я не говорил такого. Читай внимательней, а еще я ссылки приложил для подробных пояснений, там это первым пунктом говорят.
А еще соглашусь с анонами выше, ты много лишнего написал.
>пук
Маня, если тебе везде мерещаться тролли - мне тебя жаль. Складывается впечатление что ты реально контуженный , обиженный жизнью имбицил. Могу тебе и в глаза сказать, готов приехать послушать?)) Вся та хуйня тобою написанное это простое пиздабольство, рембо ты комнатный)) от того что ты много написал, жизнь твоя лучше не станет)) пиздеть не мешки ворочить, много вас таких по весне оттаяло)) Про таких как ты говорят: Мама не хотела, папа не старался) Вникай в моё послание тебе постарайся проанализировать и сделать выводы для себя)
Это опять я.
Я не случайно заикнулся про гарвардскую архитектуру.
Сейчас вот порылся, навёл справки. У меня в закоулках памяти действительно что-то такое было.
Дело в том, что стандартом ISO C запрещено присвоение указателя на функцию указателю на void.
Это как раз связано с этой архитектурой.
Вот смотрите
https://stackoverflow.com/questions/36645660/why-cant-i-cast-a-function-pointer-to-void
О да! Сначала мне говорят "заебись пояснил", а теперь "много воды спизданул".
Коль читаешь по слогам, и ничего не понимаешь - нехуй на других проецировать.
Хуя у тебя проблемы с эго, ебачок.
В вопросе чувак кастит указатель на функцию на простой нулевой указатель. Кому это надо бля? Причем тут архитектуры, мозгоеб?
тут несколько человек общаются с тобой, тот кто говорил что заебись пояяснил уже ушел
Неужели я это не понимаю? Мы тут сейчас просто выясняем кто кого перетроллит :)
Эээ я ни с кем не спорил просто помог чуваку понять эти элементарные вещи. Я хз что там за шизойд на меня напал.
Звонишь в POSIX, спрашиваешь.
Маняпроекции ммм
>Назовите все способы узнать длину файла в Posix.
Это такие вопросы на собеседованиях дают?
Если б меня такое спросили про Windows, я бы сказал что в WinAPI есть различные системные вызовы. Среди них должен быть и тот, позволяющий узнать длину файла. Когда мне это понадобится в коде, я просто открываю документацию и выясняю этот вопрос.
Я posix не знаю и как там узнать длину файла в душе не ебу.
Может, команда ls позволяет вывести название файла и его размер. Однако она все равно должна вызывать какие-то соответствующие системные вызовы, к которым всё сводится.
Вообще, нахуй на зубок знать этот posix, эти API? Берёшь доки и читаешь.
По продаже файлов, очевидно. Но вообще они стандартные, самые распространенные - под А4, т.е. размер 21 на 27 см.
Это ты про себя, да?
Ну, stat и open+lseek. Наверняка, ещё есть, нормальных больше не знаю.
>Не знаю, туда ли я обращаюсь, но попробуем. Недавно увидел вебмку с демкой на спектруме и задался вопросом. Если ли тут аноны, которые пишут/писали демки? Можете гайдов подкинуть или других материалов. Просто для меня это темный лес.
БРАТЬЯ СЛОВЯНЕ ПОМОГИТЕ
Значит она глобальная и в другой единице трансляции.
Стоит начать с тырпрайза, потом идти байтослесарем.
Ищи на сайте олдгеймс, ещё в игромании вроде была статья лет 10 назад или раньше, и на хабре тоже.
Гугли демосцены. не демки.
Arduino? Arduino. Поиграться со светодиодиками, датчиками, придумать себе какой-нибудь проектик по управлению чем-то. Учиться только на практике, никаких блять книг на 1000 страниц. Там С++ хибару запилили над обычным AVR контроллером. Инфы в инете полно. Но держи в уме что это игрушка. Когда станет тесно, переходить к STM32 на бибилотеке HAL. Отладочные платы nucleo или bluepill. Там уже можно "Инсайдерское руководство по STM" почитывать, что бы понимать как работает ядро и не писать как пхпшник. Так же советую статьи istarik.
Ну а там уже можно и регистрами немного преисполниться, если оно тебе нафиг надо, на низкоуровневых либах типа LL (SPL скоро фсё, но деды на проде еще 100500 лет будут юзать).
>Тип void же - это просто указатель (т.е. адрес в памяти), про который неизвестно на что же именно он указывает.
Тип void это не указатель и не адрес в памяти долбоеб. Это тип который не имеет памяти, или информации.
>Это дело программиста - проследить, что указатели void используются без ошибок. Их всегда кастуют в нужный тип. И можно например указатель float перекастовать в int.
Нихуя, я могу не кастовать и присвоить указатель на него и нихуя не будет.
>Существуют архитектуры компьютеров
Они нахуй никому не нужны.
>Тут говоря про указатель void , это означает нулевой указатель, т.е он может указывать на какой угодно тип, но ему нужно динамически выделить память.
Можно не выделять.
>Он нихуя не указывает на какой угодно тип, а просто указывает неизвестно на что.
Приебался к терминологий хотя априори они не нужны для других целей. В общем долбоеб садись, тройка.
Хуета питушки, можно присваивать чо угодно в ваших маня-байтах, дебичи. Только вот прогрмма работает с данными, а не байтами, и по этому переводят всякие s_int u_int суммированием половины регистра
ну короче было 129 битов записано(+1 бит = 1), тут мы поменяли указатель и потекла подлива ведь нужно мне теперь отгрузить не 129 дылдаков коней, а уже ?? хз короче
Давай еще раскажи что нумерация(порядок) массивов у тебя с ноля начинается, а нет не начинается, индекс может, а вот нумерация врядли, может даже не быть нумерации, плак-плак. Вообщем обтекай, лох-пидр.
Прикинь, 0xFF0011 вообще нехуя не значит вне контекста и то что ты ответишь на 2+2=Залупа никому не нужно
Ну как это противоречит моему утверждению про присваивание любого типа нулевому указателю?
(И вообще много хуйни с плюсов пришло, но это не значит что свойства энных такие же и в Си)
>>1976112
Ну для твоего контекста эта хуйня что-то будет значить 100% иначе нахуй тебе эта рандомная цифра? Байтоебля есть, вкурсах?
>>1976110
Ну извини что я тебя обидел словом шизик, шизик, хватит это проецировать на меня. Лечиться тебе надо, а не мне.
На парад пойдем
Ничего. Препроцессор первый. Он потому и PREпроцессор.
Но возможны нюансы с прекомпилированными хидерами, которую поддерживают некоторые компиляторы.
Где ты такой вопрос нашёл? Тащи препода сюда - сейчас мы ему объясним где он не прав.
самое интересное для начала это сокеты и IPC
Попробуй BMP файл создать из кода.
Содержимое для начала рандомом, затем градиентом.
Задача простая, но наглядная. Заодно и кросспалтферменная - там хватит только open, write, close и чистый Си. Будет работать абсолютно на любой системе.
<thread1>
sem_wait(&sem);
....
<thread2>
sem_post(&sem);
sem_destroy(&sem);
...
Подумай сам, что будет если семафор не в ожидании был, в thread, которому ты сигналишь, во время sem_post был занят какими-то делами. Потом он попадает на освобождённый семафор и в лучшем случае вернёт ошибку, а в худешем упадёт.
Когда я изучал этот язык, я ничего не делал. Если хочешь чего-то поделать, можешь, например, написать кодирование uint64_t, int64_t (со знаком) по протобаферовской схемке (https://developers.google.com/protocol-buffers/docs/encoding) в переменное число байтов, выше советуют сокеты, можешь написать клиент для dns по udp. Советую не лезть во всякие ipc, треды там всякие, когда чуть обрастёшь щетиной, отправляйся изучать, как работает комплюктер/ос.
Ор, взял на вооружение :D
Хэш-таблицу и бинарный хип. Это нужно всегда.
Cделай программу которая будет принимать файлик как ввод и брать из него слова и заносить в другой файлик как отдельные в структуру из которой можно будет их брать. И при этом в файлик будет заноситься всё больше и больше структур с разных файлов.
В процессе пиши заголовочный файл и добавляй туда разные функции которые можно будет использовать в будущем для вывода данных с файлов. Постарайся использовать макросы для этого и функции и typedef декларации.
Cделай программу которая будет принимать файлик как ввод и брать из него слова и заносить в другой файлик как отдельные в структуру из которой можно будет их брать. И при этом в файлик будет заноситься всё больше и больше структур с разных файлов.
В процессе пиши заголовочный файл и добавляй туда разные функции которые можно будет использовать в будущем для вывода данных с файлов. Постарайся использовать макросы для этого и функции и typedef декларации.
Программа проходит 3 этапа перед предобработкой. Компилятор сначала берет заменяет все комментарии на пробел, а так же все \ и символы новой строки, а так-же приводит всё в порядок согласно кодировке. Позже начинается уже сама предобработка.
Это же форум мейл.сру с ответами
Точнее, 23 года между подходами.
А получилось так - грузил картинку из файла на стек и скармливал её в XCreateImage. А по выводу на экран видел странные артефакты в виде цветных точек внизу картинки. Тогда вставил между загрузкой картинки и выводом её на экран функцию, в которой создал локальный массив на несколько килобайт, и забил его 0x77. И при выводе картинки появилась серая полоса. Затем поэксперементировал с XCreatePixmap и, о чудо, артефакт не было.
И я весь счастливый и обрадованный завалился спать и всю ночь видел бредовые, но красочные сны.
Вопрос на засыпку - а вы понимаете чем отличается XImage от Pixmap?
Вот, хочу побаловаться с X11 на предмет "надрать задницу" gtk, Qt и иже с ними. Насчёт gtk особых проблем не вижу, она изначально кривая, а Qt может соснуть за счёт кроссплатформенности у кода, который на 101% заточен под X11. Не то, чтобы мне было очень интересно или какие-то перспективы, просто работа так заёбует, что неторопливо покопаться во внутренностях X11 сойдёт за отдых.
ПОгуглил
https://tronche.com/gui/x/xlib/
Но это так, примитивный справочник для вкатывания.
Библия X11, например, вот тут - https://www.x.org/docs/X11/xlib.pdf
>>1982399
Вроде разобрался, не помню как было, но сделал типа такого
void main()
{
char Array[32];
func1(Array);
}
void func1(char Array[32])
{
func2(Array);
}
void func2(char Array[32])
{
scanf(%32s, Array)
}
Хуй знает, я вроде изначально так и делал, вроде только амперсанд в scanf'e перед Array убрал, хотя вроде это ничего поменять не должно было, короче, не ебу, оно работает и я рад, хлть и не понимаю как
Господи, что ты делаешь?
Ты понимаешь что передавать массив в функцию это худшее, что можно придумать?
Срочно меняй
void func2(char Array[32])
на
void func2(char * Array)
>Ты понимаешь что передавать массив в функцию это худшее,
Почему? Энивей передается указатель.
- получает управление от bios/uefi, прочитав mbr/uef-раздел или подобное;
- на втором этапе чекаются диски и партиции на предмет программ (наверное через магические байты или адреса);
- далее, по выбору загрузка и передача управления;
неужели это напорядок сложнее какого-нибудь сишного компилятора, или я что-то пропустил?
асло насколько заебисто будет пилить такое для нюфага?
есть ли вообще смысл это делать, когда гугл уже на нулевой спойлерит гайдами по сабжу? мб лучше будет просто откопать и почитать сурцы какого-нибудь граба или лило?
Дико извиняюсь, был не прав, сейчас тоже листинги посмотрел, там при передаче массива в качестве аргумента, он на указатель распадается. Неплохая каша у меня в голове, тогда где массивы полностью копируются?
>тогда где массивы полностью копируются?
Опять же могу ошибаться, но структуры копируются со всеми полями.
>но структуры копируются со всеми полями.
Разумеется, если их передать явно, то есть f(struct s);
Сложно всё, где ты зависишь от спецификаций и того как кто-то другой что-то запилил.
Когда пилишь компилятор - весь код твой, тебе не нужно ебаться чтобы понять почему такая структура AST, или репрезентация данных.
А вот с бутлоадером надо. Плюсом ещё надо делать драйвера для фс. Уметь общаться с Ефи/биосом(это отдельный Легаси ад). На каком-то riscv/arm может и попроще, но там зачастую вообще целая цепочка из бутлоадеров используется для созданий нужной среды исполнения ядра ОС.
>Плюсом ещё надо делать драйвера для фс.
здесь же всё на уровне апи - open/read/write, не так ли?
>Уметь общаться с Ефи/биосом(это отдельный Легаси ад)
сейчас мне это представляется самым интересным хотя знаю об этом почти нихуя.
>На каком-то riscv/arm может и попроще,
бтв портабельность может стать проблемой. изначально хотел писать под x86_64, а сейчас даже не знаю. алсо думаю отладить на старом иде-диске, вместо ВМ.
>
> >Плюсом ещё надо делать драйвера для фс.
> здесь же всё на уровне апи - open/read/write, не так ли?
На этапе бутлоадера у тебя есть какая-то инфа на блоках на винте. Тебе из нее нужно собрать фс. Нужно понимать представление файлов и директорий на диске. И все это нужно написать. Или спиздить библиотеку с гитхаба
> >Уметь общаться с Ефи/биосом(это отдельный Легаси ад)
> сейчас мне это представляется самым интересным хотя знаю об этом почти нихуя.
Это легаси ад с тонной принятых нынче не логичных решений. На каком-то биосе система загружается в 16 битном реальном режиме. Нужно А20 разблокировать. И дальше более высокие режимы включать. Велика вероятность что твой код может не заработать на другом процессоре/биосе, так как баги имеют место быть.
> >На каком-то riscv/arm может и попроще,
> бтв портабельность может стать проблемой. изначально хотел писать под x86_64, а сейчас даже не знаю. алсо думаю отладить на старом иде-диске, вместо ВМ.
Однозначно.
Алсо, есть ещё несколько способов читать накопители, так что мужайся.
Пока не начнёшь писать - не поймёшь почему это задача выделенная фиолетовым.
>мб лучше будет просто откопать и почитать сурцы какого-нибудь граба или лило?
Можно, но зачем, если всё можно прочитать на osdev вики.
>>1983451
>бутлоадером
>драйвера для фс
>Уметь общаться с биосом
Запиздючился в первые 512 байтов, прочитал сектора через бивосо int13h:02, и не надо делать никакую fs.
Для ньюфага проще не ебатсо с загрузчиком, если это не сама цеаль, а ебануть мульбутовое ядро.
lilo или grub
Наглядно:
struct stack
{
struct node (pop)(struct stack sptr);
}
struct stack example_stack = malloc(sizeof(example_stack));
struct node example_node = newstack->pop(example_stack);
Если попробовать объявить pop() как static в условном stack.c (где и происходит маллок на структуру), очевидно, не срабатывает.
Стерлись астериски.
Это не плюсовый тред, бро, ты jmp по не установленому адресу делаешь.
оно как я понимаю бывают при выходе за пределы массива, однако у меня вроде все норм с этим
Там везде struct пропущен, ну тип надо проверять, чё там fread пишед. Это плюсовая параша похоже.
Блин, а когда ты будешь проверять что тебе всё верно выделилось/вернулось?
Что вернул fread? Что вернул malloc()?
И один маленький нюанс - заверни структуру в
#pragma pack(1)
хотя бы для теста.
Я допускаю что массив структур может занимать место, не равно sizeof множенное на количество.
Бля, а ты не внимательный.
ты в fread передаешь указатель на указатель. Нафига?
Всё, ошибка найдена. Исправляй первый параметр. Убирай & у первого параметра.
Вот как живут программисты в России для контраста
https://2ch.hk/po/res/42674731.html (М)
> Я допускаю что массив структур может занимать место, не равно sizeof множенное на количество.
Нет.
>Какой смысл в сисколлах типа brk, если можно автоматически выделять страницу памяти в момент первой записи?
1. можно освобождать память с конца хипа.
2. отлавливание обращений не туда.
3. brk задает нижнюю границу для автоматического роста стека.
>Как аллокаторы борятся с фрагментацией?
Если размер маленький, округляют его вверх (32,48,64...) и делят страницы на кусочки одного размера. При выделении кусков в несколько страниц никак не борются, только делают эффективную структуру для поиска свободного места.
>Можно ли вызвать много раз alloc так, чтобы максимально фрагментировать память?
Да. если потом вызвать free для каждого второго блока.
> Какая структура данных применяется для отслеживания освободившегося места?
Списки или битовые карты для кусочков внутри страниц, списки/деревья/хеши для свободных кусков в страницу и более.
А как треды живут каждый со своим стеком? По другому адресу выделяют новый стек или всё-таки переключают страницы?
Сейчас память под стеки мапится. Гугли MAP_GROWSDOWN, например. И хип также мапится, а brk считается устаревшим интерфейсом.
Вероятно зависит от реализации терминала ещё. Линукс таки да, без явного флаша не выводит пока не наберётся целая строка.
Спасибо
>Буффер вывода на винде и линуксе разный?
man setvbuf
или
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/setvbuf?view=msvc-160
Попробуй использовать - будет одинаковый.
>новичку лучше всего по Си читать справочник шилдта
http://www.iso-9899.info/wiki/Books
>Stuff that should be avoided
>Books written by Herb Schildt.
>Как у любой другой переменной, имя функции это её адрес
у тебя интовая переменная тоже равна своему указателю?
такое поведение ровно в двух случаях есть: функции мутируют в указатель на себя, массивы мутируют в указатели на первый элемент.
>И можно например указатель float перекастовать в int.
чё ты несёшь, вот чё ты несёшь. это UB
лень искать ссылку на стандарт. но это нарушение strict aliasing. К байтам объекта можно обращаться только по эффективному типу либо по типу char/unsigned char. То есть кастовать (floatж) в (charж) можно, и читать потом, в (intж) - нельзя.
А что там по union'ам?
даа что хочешь можешь писать, пока там сидит флоат, нельзя к этим байтикам обращать по интовому указателю. если там был юнион - можешь записать. второй вариант - memcpy и memmove - они копируют вместе с бантиками эффективный тип, это в стандарте написано.
-fno-strict-aliasing
>нарушение strict aliasing
Проиграл. Вместо того, чтобы починить компилятор, который своими говняными оптимизациями ломаент код, они просто придумали запрещающее маня-правило. Чисто русский подход.
Брайан В. Керниган, Деннис М. Ритчи кто из этих достойных джентльменов русский?
Твоя мамка
Посмотреть то можно, а вот понять.
>ваще похую
ну ты тут показал, что тебе конкретная версия конкретного компилятора с конкретными флагами на конкретном сорце не провела по губам, имея такую возможность. писатели компиляторов стараются без особой нужды не проучивать васянов, но зачем создавать в коде место для потенциального рандомного бага?
>Я 10 лет пилю йоба легаси на этом самострельном языке.
Я конечно люблю С++, но если ты эстет и любишь компактный исполняемый код, считая это разновидностью искусства, то у Си конкурентов как бы нет.
А когда ты пытаешься вытянуть компактность исполняемого кода в С++, то он внезапно сразу становится похож на Си - без библиотек шаблонов и с отключенными опциями компилятора исключениями.
Иначе исполняемый код растёт как на дрожжах.
От моего легаси требуется не компактность, а производительность и возможность навешивать плюшки до бесконечности. И вот тут бы с самого начала писать с шаблонами и даже классами. Хз как с производительностью, но мне почему-то кажется, это могло бы уменьшить попоболь и вносимые ошибки.
>А zig? А rust
Какие страшные слова. Ну зачем мне эти языки, если я пишу на Си и Си с плюсами? И на них я могу сделать всё. Почти всё.
>>1988902
> а производительность и возможность навешивать плюшки до бесконечности.
Так выбор алгоритма это 75%-90% производительности, а остальное это остальные факторы, начиная от прямоты рук и заканчивая вомзожностями компилятора.
Например, я обожаю ассоциативный массивы, просто оргазмирую от этой структуры данных, при этом даже на плюсах иногда отказываюсь от использования std::map и фигачу свою специализированную реализацию хеш-таблиц, заточенных под конкретную задачу.
Удивительно как сишники/плюсовики в упор не понимают проблем своего языка. Конечно, это дорого переучиваться, и зачастую незачем, но в такое отрицалово реальности уходить можно разве что из-за непомерного количества времени которое ушло на изучение плюсов. Типа никому не признаюсь что купил говно, уж очень оно дорогое было.
>в упор не понимают проблем своего языка
ну и что тебе ответить? Если не брать во внимание хитрые шаблоны, то смотря на код я знаю что сгенерирует компилятор и как будет выполняться сгенеррованный код. Знаю что и где будет оптимизировано, какие конструкции поломают оптимизацию, а где можно оптимизировать руками.
А некоторые приёмы вообще рассказывать не хочется, потому как в чистом виде know how, что позволяет иметь конкурентное преимущество.
Токсичный дед. Ну понятно.
Есть еще божественная Дишечка с ее BetterC.
согласен
setjmp/longjmp
Нет там никакого говна.
Попытался сделать выбор массива, куда надо писать, путём добавления ещё одного аргумента в макрос и функцию.
И, видимо, где-то обосрался.
Когда убираю аргумент и делаю массив фиксированным - всё работает как надо.
Я тебе сказал что делать. Выбор за тобой - ебись дальше или перепиши нормально.
Прочитай выражение которое написал. Оно реально не самое очевидное. От такого в коде лучше избавляться.
Понятно.
И как бы мне это помогло, просто интересно?
Ну вот переписал я. Но в целом это не поможет...
Я уже обрадовался: чел помог, нашёл в чём проблема - поправлю и пойду бодаться дальше, а тут ему не нравится написание... БЛЯДЬ!
https://onlinegdb.com/SkvVhB2Hd
>countof(buf)
>(sizeof(array) / sizeof(array[0]))
Ты в функцию передал уже не массив, а только указатель.
Это намек что ты пишешь трудночитаемое говно. Если левый созерцатель не смог понять что у тебя происходит - вряд ли и ты понимаешь что пишешь. Один это выразил негодованием и требованием переписать строчку, второй предупредил что строка мутная. Оба просто не захотели в нечитаемом говне колупаться.
Но вообще у тебя ошибка из-за использования макроса так то, а остальной код - ну его можно просто заменить на 2 строчки - вызов vsnprintf и прибавление к nb количества символов.
multiple unsequenced modifications
>Это намек что ты пишешь трудночитаемое говно. Если левый созерцатель не смог понять что у тебя происходит
Я, блядь, голову на отсечение даю - ты ещё трудночитаемого говна не видел!
И к кому мне, бладжад, бежать, если мне что-то не нравится?
>>1989850
>>1989836
>в функцию передал уже не массив, а только указатель
Это как-то можно пофиксить?
Подсчёт кол-ва чимволов просто и в других местах использую.
Пока засунул в епременную внутри функции...
> >Это намек что ты пишешь трудночитаемое говно. Если левый созерцатель не смог понять что у тебя происходит
> Я, блядь, голову на отсечение даю - ты ещё трудночитаемого говна не видел!
Вообще видел, ты его сюда притащил.
> И к кому мне, бладжад, бежать, если мне что-то не нравится?
fork & pull request
>И к кому мне, бладжад, бежать, если мне что-то не нравится?
Поздно уже бежать, надо было учить, пока была возможность.
>Это как-то можно пофиксить?
Захардкодить в дефайне или глобалке и везде использовать; передавать размер ещё одним аргументом; передавать структуру с массивом внутри, тогда весь массив будет копироваться; переходить на другой язык, где это делается автомагически; поменять логику программы.
>Вы все шизики! Один я д'Артаньян стою красивый в белом пальто и знаю, как правильно! (только ошибку за меня найдите, а то мне тяжело)
>>1989904
Чувак, давно у психиатра был?
Дай угадаю, ты там ржал при написании. Я тоже посмеялся.
>Смешно. Линус, залогинься. Тоже мне, единственный и неоспоримый нашёлся.
Знаешь, качественный код отбирают тонны глаз. А ты проверки парой глаз не прошел.
>Ещё один. Шиза.
На самом деле ты не умеешь признавать свои ошибки и программист из тебя явно из-за этого херовый.
>Вот только не надо. Ещё название ВУЗа попроси, чтобы на кафедру отписать.
Ну это многое бы объясняло. В основном студенты так оправдывают свое говно.
>>1989904
Выглядит реально так, лол.
>>1989920
> Возможно я зря огрызаюсь, но не нападали бы - не пришлось бы писать подобную дичь.
Дураком себя выставил на самом деле. На критику и негатив реагировать не умеешь. За умного ты больше не сойдешь здесь.
>А ты проверки парой глаз не прошел.
>За умного ты больше не сойдешь здесь.
Какой ужас. Как же теперь дальше жить. Пожалуй, выйду покурить в окно.
Иди на хуй просто, лол.
Кого ты посылаешь, маня, посылалка не выросла, ты даже код писать не умеешь, лол.
Конечно, есть проблемы. Есть свои проблемы у всего. Но так ли они суперкритичны, чтобы уходить на что-то другое? И будут ли какие-то суперпреимущества, которые нивелируют новые проблемы? То-то же.
А ты голубой?
Круто как
Да я не призываю уходить. Преимущества есть, всё не на ровном месте выросло. Хотя бы в курсе дел быть стоит. А то получаются такие личности, которые искренне верят что существует только один язык, это на котором я пишу, и конкурентов у него нет, тоже только потому что я на нём пишу.
Код говно, да и сам ты лох и чмо :)
>Unfortunately, the PC industry has never been good about maintaining standards. So each PC manufacturer and each BIOS manufacturer randomly made up new BIOS functions.
неужели за 40 лет нельзя было запилить?
кун-с-бутлодером
Большинство стандартных вещей поддерживалось всеми более-менее одинаково. Уж на бутлоадер-то точно хватало. А сейчас UEFI уже, вообще не о чем думать.
>yvDz8u7pIOru5CE=
Я не уверен, но по-идее можно в таблицу ебануть нули на позицию '=', и тогда всё будет чики-пуки.
Зачем тебе бутлоадер?
Ly8gyu7k6PDu4uDt6OUgYmFzZTY0DQppbnQgYmFzZTY0X2VuYyhjaGFyICpvdXRwdXQsIGNoYXIgKmlucHV0LCBpbnQgc2l6ZV9pbnB1dCwgaW50ICp0ZW1wLCBpbnQgc3RyX2xlbikNCnsNCgljaGFyICpiNjQgPSAiQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLyI7DQoJY2hhciAqZmxhZyA9IChjaGFyICopIHRlbXA7DQoJY2hhciAqdCA9IChjaGFyICopIHRlbXAgKyAxOw0KCWNoYXIgKmRhdGEgPSAoY2hhciAqKSB0ZW1wICsgMjsNCgljaGFyICpkbGVuID0gKGNoYXIgKikgdGVtcCArIDM7DQoJaW50IG4gPSAwOw0KCQ0KCXN0cl9sZW4gPSBzdHJfbGVuIC8gNCAqIDQ7DQoJDQoJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplX2lucHV0OyBpKyspDQoJew0KCQlzd2l0Y2ggKCp0KQ0KCQl7DQoJCQljYXNlIDA6DQoJCQkJb3V0cHV0W24rK10gPSBiNjRbaW5wdXRbaV0gPj4gMiAmIDYzXTsNCgkJCQkqZGF0YSA9IGlucHV0W2ldOw0KCQkJCSgqdCkrKzsNCgkJCQlpZiAoKmZsYWcgJiYgaSA9PSBzaXplX2lucHV0IC0gMSkNCgkJCQl7DQoJCQkJCW91dHB1dFtuKytdID0gYjY0WypkYXRhIDw8IDQgJiA0OF07DQoJCQkJCW91dHB1dFtuKytdID0gJz0nOw0KCQkJCQlvdXRwdXRbbisrXSA9ICc9JzsNCgkJCQkJb3V0cHV0W24rK10gPSAweDBEOw0KCQkJCQlvdXRwdXRbbisrXSA9IDB4MEE7DQoJCQkJCSp0ID0gMDsNCgkJCQl9DQoJCQkJYnJlYWs7DQoJCQljYXNlIDE6DQoJCQkJb3V0cHV0W24rK10gPSBiNjRbKmRhdGEgPDwgNCAmIDQ4IHwgaW5wdXRbaV0gPj4gNCAmIDE1XTsNCgkJCQkqZGF0YSA9IGlucHV0W2ldOw0KCQkJCSgqdCkrKzsNCgkJCQlpZiAoKmZsYWcgJiYgaSA9PSBzaXplX2lucHV0IC0gMSkNCgkJCQl7DQoJCQkJCW91dHB1dFtuKytdID0gYjY0WypkYXRhIDw8IDIgJiA2MF07DQoJCQkJCW91dHB1dFtuKytdID0gJz0nOw0KCQkJCQlvdXRwdXRbbisrXSA9IDB4MEQ7DQoJCQkJCW91dHB1dFtuKytdID0gMHgwQTsNCgkJCQkJKnQgPSAwOw0KCQkJCX0NCgkJCQlicmVhazsNCgkJCWNhc2UgMjoNCgkJCQlvdXRwdXRbbisrXSA9IGI2NFsqZGF0YSA8PCAyICYgNjAgfCBpbnB1dFtpXSA+PiA2ICYgM107DQoJCQkJb3V0cHV0W24rK10gPSBiNjRbaW5wdXRbaV0gJiA2M107DQoJCQkJKnQgPSAwOw0KCQkJCWlmIChzdHJfbGVuICYmIChuICsgKmRsZW4pICUgKHN0cl9sZW4gKyAyKSA9PSBzdHJfbGVuIHx8ICpmbGFnICYmIGkgPT0gc2l6ZV9pbnB1dCAtIDEpDQoJCQkJew0KCQkJCQlvdXRwdXRbbisrXSA9IDB4MEQ7DQoJCQkJCW91dHB1dFtuKytdID0gMHgwQTsNCgkJCQl9DQoJCQkJYnJlYWs7DQoJCX0NCgl9DQoJDQoJaWYgKCpmbGFnKQ0KCQkqZGxlbiA9IDA7DQoJZWxzZQ0KCQkqZGxlbiA9IChuICsgKmRsZW4pICUgKHN0cl9sZW4gKyAyKTsNCgkNCglyZXR1cm4gbjsNCn0NCg0KLy8gxOXq7uTo8O7i4O3o5SBiYXNlNjQNCmludCBiYXNlNjRfZGVjKGNoYXIgKm91dHB1dCwgY2hhciAqaW5wdXQsIGludCBzaXplX2lucHV0LCBpbnQgKnRlbXApDQp7DQoJY2hhciAqdCA9IChjaGFyICopIHRlbXAgKyAxOw0KCWNoYXIgKmRhdGEgPSAoY2hhciAqKSB0ZW1wICsgMjsNCgljaGFyIGluZGV4Ow0KCWludCBuID0gMDsNCgkNCglmb3IgKGludCBpID0gMDsgaSA8IHNpemVfaW5wdXQ7IGkrKykNCgl7DQoJCWluZGV4ID0gaW5wdXRbaV07DQoJCWlmIChpbmRleCA+PSA2NSAmJiBpbmRleCA8PSA5MCkgLy8gQS1aDQoJCQlpbmRleCAtPSA2NTsNCgkJZWxzZSBpZiAoaW5kZXggPj0gOTcgJiYgaW5kZXggPD0gMTIyKSAvLyBhLXoNCgkJCWluZGV4IC09IDcxOw0KCQllbHNlIGlmIChpbmRleCA+PSA0OCAmJiBpbmRleCA8PSA1NykgLy8gMC05DQoJCQlpbmRleCArPSA0Ow0KCQllbHNlIGlmIChpbmRleCA9PSA0MykgLy8gKw0KCQkJaW5kZXggPSA2MjsNCgkJZWxzZSBpZiAoaW5kZXggPT0gNDcpIC8vIC8NCgkJCWluZGV4ID0gNjM7DQoJCWVsc2UgDQoJCQlpbmRleCA9IC0xOw0KCQkNCgkJaWYgKGluZGV4ID49IDApDQoJCXsNCgkJCXN3aXRjaCAoKnQpDQoJCQl7DQoJCQkJY2FzZSAwOg0KCQkJCQkqZGF0YSA9IGluZGV4IDw8IDI7DQoJCQkJCSgqdCkrKzsNCgkJCQkJYnJlYWs7DQoJCQkJY2FzZSAxOg0KCQkJCQlvdXRwdXRbbisrXSA9ICpkYXRhIHwgaW5kZXggPj4gNDsNCgkJCQkJKmRhdGEgPSBpbmRleCA8PCA0Ow0KCQkJCQkoKnQpKys7DQoJCQkJCWJyZWFrOw0KCQkJCWNhc2UgMjoNCgkJCQkJb3V0cHV0W24rK10gPSAqZGF0YSB8IGluZGV4ID4+IDI7DQoJCQkJCSpkYXRhID0gaW5kZXggPDwgNjsNCgkJCQkJKCp0KSsrOw0KCQkJCQlicmVhazsNCgkJCQljYXNlIDM6DQoJCQkJCW91dHB1dFtuKytdID0gKmRhdGEgfCBpbmRleDsNCgkJCQkJKnQgPSAwOw0KCQkJCQlicmVhazsNCgkJCX0NCgkJfQ0KCX0NCgkNCglyZXR1cm4gbjsNCn0=
Ly8gyu7k6PDu4uDt6OUgYmFzZTY0DQppbnQgYmFzZTY0X2VuYyhjaGFyICpvdXRwdXQsIGNoYXIgKmlucHV0LCBpbnQgc2l6ZV9pbnB1dCwgaW50ICp0ZW1wLCBpbnQgc3RyX2xlbikNCnsNCgljaGFyICpiNjQgPSAiQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLyI7DQoJY2hhciAqZmxhZyA9IChjaGFyICopIHRlbXA7DQoJY2hhciAqdCA9IChjaGFyICopIHRlbXAgKyAxOw0KCWNoYXIgKmRhdGEgPSAoY2hhciAqKSB0ZW1wICsgMjsNCgljaGFyICpkbGVuID0gKGNoYXIgKikgdGVtcCArIDM7DQoJaW50IG4gPSAwOw0KCQ0KCXN0cl9sZW4gPSBzdHJfbGVuIC8gNCAqIDQ7DQoJDQoJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplX2lucHV0OyBpKyspDQoJew0KCQlzd2l0Y2ggKCp0KQ0KCQl7DQoJCQljYXNlIDA6DQoJCQkJb3V0cHV0W24rK10gPSBiNjRbaW5wdXRbaV0gPj4gMiAmIDYzXTsNCgkJCQkqZGF0YSA9IGlucHV0W2ldOw0KCQkJCSgqdCkrKzsNCgkJCQlpZiAoKmZsYWcgJiYgaSA9PSBzaXplX2lucHV0IC0gMSkNCgkJCQl7DQoJCQkJCW91dHB1dFtuKytdID0gYjY0WypkYXRhIDw8IDQgJiA0OF07DQoJCQkJCW91dHB1dFtuKytdID0gJz0nOw0KCQkJCQlvdXRwdXRbbisrXSA9ICc9JzsNCgkJCQkJb3V0cHV0W24rK10gPSAweDBEOw0KCQkJCQlvdXRwdXRbbisrXSA9IDB4MEE7DQoJCQkJCSp0ID0gMDsNCgkJCQl9DQoJCQkJYnJlYWs7DQoJCQljYXNlIDE6DQoJCQkJb3V0cHV0W24rK10gPSBiNjRbKmRhdGEgPDwgNCAmIDQ4IHwgaW5wdXRbaV0gPj4gNCAmIDE1XTsNCgkJCQkqZGF0YSA9IGlucHV0W2ldOw0KCQkJCSgqdCkrKzsNCgkJCQlpZiAoKmZsYWcgJiYgaSA9PSBzaXplX2lucHV0IC0gMSkNCgkJCQl7DQoJCQkJCW91dHB1dFtuKytdID0gYjY0WypkYXRhIDw8IDIgJiA2MF07DQoJCQkJCW91dHB1dFtuKytdID0gJz0nOw0KCQkJCQlvdXRwdXRbbisrXSA9IDB4MEQ7DQoJCQkJCW91dHB1dFtuKytdID0gMHgwQTsNCgkJCQkJKnQgPSAwOw0KCQkJCX0NCgkJCQlicmVhazsNCgkJCWNhc2UgMjoNCgkJCQlvdXRwdXRbbisrXSA9IGI2NFsqZGF0YSA8PCAyICYgNjAgfCBpbnB1dFtpXSA+PiA2ICYgM107DQoJCQkJb3V0cHV0W24rK10gPSBiNjRbaW5wdXRbaV0gJiA2M107DQoJCQkJKnQgPSAwOw0KCQkJCWlmIChzdHJfbGVuICYmIChuICsgKmRsZW4pICUgKHN0cl9sZW4gKyAyKSA9PSBzdHJfbGVuIHx8ICpmbGFnICYmIGkgPT0gc2l6ZV9pbnB1dCAtIDEpDQoJCQkJew0KCQkJCQlvdXRwdXRbbisrXSA9IDB4MEQ7DQoJCQkJCW91dHB1dFtuKytdID0gMHgwQTsNCgkJCQl9DQoJCQkJYnJlYWs7DQoJCX0NCgl9DQoJDQoJaWYgKCpmbGFnKQ0KCQkqZGxlbiA9IDA7DQoJZWxzZQ0KCQkqZGxlbiA9IChuICsgKmRsZW4pICUgKHN0cl9sZW4gKyAyKTsNCgkNCglyZXR1cm4gbjsNCn0NCg0KLy8gxOXq7uTo8O7i4O3o5SBiYXNlNjQNCmludCBiYXNlNjRfZGVjKGNoYXIgKm91dHB1dCwgY2hhciAqaW5wdXQsIGludCBzaXplX2lucHV0LCBpbnQgKnRlbXApDQp7DQoJY2hhciAqdCA9IChjaGFyICopIHRlbXAgKyAxOw0KCWNoYXIgKmRhdGEgPSAoY2hhciAqKSB0ZW1wICsgMjsNCgljaGFyIGluZGV4Ow0KCWludCBuID0gMDsNCgkNCglmb3IgKGludCBpID0gMDsgaSA8IHNpemVfaW5wdXQ7IGkrKykNCgl7DQoJCWluZGV4ID0gaW5wdXRbaV07DQoJCWlmIChpbmRleCA+PSA2NSAmJiBpbmRleCA8PSA5MCkgLy8gQS1aDQoJCQlpbmRleCAtPSA2NTsNCgkJZWxzZSBpZiAoaW5kZXggPj0gOTcgJiYgaW5kZXggPD0gMTIyKSAvLyBhLXoNCgkJCWluZGV4IC09IDcxOw0KCQllbHNlIGlmIChpbmRleCA+PSA0OCAmJiBpbmRleCA8PSA1NykgLy8gMC05DQoJCQlpbmRleCArPSA0Ow0KCQllbHNlIGlmIChpbmRleCA9PSA0MykgLy8gKw0KCQkJaW5kZXggPSA2MjsNCgkJZWxzZSBpZiAoaW5kZXggPT0gNDcpIC8vIC8NCgkJCWluZGV4ID0gNjM7DQoJCWVsc2UgDQoJCQlpbmRleCA9IC0xOw0KCQkNCgkJaWYgKGluZGV4ID49IDApDQoJCXsNCgkJCXN3aXRjaCAoKnQpDQoJCQl7DQoJCQkJY2FzZSAwOg0KCQkJCQkqZGF0YSA9IGluZGV4IDw8IDI7DQoJCQkJCSgqdCkrKzsNCgkJCQkJYnJlYWs7DQoJCQkJY2FzZSAxOg0KCQkJCQlvdXRwdXRbbisrXSA9ICpkYXRhIHwgaW5kZXggPj4gNDsNCgkJCQkJKmRhdGEgPSBpbmRleCA8PCA0Ow0KCQkJCQkoKnQpKys7DQoJCQkJCWJyZWFrOw0KCQkJCWNhc2UgMjoNCgkJCQkJb3V0cHV0W24rK10gPSAqZGF0YSB8IGluZGV4ID4+IDI7DQoJCQkJCSpkYXRhID0gaW5kZXggPDwgNjsNCgkJCQkJKCp0KSsrOw0KCQkJCQlicmVhazsNCgkJCQljYXNlIDM6DQoJCQkJCW91dHB1dFtuKytdID0gKmRhdGEgfCBpbmRleDsNCgkJCQkJKnQgPSAwOw0KCQkJCQlicmVhazsNCgkJCX0NCgkJfQ0KCX0NCgkNCglyZXR1cm4gbjsNCn0=
Ты суть-то понял, зачем используется таблица, и почему подобный метод быстрее на современном железе?
На поверхности. Cмысл в том, что ты экономишь на командах, и на современном железе за такой небольшой таблицей ты в память не ходишь.
Не дальше второго уровня.
256 байт - это 6 кэшлайнов в худшем случае, в плотном цикле они ваще не будут выходить из кэша первого уровня.
Если освобождаешь горячую память(в кэше). Или памяти мало(ембед).
Ты зарплаты сначала посмотри. Охуеешь.
> Дико извиняюсь, был не прав, сейчас тоже листинги посмотрел, там при передаче массива в качестве аргумента, он на указатель распадается.
В Си массивы никогда неявно не копируются.
Более того, объявления void f(int arr[32]), void f(int arr[]) и void f(int * arr) вообще абсолютно эквивалентны друг другу.
> Неплохая каша у меня в голове, тогда где массивы полностью копируются?
Целиком копируются лишь структуры со всеми их полями (но не массивы структур, тут правила те же).
А ещё std::vector<> и иже с ними из плюсов, а также классы со специальными конструкторами копирования оттуда же, но это уже не Си, понятное дело.
Скорее всего, именно с плюсовыми шаблонами из STL всё и перепуталось.
При передаче указателя на массив в функцию efm_log_writev()
Функция получает указатель на sendbuf, а не весь массив. Информация о размере массива внутри функции утеряна.
В связи с этим countof(buf) внутри этой функции всегда возвращает sizeof(char )/sizeof(char) = 8 (или 4 на 32-битной архитектуре), но никак не ожидаемые 2000.
Переписывается примерно так. Не тестировал, но суть должна быть понятна.
buf, const char tag, const char format, va_list args)> void efm_log_writev(char
void efm_log_writev(char buf, unsigned buf_countof, const char tag, const char *format, va_list args)
> #define EFM_LOGE( buf, tag, format, ... ) efm_log_write(buf, tag, LOG_FORMAT(E, format), tag, ##__VA_ARGS__)
#define EFM_LOGE( buf, buf_countof, tag, format, ... ) efm_log_write(buf, buf_countof, tag, LOG_FORMAT(E, format), tag, ##__VA_ARGS__)
И так далее, всюду после buf добавляешь buf_countof
В самой функции efm_log_writev вместо countof(buf) и sizeof(buf) используешь buf_countof. К счастью, размер char всегда равен одному байту по определению, так что они здесь будут эквивалентны.
На самом верхнем уровне
> EFM_LOGE(sendbuf, TAG, "FOO %s, %d", "bar", 123);
EFM_LOGE(sendbuf, countof(sendbuf), TAG, "FOO %s, %d", "bar", 123);
Макрос countof() может быть полезным, но об него очень просто обрезаться. Настолько просто, что я бы не рекомендовал использовать его практически нигде, кроме тех случаев, когда работаешь с массивом, который только что локально объявил на стеке.
А без знания этих тонкостей языка его лучше вообще не трогать, как по мне.
*забыл обработать звёздочки как надо, ну да ладно, суть всё равно должна быть понятна
Можно написать в хэдэре функцию, чтобы ее определение было в файлах, в которые ты подключил заголовочник. Плюсом к этому получаешь библиотеку, которая не имеет своих модулей компиляции. Сплошь удобство? Минусы есть - могут быть дубликаты функций в разных файлах, куда ты свой заголовочник подключал. Особенно если делал функции как static.
Причины можно придумывать дальше, да и недостатки подхода тоже. Как и во всем Си - надо знать что делаешь, и с какой целью, и тогда это оправдано.
это сишный способ писать шаблоны. Таким образом можно реализоввывать библиотеки с двумя важными свойствами
1) типобезопасность
2) лучшая оптимизация (чем при передаче шаблонного параметра в качестве "обычного")
с типобезопасностью понятно. в плане оптимальности, если рассматривать пример библиотеки векторных вычислений, компилятор сможет заинлайнить векторные функции, в то время как при стандартном подходе (заголовок + реализация в отдельном компилируемом модуле) компилятору придётся строго придерживаться ABI (по-простому - протокола передачи аргументов при вызове функции). компилятору придётся лишний раз копировать данные (частенько); так как функция теперь - чёрный ящик, он не сможет оптимизировать, используя о ней знание.
Спасибо, но я просто задал размер массива в дефайне, а затем объявляю массив с задефаненным размером. Пока всё нормально.
>>1994309
>Этому долбоебу не стоит помогать. Он на помощь огрызается.
Это не помощь. На меня просто вылили ушат помоев, которые, похоже, до меня приняли такие вот "помощники".
Спасибо, ЧСВ-шное чмо, за твою "помощь". Ебал я таких помощников.
>тест
>тест
Плюсы
@
Несколько гигов исходников
@
Хуле так долга собирается
Пару лет назад нужно было собрать, ждал 8 часов.
Че то не нраветься?
Наверняка есть какой-нибудь системный вызов для копирования файлов, ну и обёртка над ним в стдлибе.
>man setbuf
>stream buffering operations
Фаел != стрим, чувак.
Помню, как пытался собрать эту залупу. Раз 5 где-то пересобирал. Самый лютый пиздец в том, что пока ты не соберешь успешно до условных 60-80%, ты не узнаешь какая хуйня решит наебнуться/отвалиться. В основном это из-за кривой конфигурации cmake, а официальная документация llvm-project оставляет желать лучшего. Короче, собирал где-то 3 дня все это. Правда не помню уже зачем и нахуя.
>Наверняка есть какой-нибудь системный вызов для копирования файлов,
наврятли. правда можно сделать обратное, т.е. получить доступ к ломтю памяти через файловый дескриптор через не совсем стандартный fmemopen().
>>man setbuf
>>stream buffering operations
>Фаел != стрим, чувак.
так отличие только в сикабельности, все стандартные потоки в прыщах есть char devices, т.е. тe же файлы.
Ну, так тоже сработает, конечно.
Мой вариант пригодится в случае, если код разрастётся и если вдруг когда-нибудь придётся использовать более чем один буфер с разными размерами.
Просто поосторожнее с countof() и sizeof(): они в этом аспекте очень опасны.
Вот.
Раскритикуйте говнокод пожалуйста:
https://pastebin.com/zWmKy6AY
1- нет комментариев
2- нет разделения между логикой игры и винтухлятиной
3- направление проще представлять в виде двух дельт, тогда уйдут свитчи
Тип короче ты всякие штуки, которые относятся чисто к сущности snake мутишь в wndproc, хотя их бы вынести в отдельные функции (возможно, даже в отдельный compile unit, если бы >>1995666 анон этого затребовал), думай об этом так, что если бы тебя попросили написать змейку для терминала (80×24), неплохо было бы использовать уже написанное. Неплохо бы написать комменты, описалово к функциям, ну и вообще.
Выше ньюфаг декодер для base64 делал, пиздуй декодер для utf8 писать, скидывай результат в тред, обсудим
бля забыл что между звёздочками курсив, не сижу на ваших двачах просто
короче пикрил смотрите
Однажды Эрнест Хемингуэй поспорил что сможет написать строку, способную растрогать любого
Выражения дополнительно в скобки оберни.
Какова же разница между expression и conditional expression?
Тебе надо добавить перевод строки чтобы буфер сбрасывался
То есть выше, но все всё поняли.
Зачем нужен С, когда есть Rust?
Заголубел
Пишу свой обрезанный шелл. Проблема при вызове любой комманды с пайпом - к примеру ls | cat -e.
Поставленно все так, что для каждой отдельной команды определяется откуда и куда вводить\выводить вызывается fork в котором выполняется execve. Таким образом выходят паралельные дочерние процессы, в случае примера первая дочь будет execve(ls) а вторая execve(cat).
Проблема в том, что хоть как-то умирает после execve только первый процесс (уходит в зомби), все что после него продолжает жить, даже после вывода. То есть пример выведет все как надо, но вторая дочь (cat) будет продолжать работать. Что происходит и как это исправить?
> >Наверняка есть какой-нибудь системный вызов для копирования файлов,
> наврятли.
sendfile на Linux, fcopyfile на bsd/mac os
На винде думаю свое апи тоже есть
>Сажи безграмотному.
Чем тебе не нравитсч "дочерний"? Сыновний или детский звучит вырвиглазно.
Можно конечно использовать "порождённый" или "потомок", но такой термин точно не передаёт суть.
>открыл man на английском
Мы про английскую версию говорим что-ли?
https://www.opennet.ru/man.shtml?topic=fork&category=2
>Сыновний
Сычевний
Тебя не смущает что "седьмой час", это нифига не семь часов и сколько-то там минут.
Тебя не смущает что XX век это 1901-2000?
Тебя не смущает что при этом "девяностые" это 1990-1999?
Иди лучше там повоюй.
Не, он имеет ввиду что процесс - дочь просесса. Как сын - дочь отца выходит
В твоём примере - Дочерний цикл = цикл у дочери
Перекатился в гейропку в IT
@
Постоянно слышишь, как о программисте в общем контексте говорят she
@
Проверяешь не отвалился ли у тебя член
cat скорее всего будет ждать закрытия write конца, поэтому она будет заблокирована в системном вызове, ведь eof никогда не придёт
Судя по коду я не вижу возможным, что до execve(ls) дойдёт. Если посылалось cmd: [ls, pipe(1)], [cat, pipe(0)]: то будет, во-первых, race condition между родителем и потомком, во-вторых, fork с execve(cat) [child], и потом уже в зависимости, от результатов гонки waitpid, если выиграл родитель, то он заблочиться в waitpid, ежели нет будет возвращение из функции, и будет fork для ls, который тоже будет тупа либо зомбёй либо его рипнут через waitpid.
Добавлю, что ты ещё вообще не проверяешь результаты системных вызовов, плюсом надо бы проверить чё там по сигналам.
Короче хуёво написал, переделывай.
В своей махарайке использую cJSON либу: https://github.com/DaveGamble/cJSON
Спустя пару минут работы программного цикла ловлю hardfault, похоже, связанный именно с этой либой.
Логи регистров состояния: https://pastebin.com/b2Y23vBV
С такой фигнёй сталкиваюсь впервые, опыта - нуль.
Или сажите, на каком форуме смогут помочь.
man gcc
Каким-то хером output_size (скриншот 2) увеличилось до 13618.
Хотя размер строки не превышает 2000 символов.
Как отловить почему произошло увеличение?
пример
123^Z
пробел^Z
не определяется как EOF.
Это везде так, EOF только с начала строки.
Спрячь его корзину с грязными трусами.
Подскажите, плез, мне нужен этот коммит: https://github.com/DaveGamble/cJSON/pull/494
Как его применить самостоятельно к текущему релизу бибилиотеки, если он не одобрен разработчиками?
Затем, что Jansson - такое же говно и у cJSON больше упоминаний про embed. По крайней мере свежих.
Самый простой способ это склонировать бранч того человека который сделал пул реквест и собрать библиотеку с этого бранча.
man 3 syslog
код
using namespace std;
struct towary
{
char nazva[15], manufacturer[100] ;
int price, zal;
long int mass;
struct towary next; // посилання на наступний вузол
};
struct towary poperedtow, element, pershiy, novii, ostan;
void Stvorutu(void); // Функція створення списку
void Vuvestu(void); // Функція виведення елементів списку
void Novuy(void); // Функція створення нового елемента та внесення його на початоксписку
int main()
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
printf("Створюємо список який містить інформацію про товари (назва, ціна, вага, залишок,виробник). \n");
printf("Для закінчення введення списку ввести нулі у всі поля \n");
Stvorutu();
printf("Створений список \n");
//Vuvestu();
printf("Додаємо в кінець списку новий елемент \n");
Novuy();
element = ostan;
novii->next = element;
ostan = novii; // Додаємо новий елемент до початку списку
printf("Оновлений список: \n");
Vuvestu();
return 0;
}
void Stvorutu(void)
{
element = (struct towary)malloc(sizeof(struct towary)); // Виділення пам'яті під новий вузол
pershiy = element;
do
{
poperedtow = element; // Попередній вузол вказує на створюваний
printf("Введіть назву товару, ціну, вагу, залишок, виробника ");
scanf("%s %d %d %d %s", element->nazva, &element->price, &element->mass, &element->zal, &element->manufacturer); //Збереження полів даних для вузла, що додається
element->next = (struct towary)malloc(sizeof(struct towary)); // Виділення пам'ятіпід наступний вузол
element = element->next; // Створений вузол вказує на наступний
} while (poperedtow->price != 0 || poperedtow->mass != 0);
ostan = poperedtow; // Фіксуємо останній елемент
poperedtow->next = NULL; // Це останній вузол однозв'язного лінійного списку
}
void Vuvestu(void)
{
element = pershiy;
while (element != NULL) // Переглядаємо список, починаючи з першого елемента,поки не дійдемо до кінця списку
{
printf("Назва %s ціна %d вага %d залишок %d виробник %s\n", element->nazva,
element->price, element->mass, element->zal, element->manufacturer);
poperedtow = element;
element = element->next; // Перехід до наступного вузла
}
}
void Novuy(void)
{
//element = (struct towary)malloc(sizeof(struct towary)); // Виділення пам'яті під новий вузол
element=poperedtow;
//ostan = element;
do {
//element = poperedtow;
//poperedtow = element;
//element = element->next;
novii = (struct towary)malloc(sizeof(struct towary));
printf("Введіть назву товару, ціну, вагу, залишок, виробника ");
scanf("%s %d %d %d %s", element->nazva, &element->price, &element->mass, &element->zal, &element->manufacturer); //Збереження полів даних для вузла, що додається
element->next = (struct towary*)malloc(sizeof(struct towary)); // Виділення пам'ятіпід наступний вузол
element = element->next;
}
while (poperedtow->price != 0 || poperedtow->mass != 0 );
ostan = poperedtow; // Фіксуємо останній елемент
poperedtow->next = NULL;
}
код
using namespace std;
struct towary
{
char nazva[15], manufacturer[100] ;
int price, zal;
long int mass;
struct towary next; // посилання на наступний вузол
};
struct towary poperedtow, element, pershiy, novii, ostan;
void Stvorutu(void); // Функція створення списку
void Vuvestu(void); // Функція виведення елементів списку
void Novuy(void); // Функція створення нового елемента та внесення його на початоксписку
int main()
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
printf("Створюємо список який містить інформацію про товари (назва, ціна, вага, залишок,виробник). \n");
printf("Для закінчення введення списку ввести нулі у всі поля \n");
Stvorutu();
printf("Створений список \n");
//Vuvestu();
printf("Додаємо в кінець списку новий елемент \n");
Novuy();
element = ostan;
novii->next = element;
ostan = novii; // Додаємо новий елемент до початку списку
printf("Оновлений список: \n");
Vuvestu();
return 0;
}
void Stvorutu(void)
{
element = (struct towary)malloc(sizeof(struct towary)); // Виділення пам'яті під новий вузол
pershiy = element;
do
{
poperedtow = element; // Попередній вузол вказує на створюваний
printf("Введіть назву товару, ціну, вагу, залишок, виробника ");
scanf("%s %d %d %d %s", element->nazva, &element->price, &element->mass, &element->zal, &element->manufacturer); //Збереження полів даних для вузла, що додається
element->next = (struct towary)malloc(sizeof(struct towary)); // Виділення пам'ятіпід наступний вузол
element = element->next; // Створений вузол вказує на наступний
} while (poperedtow->price != 0 || poperedtow->mass != 0);
ostan = poperedtow; // Фіксуємо останній елемент
poperedtow->next = NULL; // Це останній вузол однозв'язного лінійного списку
}
void Vuvestu(void)
{
element = pershiy;
while (element != NULL) // Переглядаємо список, починаючи з першого елемента,поки не дійдемо до кінця списку
{
printf("Назва %s ціна %d вага %d залишок %d виробник %s\n", element->nazva,
element->price, element->mass, element->zal, element->manufacturer);
poperedtow = element;
element = element->next; // Перехід до наступного вузла
}
}
void Novuy(void)
{
//element = (struct towary)malloc(sizeof(struct towary)); // Виділення пам'яті під новий вузол
element=poperedtow;
//ostan = element;
do {
//element = poperedtow;
//poperedtow = element;
//element = element->next;
novii = (struct towary)malloc(sizeof(struct towary));
printf("Введіть назву товару, ціну, вагу, залишок, виробника ");
scanf("%s %d %d %d %s", element->nazva, &element->price, &element->mass, &element->zal, &element->manufacturer); //Збереження полів даних для вузла, що додається
element->next = (struct towary*)malloc(sizeof(struct towary)); // Виділення пам'ятіпід наступний вузол
element = element->next;
}
while (poperedtow->price != 0 || poperedtow->mass != 0 );
ostan = poperedtow; // Фіксуємо останній елемент
poperedtow->next = NULL;
}
Блядь, проебался, код не должен был быть под спойлером
using namespace std;
struct towary
{
char nazva[15], manufacturer[100] ;
int price, zal;
long int mass;
struct towary next; // посилання на наступний вузол
};
struct towary poperedtow, element, pershiy, novii, ostan;
void Stvorutu(void); // Функція створення списку
void Vuvestu(void); // Функція виведення елементів списку
void Novuy(void); // Функція створення нового елемента та внесення його на початоксписку
int main()
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
printf("Створюємо список який містить інформацію про товари (назва, ціна, вага, залишок,виробник). \n");
printf("Для закінчення введення списку ввести нулі у всі поля \n");
Stvorutu();
printf("Створений список \n");
//Vuvestu();
printf("Додаємо в кінець списку новий елемент \n");
Novuy();
element = ostan;
novii->next = element;
ostan = novii; // Додаємо новий елемент до початку списку
printf("Оновлений список: \n");
Vuvestu();
return 0;
}
void Stvorutu(void)
{
element = (struct towary)malloc(sizeof(struct towary)); // Виділення пам'яті під новий вузол
pershiy = element;
do
{
poperedtow = element; // Попередній вузол вказує на створюваний
printf("Введіть назву товару, ціну, вагу, залишок, виробника ");
scanf("%s %d %d %d %s", element->nazva, &element->price, &element->mass, &element->zal, &element->manufacturer); //Збереження полів даних для вузла, що додається
element->next = (struct towary)malloc(sizeof(struct towary)); // Виділення пам'ятіпід наступний вузол
element = element->next; // Створений вузол вказує на наступний
} while (poperedtow->price != 0 || poperedtow->mass != 0);
ostan = poperedtow; // Фіксуємо останній елемент
poperedtow->next = NULL; // Це останній вузол однозв'язного лінійного списку
}
void Vuvestu(void)
{
element = pershiy;
while (element != NULL) // Переглядаємо список, починаючи з першого елемента,поки не дійдемо до кінця списку
{
printf("Назва %s ціна %d вага %d залишок %d виробник %s\n", element->nazva,
element->price, element->mass, element->zal, element->manufacturer);
poperedtow = element;
element = element->next; // Перехід до наступного вузла
}
}
void Novuy(void)
{
//element = (struct towary)malloc(sizeof(struct towary)); // Виділення пам'яті під новий вузол
element=poperedtow;
//ostan = element;
do {
//element = poperedtow;
//poperedtow = element;
//element = element->next;
novii = (struct towary)malloc(sizeof(struct towary));
printf("Введіть назву товару, ціну, вагу, залишок, виробника ");
scanf("%s %d %d %d %s", element->nazva, &element->price, &element->mass, &element->zal, &element->manufacturer); //Збереження полів даних для вузла, що додається
element->next = (struct towary*)malloc(sizeof(struct towary)); // Виділення пам'ятіпід наступний вузол
element = element->next;
}
while (poperedtow->price != 0 || poperedtow->mass != 0 );
ostan = poperedtow; // Фіксуємо останній елемент
poperedtow->next = NULL;
}
Блядь, проебался, код не должен был быть под спойлером
using namespace std;
struct towary
{
char nazva[15], manufacturer[100] ;
int price, zal;
long int mass;
struct towary next; // посилання на наступний вузол
};
struct towary poperedtow, element, pershiy, novii, ostan;
void Stvorutu(void); // Функція створення списку
void Vuvestu(void); // Функція виведення елементів списку
void Novuy(void); // Функція створення нового елемента та внесення його на початоксписку
int main()
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
printf("Створюємо список який містить інформацію про товари (назва, ціна, вага, залишок,виробник). \n");
printf("Для закінчення введення списку ввести нулі у всі поля \n");
Stvorutu();
printf("Створений список \n");
//Vuvestu();
printf("Додаємо в кінець списку новий елемент \n");
Novuy();
element = ostan;
novii->next = element;
ostan = novii; // Додаємо новий елемент до початку списку
printf("Оновлений список: \n");
Vuvestu();
return 0;
}
void Stvorutu(void)
{
element = (struct towary)malloc(sizeof(struct towary)); // Виділення пам'яті під новий вузол
pershiy = element;
do
{
poperedtow = element; // Попередній вузол вказує на створюваний
printf("Введіть назву товару, ціну, вагу, залишок, виробника ");
scanf("%s %d %d %d %s", element->nazva, &element->price, &element->mass, &element->zal, &element->manufacturer); //Збереження полів даних для вузла, що додається
element->next = (struct towary)malloc(sizeof(struct towary)); // Виділення пам'ятіпід наступний вузол
element = element->next; // Створений вузол вказує на наступний
} while (poperedtow->price != 0 || poperedtow->mass != 0);
ostan = poperedtow; // Фіксуємо останній елемент
poperedtow->next = NULL; // Це останній вузол однозв'язного лінійного списку
}
void Vuvestu(void)
{
element = pershiy;
while (element != NULL) // Переглядаємо список, починаючи з першого елемента,поки не дійдемо до кінця списку
{
printf("Назва %s ціна %d вага %d залишок %d виробник %s\n", element->nazva,
element->price, element->mass, element->zal, element->manufacturer);
poperedtow = element;
element = element->next; // Перехід до наступного вузла
}
}
void Novuy(void)
{
//element = (struct towary)malloc(sizeof(struct towary)); // Виділення пам'яті під новий вузол
element=poperedtow;
//ostan = element;
do {
//element = poperedtow;
//poperedtow = element;
//element = element->next;
novii = (struct towary)malloc(sizeof(struct towary));
printf("Введіть назву товару, ціну, вагу, залишок, виробника ");
scanf("%s %d %d %d %s", element->nazva, &element->price, &element->mass, &element->zal, &element->manufacturer); //Збереження полів даних для вузла, що додається
element->next = (struct towary*)malloc(sizeof(struct towary)); // Виділення пам'ятіпід наступний вузол
element = element->next;
}
while (poperedtow->price != 0 || poperedtow->mass != 0 );
ostan = poperedtow; // Фіксуємо останній елемент
poperedtow->next = NULL;
}
Да-а, уже подсказали.
Ты чё, сука, расист?
Бля, ну не стукай
Якщо ти не знаєш про pastebin та вчишся на програміста - краще забирай документи з внз та іди працювати на завод.
Байто-слесарем на байто-завод?
Если я придумаю свою охуительную библиотечку MyFuckingLibrary, должен ли я описывать переопределить каждый базовый тип а-ля "typedef double MFLdouble"?
Чтобы резко внезапно менять тип во всем коде.
ГЛинт должен быть 2's complement и минимум 32 бита по спецификации. И так далее. В твом компиляторе си это совершенно случайно = int.
Во всех современных компиляторах есть int_least32_t. А для не 2 complement надо свою виртуальную машину писать и свой компилятор.
мимо
Расскажи это ребятам из SGI 90-х.
Я знаю про pastebin, но не могу понять конкретно эту тему, даже после выкуривания всей инфы, до какой смог дотянуться.
У дейтелов смотрел?
Что там не понимать? Если lst->next == NULL, создаешь
lst->next = malloc(sizeof(list)), задаешь lst->next->next = NULL, lst->next->value = нужное тебе значение.
Если lst->next не NULL, делаешь lst = lst->next.
Только голову запомни, иначе весь список проебешь
https://www.youtube.com/watch?v=7OXYO8Ncjm4&list=PLvb7ivodu7oQkuxXHqv_LjUWupqSkfQKM
Есть смысл покупать справочник по сям в виде книги? Недавно купил несколько книг в твёрдой обложке, доволен как слон.
В си нормальные регулярки есть?
Нашел
называется дохуя свободного времени
Можно ли как-то передать в функцию, принимающую структурную переменную (foo_t), только одно поле структуры bar (ptr.str[0])?
Компилятор ругается на несовместимы тип указателя, когда пытаюсь подсунуть &ptr.str[0].
Блин, пока нету времени. Потом.
Вангую, что функция принимает аргумент по значению void func(foo_t value), и тогда тебе не нужен &. Либо ты облажался где-то еще (например, ты хотел bar(ptr->str)).
Нет, функция принимает именно указатель.
https://ideone.com/82O2Sw
Странно, но эмулятор не ругается.
Я же получаю то, что на пике. Забить на варнинг?
А как грамотно выделить память под первый элемент? Что если у меня список из 1 элемента, и голова указывает на NULL?
https://youtube.com/playlist?list=PLRDzFCPr95fLjzcv6nNdjMu_9RcZgIM9U
есть такая штучка, возможно будет лучше того, что ты скинул.
у этого чела канал в целом годный, всем советую
Вроде все ок. А на код именно в таком виде, как ты запостил на ideone, у тебя на машине ругается? Может быть, у тебя там дефайны какие-то локально или типы на самом деле чем-то отличаются.
>А на код именно в таком виде, как ты запостил на ideone, у тебя на машине ругается?
Нет, не ругается.
Короче, оставил оригинальную структуру, содержащую необходимые поля.
Свою копию структуры удалил, хотя какая хрен разница - поля совпадали с оригинальной структурой, только что она была по-другому названа.
typedef struct bar {
original_struct_t str[2]; // original_struct_t - имя оригинальной структуры
} bar_t;
original_struct_t oneFieldOnly;
Так ошибки нет. По идее, и оригинальная структура не будет затронута и у меня свои копии будут.
Ещё бы знать, в чём я объебался.
Из описания опенгруп: The pthread_join() function shall suspend execution of the calling thread until the target thread terminates
Что это вообще значит? Одновременно работают несколько потоков, зачем один должен ожидать другой? Ожидать где? Какой ещё вызывающий и целевой поток?
Ну должен же быть в этом какой-то смысл раз не только pthread_exit используют.
Главный тред передал задачу в дочерний, и ждёт пока он ее исполнит после того как сам что то ещё поделал, что не понятно? Тредами управляет ос, главный только делает к ней запросы.
Есть к примеру такие куски кода:
pthread_join(T1, NULL);
pthread_join(T2, NULL);
pthread_join(T3, NULL);
pthread_join(T4, NULL);
Все четыре треда дочерние по отношению к основному (созданному при запуске программы)? Если так то основной ожидает все 4 разом или они выполняются произвольно? Зачем ждёт?
Ответ четко написан в процитированной тобой документации.
Если ты до сих пор не понимаешь, возможны варианты:
1. Ты - дебил, иди работать дворником.
2. Ты не знаешь английского, иди учи английский сначала.
3. Ты пришел из говна вроде жабаскрипта, в котором отсутствует понятие порядка выполнения, ибо это говно основано на ивентах. Т.е. ты не представляешь как работает компьютер, как он выполняет код, т.е. как работают программы в принципе, но уже лезешь в треды. Просто сотри себе память о своем жабоговне и иди "в первый класс" начинать с элементарных обучающих языков учиться понимать сто такое "програм флоу" или как там это называется, короче последовательность, ветвления, переходы и т.п.. А ты лезешь в ядерную физику не понимая даже арифметики. Просто вали нахуй, учись с азов.
Кусок дерьма, я прошитое дерево написал. А вот что тебе пожалуй неизвестно: https://ru.wikipedia.org/wiki/Проклятие_знания
> Если так то основной ожидает все 4 разом или они выполняются произвольно? Зачем ждёт?
Ждет оно, чтобы удостовериться, что работа завершена, точно так же надо ждать потомка, если у тебя процессы, а не потоки. Потоки выполняются параллельно. Джойн ждет один поток, т.е., все твои вызовы выполняются последовательно - пока T1 не завершится, ждать T2 ты не будешь, и даже если T2 давно сдох, ты об этом не узнаешь, пока не закончишь ждать T1. Воркфлоу такой: ты сигналишь потоку, что ему пора на покой (используя другие примитивы синхронизации), потом ждешь, пока он приберется за собой и успешно умрет.
Твое недоумение понятно, в никсах апи по обыкновению кривой. Белые люди в винде сделали нормально: можно WaitForMultipleObjects, либо получая уведомления либо по мере завершения потоков (при чем не по порядку, а кто раньше помер - про того и скажут), либо ждать всех сразу до победы.
>Ага, Линукс называется.
ебать остряк в чяти.
>>2016502
ну ващ куча. есть STB например (хэштаблицы, вектора, работа с картиночками и проч, ориентировано на геймдев), есть Glib (не путать с glibc). а так - гугли тупо под конкретный запрос.есть на все вкусы: с абстрактными типами данных на войд-звёздочка, типобезопасные с макромагией.
Спасибо. Почему то, когда гуглил показалось, что на си принято руками велосипедить структуры. Это хоть отчасти так или просто верхние страницы Гугла забиты ответами преподов говновузов?
ну в половине случаев это ответы брейндед с++ прогеров, у которых абстрактные типы данных невозможны в чистом си, так как там нет шаблонов. в половине- микроконтроллерных байтоёбов, которые и впрямь часто велосипедят, но с умыслом: для лучшего ручного контроля за укладыванием всего в памяти. писатели прикладных прог на чистом Си - вымирающий вид.
Удобной для большинства таблицы или дерева не получается даже на уровне интерфейса. Например, в openbsd был достаточно универсальный хэш oah, но в нем нельзя было сделать проход по таблице с удалением, пришлось отфоркать и переделать.
Я сразу с регистров-дефайненых-в-cmsis начинал. Все равно придётся дрочить референс мануал. Да и там как раз названия этих всех регистров.
Нету желания дрочить рм/даташиты/аппноты/ерраты/другие пдф талмуды - не стоит связываться с МК.
> Нету желания дрочить рм/даташиты/аппноты/ерраты/другие пдф талмуды - не стоит связываться с МК.
Золотые слова.
связался с МК и пригорел от обилия даташитов
Тут один пидорас говорил что нулевые указатели нужно кастить.
Вот список который я собрал для себя: gdb, valgrind, cmake... Еще что изучать?
Почему цикл срабатывает и выводит еще один пустой элемент, когда значение current == NULL? Какого хуя?
Ты про проверку sgets? Я не нашел способа получше условия проверять, я тупой. switch не сработает там.
> Почему цикл срабатывает и выводит еще один пустой элемент, когда значение current == NULL? Какого хуя?
Потому что вот здесь
> current = malloc(sizeof *current);
malloc() выдаёт какой-то указатель,
> prev->next = current;
этот указатель копируется в prev->next
> current = NULL;
А вот это затирает только в current, но при этом prev->next остаётся тем же самым, что тебе вернул malloc().
Вдобавок,
> free(current);
> current = current->next;
Тут неопределённое поведение, после free значение current->next не определено.
БЛЯ СПАСИБО!
> free(current);
> current = current->next;
>Тут неопределённое поведение, после free значение current->next не определено.
а разве current не получает память в статике и просто значение current каждый раз переписывается новым? Сам указатель же статический верно?
Почему это работает блять!?
Не за что
> а разве current не получает память в статике и просто значение current каждый раз переписывается новым? Сам указатель же статический верно?
current - да, действительно статический.
А вот current->next уже смотрит в кучу.
> Почему это работает блять!?
А работает это потому, что после того, как блок памяти удалён, операционная система может не перезаписать его нулями или каким-то мусором, а оставить таким, как есть, в первую очередь для увеличения быстродействия. Соответственно, при обращении current->next данные там до сих пор, вероятно, лежат. А могут и не лежать.
Почитай про так называемые висячие указатели - это про это.
Правильно должно быть что-то вроде этого:
> void \* to_free = current;
> current = current->next;
> free(to_free);
Не нужно (нет предупреждения).
Кастить NULL нужно ТОЛЬКО при передаче в фции вида printf %p, бо там ждут void@, а не что попало.
но эти ифы не читабельны.
> Обязательно ли кастить малок в нужный тип? Или так и присваивать?
Нет, не обязательно. Но лично я всегда делаю явный каст, потому что если вдруг тип изменится, если вдруг я где-то ошибусь или произойдёт ещё чего-нибудь волшебное, компилятор без явного каста проглотит всё без проблем, а с кастом уже выдаст предупреждение о несовместимых типах. Отлаживать подобные ошибки - одно "удовольствие".
А насчёт того, что тебе кто-то говорил, что нужно, дело вот в чём. В Си не нужно, а вот в плюсах таки нужно. Если собирать сишный код плюсовым компилятором, то предупреждения всё-таки полетят.
бля, ну давай, расскажи, где в системной библиотеке линукса абстрактные деревья, хэштаблицы и прочие структуры данных для произвольных типов данных
но ведь если тупо написать
loh = malloc (sizeof ж loh);
то ошибки не будет ни при каком изменении типа
А зачем сишный компилятор, убогий и без библиотек.
"Си" это не язык и не компилятор, а способ программировать на плюсах со стороны Си, а не плюсов.
>Си-тред = С++
>С++-тред = С++
Вот так, а софт с названием "Си" это бесполезный мусор, устаревший еще 30 лет назад.
> но ведь если тупо написать
> loh = malloc (sizeof ж loh);
Верно. Многие так и делают, насколько мне известно. Но лично я предпочитаю, чтобы у меня на всякий случай было как можно больше раз упомянут тип, чтобы я всегда имел перед глазами то, с чем я работаю. Да, это многословнее, но всё-таки.
> double ж t = (double ж) malloc(10 ж sizeof(double));
Таким образом я ловлю опечатки в духе
> double жж t = (double ж) malloc(10 ж sizeof(double));
В остальном же это больше вопрос стиля и привычки. Кто-то вообще оборачивает всё это в #define NEW(), в этом тоже есть свой смысл.
>>2021149
Понятия не имею, если честно.
Я просто рассказал, почему, возможно, кто-то говорил, что каст нужен: нужен, но только в плюсах.
Ну и да, всякие библиотеки могут быть написаны так, чтобы компилироваться и под Си, и под С++, вместо того, чтобы иметь отдельную версию под Си и под плюсы.
> Ну и да, всякие библиотеки могут быть написаны так, чтобы компилироваться и под Си, и под С++, вместо того, чтобы иметь отдельную версию под Си и под плюсы.
Так не делают (попробуй написать нехелловорд и поймёшь). Просто вставляют extern "C" в заголовок.
Соглашусь.
Юзал rocksdb. Их сишный апи - это функции которые дёргают внутри С++ классы и их методы. Но я в принципе и не против.
> Так не делают (попробуй написать нехелловорд и поймёшь). Просто вставляют extern "C" в заголовок.
Ну, возможно, тут уж точно спорить не буду
struct mystruct_B
{
unsigned char DateStr[8];
unsigned char TimeStr[8];
unsigned short Lambda;
int X_sample;
int Y_sample;
int Z_sample;
}structb_t;
Должен ли я использовать extern int при условии что все переменные из данной структуры объявлены в другом модуле? И вообще что можно прочитать чтоб лучше понимать как работают указатели/ссылки в проектах с более чем одним .с файлом?
>current == NULL
Нахуй так писать, кста? И вообще где и какой мудень советует использовать NULL?
Что ты несешь? Поля структуры доступны только для переменных типа structb. В заголовке будет этот структ и extern structb s1, s2
Слушай я долбоеб что ты от меня хочешь? Я даже не знаю как проверить переменную, инициализирована ли она или нет, вот и на нул проверяю. Если объяснишь одной строчкой по ебалу то я буду благодарен. Но я и так прочитаю по поводу этой хуйни. Нужно будет почитать какие значения ставит Си при объявлений.
Переменные из структуры уже объявленны в заголовочном файле data.h, в моем заголовочном файле эти же переменные идут как extern, в связи с этим вопрос - должна ли структура состоять из extern int X_samole, или я слишком хитрожопый когда хочу запихнуть уже имеющиеся переменные и их значения в структуру?
>инициализирована ли она или нет
Братиш, ты чё ёпта, если ты не инициализировал её, то она не инициализирована, тем более локальная переменная, не обязательно будет иметь значение равное 0.
> слишком хитрожопый когда хочу запихнуть уже имеющиеся переменные и их значения в структуру
Это.
А как мне быть тогда если я хочу собрать значения из нескольких переменных и записать их в один буфер?
Используй оператор присваивания.
Есть модуль в заголовочном файле которого заданы переменные int X_sample, int Y_sample, int Z_sample, есть другой модуль в заголовке которого есть две переменные unsigned char. Во время выполнения программы в эти переменные пишутся данные, я хочу собрать эти данные в одну структуру и записать в 32-байтный буфер. Вопрос в том могу ли я объединить все вышеперечисленные переменные в одну структуру и они сразу же будут хранить актуальные значения или же мне нужно сначала определить структуру, в которой будет все что угодно кроме актуальных данных а потом передавать значения переменных?
Программа состоит из нескольких .с файлов(хз как назвать модулем или подпрограммой) , у каждого из них свои заголовочные файлы .h вот я хочу получить данные из модулей или подпрограмм и записать их.
>Программа состоит из нескольких .с файлов
Linkage unit (вроде)
Зачем ты хочешь собрать их в одну структуру? Может тебе оно не надо?
Ты тип для записи в одно место хочешь прочитать из разных мест, а потом писануть их разок в другое место, затем ты их собрался куда-то в третье место записывать, но уже методом по-проще, как я понял. Зачем всё это? Звучит как хуйня.
> Зачем ты хочешь собрать их в одну структуру? Может тебе оно не надо?
Мне надо их записать на флэш память физическую, поэтому я хотел их собрать в один буфер, а из буфера в физическую память.
> я хочу получить данные из модулей или подпрограмм и записать их
Так получи и запиши блять, зачем ты изобретаешь какую-то хуйню?
> Мне надо их записать на флэш память физическую, поэтому я хотел их собрать в один буфер
struct mystuct data = { .foo = some_var, .bar = some_other_var, .baz = some_getter(); }; // C11 initialization
struct mystuct data = { some_var, some_other_var, some_getter() }; // C89 initialization
struct mystuct data;
data.foo = some_var;
data.bar = some_other_var;
data.baz = some_getter(); // fine too
my_write(&data, sizeof(data));
Не надо никаких extern для структуры писать. Тебе эта структура нужна только чтобы записать, так сделай ее локальной переменной, и пусть она канет в небытие после записи.
char openglShaderSource[] = "
#include "shaderSourceFileName"
";
но конечно же не буквально так. А то неудобно шопиздец. Можно инлайнить и каждую строчку оборачивать в "...\n", а чтоб закрывающиеся кавычки шли под линеечку, приходится рекордить сложнейший макрос в виме. Можно в рантайме делать все это fopen, fseek, ftell, rewind, malloc, fread, fclose. Эскобар какой-то.
Пиздец, аноны, так не хочется в кресты перекатываться
https://stackoverflow.com/questions/410980/include-a-text-file-in-a-c-program-as-a-char
Попробуй вот так
> #define HEREDOC(...) #__VA_ARGS__
Ну и в коде
> const char text[] = HEREDOC(
> text "text";
> text text text;
> );
Это не то чтобы идеальный способ, но для твоих целей может подойти.
Деды умеют собирать ресурсы в объектный файл через ld в линуксах и использовать штатную возможность (ресурсы, windres/rc) в винде. Нет никакого смысла преобразовывать внешний файл в текст с эскейпами и всей хуйней, чтобы потом сишный компилятор преобразовал его обратно в изначальный вид.
тг @hepacika
Ну, не чмо, а долбоёб. Ради какой-то мелкой хуйни, которую можно пережить, свалил в кресты, у тебя раньше была одна проблемлка, теперь есть проблемы, которые добавят кресты. Если это не долбоебизм, я тогда не знаю даже. Суть донёс, чмо.
зато в крестах можно (будет) сделать std::embed("/etc/passwd"). представляешь, как здорово? http://open-std.org/JTC1/SC22/WG21/docs/papers/2020/p1040r6.html
чем? необходимостью постоянно писать :: перед функциями?
1280x720, 0:01
Там ещё цимес в том, что если ему нужно вставить в код именно шейдер, т.е. он пишет, скорее всего, какую-то игрушку или чего-то в этом духе, ему всё равно почти наверняка придётся писать с нуля процедуру загрузки файла с диска целиком во время исполнения. Для подгрузки текстурок там каких-нибудь или ещё чего-нибудь в этом духе.
Ладно, убедил нахуй. Возвращаюсь на Си.
заодно можно будет играться с шейдерами без перевыполнения билда
Возможно, синтаксис /etc/passwd?
>Ради какой-то мелкой хуйни, которую можно пережить
>ненужно
Ненужноиды - как плесень или черви, главный признак, что пациент скорее мертв, чем жив.
Аноны, как думаете, вот такое вот писать допустимо?
> int a[] = { 1, a[0] + 1 };
gcc вроде как кушает это без проблем, правильно вычисляя a[1], но я спрашиваю больше с точки зрения соответствия стандарту и портируемости.
>>2
О, большое спасибо, анончик, сотни нефти тебе.
Доставил быстро и решительно, всегда бы так.
и как я сам этот вопрос не нашёл
Вы видите копию треда, сохраненную 22 июня 2021 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.