Вы видите копию треда, сохраненную 5 ноября 2017 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
Пожалуйста, пользуйтесь https://ideone.com/ или http://pastebin.com/ для вставки кода, если он длиной больше нескольких строк или содержит [i] или ∗.
Что читать:
- Классика от Отцов: http://www.cypress.com/file/56651/download
- Годное пособие для гуманитариев: http://web.archive.org/web/20160727235220/http://c.learncodethehardway.org/book/ (автор внезапно захотел денег)
- Немного примеров хорошего стиля: http://www.oualline.com/books.free/style/index.html
- ООП, например: http://www.cs.rit.edu/~ats/books/ooc.pdf
- Стандарт ISO/IEC 9899:1999 (он же C99): http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf (драфт) не драфт ищем на торрентах
- Стандарт ISO/IEC 9899:2011 (он же C11): http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf (драфт)
- man/Dash/zealdocs
Чем конпелировать:
- Очевидный GCC.
- clang: оче годно, батя рекомендует.
- Intel C++ Compiler: оптимизации, тысячи их.
- Visual Studio 2017 Community Edition: внезапно этим стало можно пользоваться, особенно с тулсетом clang/C2. Поддержка C11 на уровне "есть все, что тебе понадобится в реальном проекте плюс кривая библиотека". Анализатор кода в комплекте.
- Pelles C (шиндоуз онли): поучиться, вкатиться в C11 (стандарт полностью реализован, имеются в том числе threads.h и прочие stdatomic.h), но количество багов в оптимизаторе и редкие апдейты напрочь отбивают желание собирать этим что-то сколько-нибудь серьезное.
- TCC: очень маленький компилятор с багами и неполной поддержкой C99. С ключом -run умеет компилировать код в память и запускать его, что позволяет писать скрипты прямо на сишечке.
Что еще почитать:
Stephen Prata "C Primer Plus, 6th Edition" (2014)
Свежая знает про C89, C99, C11, описывает различия, объемная около тысячи страниц, годная хотя есть некоторые шероховатости, с вопросами, упражнениями и ответами. Читать после K&R или до.
http://c-faq.com/
FAQ из comp.lang.c. Древний, но все еще актуален.
Samuel P. Harbison, Guy L. Steele Jr. "C: A Reference Manual, 5th Edition" (2002)
Ебаный пересказ стандартов C89 и C99 (включая стандартную библиотеку). Для не осиливающих стандарт в оригинале. Читать в качестве подготовки к собеседованиям (есть задачник с ответами) и для ознакомления с масштабами пиздеца перед написанием своего парсера/компилера.
Peter Van Der Linden "Expert C Programming. Deep C Secrets" (1994)
"Си: грязные истории". Смехуечки, немного объяснений, чем обусловлены особенности языка, всем известные подводные камни кто там ругал косяки в JS? у нас в сишечке их гораздо больше, просто они лучше спрятаны, немного байтоебли и непонятно откуда взявшаяся глава про старинные плюсы. Читать в качестве сказки на ночь (на пару вечеров хватит).
Richard M. Reese "Understanding and Using C Pointers. Core Techniques for Memory Management" (2013) - почитать, вкатиться в указатели.
Ben Klemens "21st Century C: C Tips from the New School" (2012)
Paul Deitel, Harvey Deitel "C for Programmers with an Introduction to C11" (2013)
Stephen G. Koch@n "Programming in C (3rd Edition или 4th Edition, если найдется)" (2014)
MISRA Ltd. "Guidelines for the Use of the C Language in Critical Systems" (2013)
Набор рекомендаций по написанию надежного кода на C (промышленный стандарт). Читать - однозначно, следовать - вдумчиво и без фанатизма. Также можно посмотреть https://www.securecoding.cert.org/confluence/display/c/SEI+CERT+C+Coding+Standard
Еще более длинный список: http://www.iso-9899.info/wiki/Books#Learning_C
Онлайн-утилиты:
- https://godbolt.org/ - Compiler Explorer позволяет посмотреть выхлоп компиляторов для введенного куска кода (больше полусотни разных версий компиляторов).
- http://cdecl.org/ - С Gibberish ↔ English помогает читать сложные сишные декларации.
Прошлые треды:
- №20: https://arhivach.org/thread/254158/
- №21: https://arhivach.org/thread/260316/
- №22: https://arhivach.org/thread/262491/
- №23: https://arhivach.org/thread/277223/
Шапка: http://piratepad.net/bJ1SdmkZyu
первыйнах
Из-за вас я сначала думал, что вертикальный членец в капче это побитовое "ИЛИ"
>Что читать:
>- Классика от Отцов: http://www.cypress.com/file/56651/download
Access Denied
You don't have permission to access "http://www.cypress.com/file/56651/download" on this server.
Ну нифигасе. Дают линк, доступный только избранным... так предупреждайте, что не для всех.
Хотя бы как книга называется?
А если я поучу по книге 80х годов (там классно написано) - смогу откомпилить?
Или современные компиляторы несовместимы со старыми версиями C?
Там рассматривается си в стандарте 89 года надо читать второе издание, в первом рассматривается старый си. С89. С тех пор вышло только 2 стандарта - С99 и С11. В принципе любой компилятор будет поддерживать С89, так что проблем не возникнет.
>С.Прата
Есть шестое издание, там уже рассматривается самый свежий стандарт С11, на торрентах есть.
Называется Язык программирования Си Лекции и упражнения
У тебя могут возникнуть некоторые проблемы. Старый синтаксис поддерживается, но категорически не рекомендуется. Почему именно эта книга? Почему нельзя взять прату или к&р из шапки? Ты любишь сложности?
Но таких иллюстраций уже нет, и к тому же она бумажная, издана качественно на хорошей бумаге - читать приятно. Прямо влюбился.
>Старый синтаксис поддерживается, но категорически не рекомендуется
Можно пример старого синтаксиса, который категорически не рекомендуется?
Строки?
Дополнение: только не VC++, что-нибудь полегче.
Спасибо
Неявный инт? Не думаю, что это такая уж огромная неприятность.
> return 12345
А так никто со времен Кернигана и Ритчи не делает. Корректно завершившаяся программа должна вернуть ноль.
Я скорее про пустые скобки вместо (void), про старый синтаксис аргументов, но и про неявный int тоже помнить нужно.
> Корректно завершившаяся программа должна вернуть ноль
А моя некорректно завершилась с кодом ошибки 12345. Я автор, я так вижу.
https://www.youtube.com/watch?v=3mgGQR6oGxI
На пикрил функции для основными действиями с этим типом: sigaddset - добавить сигнал в набор, sigdelset, sigismember - проверить, является ли сигнал членом сета.
Функция sigdelset непонятна. Почему в add нет лишних скобок в правой части, которые есть в del?
Алсо, почему в sigdelset вообще происходит выключение нужного бита, ведь там побитовое И?
И эти операции не должны затронуть остальные биты, а sigdelset занулит же там всё, не?
>Функция sigdelset непонятна. Почему в add нет лишних скобок в правой части, которые есть в del?
Имхо, вкусовщина - просто выделили выражение мкобками, хотя я не эксперт в Си
Согласен.
Ну кому как.
Написал алгоритм проверки номеров кредиток и заодно самотест к нему (первые 4 и последние 4 цифры взял от реальной карты). Сам не погромист ни разу.
https://pastebin.com/nAZ5mQkb
*первые 6 и последние 4
си для этого нинужон
Написано что нужно использовать -E или -E -dM. Но оно ничего подобного не выводит.
Может и удобней, я когда пробовал мне лень было файл создавать.
по идее ошибка. забыли ~.
Ну, при приведении к sigset_t реализация автора, как я понял, всё в единицы обращает.
или даже единицы в обоих местах нужно привести к sigset_t. просто если sizeof(sigset_t) > sizeof(int) то работать не будет.
Или есть какие-то годные варианты, которых я не знаю?
Не ради траллинга спрашиваю. Чем занимаются си-пограммисты?
Даже C++ не расширенная версия Си. Они эволюционировали по своему и у них свои стандарты. Есть такие вещи которые не существуют в C++, например как массив переменной длины, а так же сложные числа. Но обратно же, такие вещи как объекты, шаблоны, стандартные библиотеки не поддерживаются Си. Можешь почитать об этом на досуге.
Во встроенных системах и системном программировании, Си все еще главный доминирующий язык, потому что ты, обычно не нуждаешься в объектах нежели в обращений к низкоуровневым вещам типа прямого интерфейса оборудования. Более того, у тебя более точные требования по времени и вместительности доступной памяти. Представь как бы ты вместил кучу информации с высокой подачей с помощью объектов С++ в пяти сот байтов микро-контроллера оперативки? Линуксы написаны на C. Другие же языки, даже включая C++, предназначены для других нужд, и в глаза Линукса он - Ужасен.
Большинство людей кстати после выхода Си остались на Ассемблере, боялись уходить от традиций. Несмотря на то, что у Си был намного лучше код.
С++ стал другим языком для других нужд, пусть даже и похожим на Си, но он потерял низкоуровневые способности, типа доступа к процессорному влиянию. Т.е такие языки как Си или Фортран это системные языки.
Да, есть годные варианты, о которых ты не знаешь. Но я намекну, почему он все еще популярен в наше время: Операционные системы, Языковые компиляторы, Ассемблеры, Интерпретаторы, Дата-Базы, Драйвера, Утилиты, Движки игр и списочек продолжается.
Я взялся за него, потому что Страуструп сказал в своей книжке, мол, что я обязан знать Си, чтобы изучить C++ и использовать его полную силу. Да конечно не обязательно знать Си, чтобы пользоваться С++, но я подумал, знание еще одного языка это не помеха, а лишь еще одно преуспевание.
Задача: при вводе a,b,c выводить "Right", при вводе q завершать программу, при вводе остальных знаков писать "Wrong".
Вот мой код:
#include <stdio.h>
int main (void){
char c;
while (scanf ("%c",&c), c != 'q')
{
if (c >= 'a' && c <= 'c')
printf ("Right \n");
else
printf ("Wrong \n");
}
return 0;
}
Ввожу a получаю :
Right
Wring
Ввожу e получаю :
Wrong
Wring
Где ошибка? Заранее благодарю.
На вход поступает символ '\n', тебе нужно от него избавиться, например, так:
Ему нужно чтобы при каждом неправильно набранном значений об этом намекалось.
Т.е введет adc
Должно выводиться - right wrong right
Если abc - Right Right Right
Если ggg - Wrong wrong wrong
У тебя условие истинно в любом случае, алсо wrong тоже выведется, потому что значение истинно.
Спасибо
Если ввести bac cab bca cba и т.д выводится right
Если ввести abcabc выводятся лишние значения
Если ввести bbb или aaa или ccc выводится - Right
Будут годные советы? Кто нибудь?
>Там для 31 различных
ну, int может быть и 16 битным.
либа для какого-то специфичного устройства?
ну да он вряд ли на 16 бит запускаться будет.
достаточно вспомнить разность int,long на винде64 и лине64.
>>Там для 31 различных
>ну, int может быть и 16 битным.
Если signet_t, значит это POSIX. Если POSIX, то int не может быть 16-битным. См. http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html
Сравнивать программирование с написанием веб-говна на PHP нельзя. Ты бы еще PHP в математикой сравнил. Это разные вещи.
Вчера вот заглядывал в сырцы Python - так там куча .c и .h файлов. Уверен, что и много другого интересного софта написано на C. А чтобы его например пропатчить, нужно C знать. Да и вообще это другое программирование, нежели на скриптоязыках. Ты программированием ради денег занялся или тебе что-то в нём понравилось?
Не совсем понял условие, но наговнокодил вот это: https://pastebin.com/yR5RxYTS
Сам начинающий, прошу кому не влом - максимум критики по коду.
>Если signet_t, значит это POSIX
да вроде ничего это не значит. как захотят так и сделают, в контексте ос.
сложно это всё.
http://www.programming1189.ru/files/Kern_Ritch.pdf
Потому что программист должен знать английский, тем более, если он не на сишечке пишет, а не на каком-нибудь jQuery. А что касается третьего издания, то изданий два, а русское "третье" - багфикс для русского перевода второго.
>Потому что программист должен знать английский, тем более, если он не на сишечке пишет, а не на каком-нибудь jQuery
такте то комплексы.
Очередной типичный для программистов таракан, что поделать.
Какие комплексы? Большинства годных статей на русском нет. Либо ты макака, потому что тебе негде учиться, либо ты осознаешь ситуацию и учишь язык. Это не говоря уже об общении с другими программистами и комментариях в коде.
у тебя какая-то каша в голове. с чего ты решил, что всем нужно читать годные, что есть только на английском, твоему мнению, статьи, и читать исходники на английском?
какой-то максимализм выпирает. как кто хочет, так пусть и учится. ты лучше свои навыки реализовывай и не выёбуйся.
>Counter
Я тоже об этом подумал, но ты тут очень много кода впихнул. Можно создать набор символов - образцов и потом программа по ним делает сравнение, но и у тебя неплохая идея со счетчиком. Т.е псевдокод -
Принять значение
Сравнить с [Переменная]
Все совпадения Right
Вывести
Несовпадения Wrong
Вывести
Он прав вообщет. Я специально занялся английским, потому что русский контент сосет жепу, редко найдешь учебное пособие которое переведено как следует. Везде провалы. Да и ресурсы в основном где пишутся полезные статьи, фичи, алсо конференций, В россии кто нибудь C конференций устраивает? Интервью с Брайаном Керниганом, расширенный набор книг по программированию от разных авторов, спецификации вместе с драфтами, да куча всего на английском. И поэтому нужно обязательно знать английский, особенно если ты хочешь чего то добиться. А так если ты программингом занялся ради смехуечков и пиздхаханек то для этого подойдет какой нибудь, ну... Язык для создания приложений для телефончиков?
Там перевод пиздец какой корявый. Например:
>Напишите программу, копирующую символы ввода в выходной поток и заменяющую
стоящие подряд пробелы на один пробел.
Т.е спрашивается, какой нахуй выводящий поток? Напиши как в книжке -
Напишите программу копирующая ввод в вывод, заменяя каждую последовательность нескольких пробелов одним.
Все. Сложно?
И так вся книга.
джвачую, ребенок еще не понимает, что важные вещи даже на англопидерском никто писать не будет
Верно.
> Большинства годных статей на русском нет
Знать английский и читать технические (научные) статейки не одно и то же. В студенчестве я регулярно делал доклады по алгебре с англицких книжек. Однако не мог без субтитров смотреть даже мультики для детей-аутистов, а любая неадаптированная книга уже на первой странице содержала сотню незнакомых мне слов.
Для вопросов на стековерфлоу хватает английского уровня гуглопереводчика.
Собственно, в этом и смысл. Человека >>1056888 спросили, почему нет русского перевода в шапке? Самый первый пришедший в голову ответ был не "потому что перевод плохой" могу сказать, что он не плохой, а потому что ТЫ ОБЯЗАН ЗНАТЬ АНГЛИЙСКИЙ, ЕСЛИ ТЫ НЕ МАКАКА. Логика прослеживается, конечно, но связь между вопросом и ответом ОЧЕНЬ опосредованная и явно прошла через цепочку когнитивных искажений. Я, если что, хорошо знаю английский, просто мне бомбит с тех, кто делает из него священную корову по поводу и без.
Я все книги по программированию читаю на английском. Я даже не смогу те обороты речи и слова по русскому сказать
>нихуя не надо знать английский для программирования
Мы приняли твое мнение во внимание На самом деле нет.
>то у меня для вас плохие новости
Всем похуй на твои новости.
>это уровень седьмого-девятого класса.
Так хули ты не выучил то?
Всем так интересно.
Тебе? Мазь купи в аптеке. И свечки анальные.
Надо только профессионалам. Для обычного программирования на русском информации более чем достаточно.
Что говорит о твоей убогости, если ты не знаешь терминологии на своем языке.
Спасибо!
Хорошая идея, спасибо что напомнил бро!
Основное правило такое: хедер должен включать свои зависимости. Если в хедере используется uit8_t - подключаешь stdint в хедере. Ну и очевидно, что в парном .c подключать stdint не нужно.
Если что, вся эта простыня говнокода аллокейтит новый argv через анусай, после чего запихивает туда имя обрабатываемой вебсервером в данный момент страницы.
Частично портабельно (на соплярис).
А вот во фряхе вместо всего этого ебалова есть setproctitle()
Хуя бог.
хукта какаято
Типа:
func(arg, {1,2,3,4});
Ну или хотя бы объявить сразу здесь же? А то чот очень душно как-то получается. Извиняюсь, если проморгал этот момент.
Спасибо.
Включал вот так :
#include <locale.h>
setlocale(LC_ALL, "Rus");
в системе: плохая).
Поройся в настройках среды, обычно можно кодировку менять. В кодеблокс это edit -> file encoding
Спасибо.
Юникод.
Это для чего так? Т.е значение совпадает с кодеком. Как это работает?
Не очень хочется выдрачивать велосипеды. Подскажите, если кто знает, пожалуйста.
Текущая версия не нравится "pw" и обилием "w".
>Стремлюсь к кратким наименованиям, полные порой выглядят жутко
Пиздуй читать "Чистый код", говно.
Я так не напишу ничего и останусь нищим. Ответь на вопрос, пожалуйста. Хотя спасибо, пролистаю всё таки.
Да ты охуел! Не согласен с книжкой. Гораздо проще один раз посмотреть на структуры и комментарии к ним, а потом беззатруднительно читать весь остальной, компактный код. Конечно, есть место длинным наименованиям, но это нужно далеко не везде, я думаю. Потому скажи мне как назвать структурку и её элементы.
каким образом это может решить компилятор, вставлять ассерт после каждой инструкции?
есть же специальные инструменты.
Ну у компилятора-то возможностей куда больше, он может вставить что-то типа jnc, jc, jo, jno - однобайтовая инструкция, выполняется один такт. Жалко только, что стандарт предпочитает неопределённое поведение, видать на ПДП подобной хуйни не было.
>есть же специальные инструменты.
Ты про какие? Те которые проверяют исходный код или которые позволяют работать динамически? Если про последние, то линкани, пожалуйста. Собственно мне нужна функция навроде __builtin_add_overflow из GCC, только что бы по-переносимей.
да фиг знает, чёт сам сижу читаю по поводу.
как минимум это что-то должно знать контекст.
Ананасы, как вы, погромируя всякие железки, определяете оптимальный размер стека? Я вот пишу хуйню на броадкомовском говно-сдк, в котором обычному printf в uart с какого-то хуя нужно 4096 байт стека, постоянно ловлю всё новые и новые stack overflow. Размеры рассчитываю на глаз и включаю заодно runtime-проверки операционки, конечно и заебался уже так делать.
add eax ebx
mov ax (или как там) %куда-то там
и типа это конвертация из инта в чар, по беззнаковому это стандартно, знаковому - нет. как это, например проверять, знаковый вариант? (char)((int)a + (int)b);
по идее же надо будет проверять диапазоны обоих, а потом и результат?
а например такой контекст = (int)a + (uint)b
будим считать за переполнение, когда a < 0 и скастуется к uint ?
тогда нужно проверить a на 0 =< a <= INT_MAX . хотя это вроде стандартное поведение.
просто размышляю. наверно реально, если компилируется без оптимизаций. может флаги есть в гцц?
мне кажется, что читаемость больше зависит от твоего умения вовремя отделить код в функцию и организовать структуру.
> Потому скажи мне как назвать структурку и её элементы.
typedef struct {
GLFWWindow *physicalWindow;
unsigned int width, height;
} Window;
Если не нравится - иди решай свои проблемы - научись печатать более чем одним пальцем, купи себе монитор с разрешением выше 640x480, найди IDE с автодополнением, если ленивый. А в комментариях пиши не расшифровку своей тарабарщины, а полезные вещи.
Это не я так сказал, так пишут все нормальные люди. В том числе и те, кто когда-то был ньюфагом и злоупотреблял короткими именами.
> купи себе монитор с разрешением выше 640x480
У меня 1024x768! А иды не нужны, ровно как и твойУёбищноеНазваниеПеременныхБлядь. Мне гораздо приятнее читать код состоящий из кратких переменных. Достаточно понимать принцип выбора названий и область под которую погроммист пограммит.
> Достаточно понимать принцип выбора названий и область под которую погроммист пограммит
и код будет прекрасно читаться.
Так, как делаешь ты, на самом деле делают далеко не везде, и раньше я такого вообще не видел, но тут только с дивана могу говорить.
> Мне гораздо приятнее читать
Если проект - твой собственный, и кроме тебя его читать никто не будет - пиши, как тебе нравится. Хоть весь юникод на однобуквенные переменные заюзай. Но помни, что если кому-то вдруг придется это читать, он будет крыть тебя матом каждую ебаную секунду.
>Хоть весь юникод
нельзя же.
> что если кому-то вдруг придется это читать
да и пусть нахуй идёт.
к чему все эти доёбки? если на работе как-то нужно писать по особому, там же на месте и ознакомят с правилами.
а то пиздец, пиши для себя как хочешь, но не показывай никому, а то тебя материть будут.
> нельзя же.
В C99 запилили extended identifiers. Весь юникод, конечно, нельзя, но символов, которые разрешено использовать в идентификаторах - овердохуя.
жёстко. я смотрю можно прям в кодах \u1234()
Помогите удостовериться.
Массиву character[TNOCHAR] присваивается 128 имен
Им присваивается каждому 0
Далее идет пересчет каждого введенного совпавшего символа
++character[c];
Запускается цикл который выводит 128 символов
Тут самое важное
Запускается еще один цикл который сравнивает значение j со значением Попавшихся совпадений character[Любое совпадение в character[c]] и инкрементируется значение j до кол-ва попавшихся character[c] и выводится кол-во символов '*' и символ новой строки после того как совпадения закончатся.
Все верно?
У тебя там в ideone чуть ниже есть standard input. Введи туда свои символы и посмотри, что получится. Но хуй знает, описал ты это, конечно, коряво. 128 имен каких-то, совпадения какие-то. Гистограмму оно строит. Все блять.
Ну конвертация-то в более узкий тип - совсем простая операция, только границы проверяй. Тот же х86, вроде бы, имеет одтельную инструкцию проверки диапазона.
Кстати же, придётся проверять ещё и деление для случая SIGNED_MIN / (-1), ну а SIGNED_MIN % (-1) по идее аппаратно вылететь должен.
Для типов меньше 64х бит можно привести данные к более широкому, проверить и отсечь если попадают в диапазон. Вот тут https://blog.regehr.org/archives/1139 мужик пишет, что относительно шутсрый метод. Для максимальных же, один пёс придётся выполнять проверки, а для знакового ещё и пилить умножение руками. Ещё можно учесть, что некоторые компиляторы-таки поддерживают безопасные операции, в ряде случаев можно наассемблерить необходимые проверки, и по итогу получить кромешный пиздец из ифдефов. Какая же ебаная хуита, простите.
На будущее, чтобы инициализировать все элементы целочисленного массива нулями, достаточно написать массив[вместимость] = {0}
Решил реализовать эту часть алгоритма на Си, а конкретней:
1. парсинг pcap файла
2. запись данных в БД постгрес
Если со вторым пунктом ясно всё и нагулится, то насчёт первого не уверен.
Какие будут советы/варианты вообще и по первому пункту в частности?
p.s. думаю моих знаний в Си хватит для этого, более чем.
Чё, вместо цикла = {0} справа приписать тяжело? Я, правда, не уверен, что это достаточно портабл и вообще работает в си, а не в крестах.
Это есть в стандарте. Когда ты инициализируешь один из элементов, остальные заполняются нулями. В данном случае инициализируется первый, и слегка непортабл это только когда нулевые указатели хранятся не в виде последовательности нулевых битов. Но я таких ебнутых машин не знаю.
В мире фей, где нет старых компиляторов может означать. Но там это может что угодно означать, что пыльца в соцветиях ноздрей хоботов голубых слонов созрела, например. Мир фей же
Ну не тяжело, но должно быть понимание базовое, хотя бы почему и когда это делать. Пока как говориться, велосипед поизучаю, а там уже и буду экспериментировать.
В моем мире поддержка хотя бы C89 есть под каждую необходимую мне железку. Если мне вдруг встретится что-то, не поддерживающее C89, я не стану называть это компилятором Си. Это будет компилятор кастомного языка с C-like синтаксисом.
Да, это есть в C89. А я, в свою очередь, прошу прощения за разговоры о непортабельность инициализации указателей - все там нормально инициализируется, вне зависимости от представления в памяти, а описанные выше проблемы возникают при попытке делать обнулять через memset(..., 0, ...).
Чувак, я знаю вывод. Программа написана правильно и видимо ты ее не понял, как и контекст вопроса.
Про массив сказал, ещё кое-что:
1) Отделяй операторы пробелами от операндов, а ещё ставь пробел справа от знаков типа , или ; -- когда будешь писать вещи хотя бы немного сложнее читаемые, чем двойной счётчик, отсутствие пробелов глаза ибат жоски будет.
2)Маловажная ремарка: каноничноъ в for-цикле пользоваться пост-инкрементом/декрементом, а не пре-. С массивами (т.к. индексация с нуля) удобнее задавать счётчик как for (i = 0; i < zalypa; i++), но во всех остальных случаях читабельность повысится при отсчёте с единицы: for (i = 1; i <= zalypa; i++).
Я так-то тоже вкатывальщик, просто немного подальше закатился, оэлдэфаги, можете обоссать
Например, у меня есть структура, несколько полей которой принимают ссылку на область памяти double(звездочка). Есть функция delete_struct, которая проходится по этим полям free().
Можно сделать так, чтобы программа не ломалась из-за попытки очистить память в куче?
Тут с примером чуть понятнее: https://pastebin.com/exxrwWjh
щито?
> каноничноъ
Труъ эстеты пишут с преинкрементом, потому что у него нет специального поведения в отличие от постинкремента.
>>1058876
Нет, нельзя. К тому же, есть еще вариант статически выделенных данных. Ты, конечно, можешь нагородить платформенно-зависимый костыль (ну там, регион стека детектить, с секцией данных сверяться), но сделай лучше флажок в структуре, не выебывайся.
так никто не делает. пишут функции конструктор и деструктор
в твоем коде непонтяная хуита с ошибками.
В общем, не понимаю я логики работы с включениями исходников - все эти заголовочные файлы и прочее. В книжках нашел только общие положения, на всяких хабрах - то же, либо какие-то рецепты для конкретных случаев. Нипанятна.
А теперь суть проблемы. Допустим, есть у меня некий файл first.h. В нем мы определяем константу coeff типа int:
#ifndef FIRST_H_INCLUDED
#define FIRST_H_INCLUDED
const int coeff = 5;
#endif // FIRST_H_INCLUDED
Далее создаем заголовочный файл second.h. В него пихаем определения функции:
#ifndef SECOND_H_INCLUDED
#define SECOND_H_INCLUDED
#include "first.h"
double func(double x);
#endif // SECOND_H_INCLUDED
Функцию определяем в файле second.cpp. В нем "инклудим" second.h и используем константу coeff (наверное и так понятно как должно выглядеть). В мэйне подцепляем second.h и вызываем функцию func. Типа по моим понятиям должно работать. Однако оно выдает ошибку multiple definition of coeff. Как правильно надо включать файлы, чтобы я мог и константой воспользоваться, и чтоб компилилось?
Заранее извиняюсь что без разметки, но кода мало, вроде как можно обойтись.
Не делай константы через const. Это плохо работает, не всегда нормально оптимизируется и все такое. Делай через #define как люди. Если все же хочешь, чтобы работал твой вариант, у тебя два выхода: сказать, что константа statiс или писать в хедере, что она extern, а реальное определение пихать в один из .c файлов.
на самом деле в реальной программе там строка const char*, мой пример искусственный и чисто модельный. А строку можно дефайном вставлять?
Хм. Щас попробовал перенести строчку #include "first.h" из файла "second.h" в файл "second.cpp" и все заработало. Странно это...
не ври. все должно работать
Ну а отвечал я про примитивные типы вроде double или int. Со строками все зависит от того, зачем тебе строка (дубликаты строк не все компиляторы схлапывают). В общем и целом, лучше делать extern в .h, строку в .c.
const int coeff = 5; это глобальная переменная
ты инклудишь в second.cpp и там это переменная, и в main.cpp и там тоже эта переменная.
ты перенес инклуд, и в main.cpp больше нет объявления этой переменной
короче, иди читай как работает конпеляция и линковка в си. это азы, без которых ты ничего не поймешь
static ограничивает видимость модулем (объектным файлом, единицей компиляции). Если extern - это определение (definition), то его видно извне, а если это объявление (declaration), то объявление для него может быть в другом модуле.
>extern - это определение (definition), то его видно извне
extern значит, что переменная определена в каком-то другом cpp-файле или подключаемой библиотеке. тогда во время линковки заместо этой переменной будет подставлен адрес этой другой определенной где-то переменной с таким названием
Ощм немного прояснилось, но буду еще разбираться. Аригато гадзаимас, анон.
Проиграл. Чувак, программу не я писал, я написал объяснение её работы и спросил - Верно ли я понял? А писал ее профи.
#include <stdio.h>
main(void)
{
int integer1, integer2, sum;
printf("Enter first integer\n");
scanf("%d", &integer1);
printf("Enter second integer\n");
scanf("%d", &integer2);
sum = integer1 + integer2;
printf("Sum is %d\n, sum");
return 0;
}
так-же нужно отметить, что модификатор extern дефолтный для всех объявлений функций
#define _CRT_SECURE_NO_WARNINGS
А вот это нахуя меня просят писать, чтобы скомпилировать программу?
Отключает бугурт компилятора студии по поводу использования "небезопасных" функций. Т.е. большинства, где используются указатели в том или ином виде.
Надо понимать, что Visual Studio - это не среда для разработки на Си. Это среда разработки на Managed C++. Да, в плюсах, даже управляемых, есть возможность использования сишного кода, но приходиться попердеть с директивами препроцессора или unmanaged вставками.
Ты просто определись: либо ты пишешь на си, либо не на си. Майкрософтоподелия к си имеют весьма посредственное отношение. Назначение Managed C/C++ только в том, чтобы делать врапперы для нэйтивных библиотек в комовскую оболочоку, с последующим вызовом их из управляемого кода, написанного на любом языке .net семейства. Программы на нём пишут только дэбики уникумы.
Проблема в том, что все остальные IDE выглядят как куски говна, поэтому делаю задания из книжки в VS. Вот как-бы и все. А почему так вышло, что они небезопасные?
Давай спустимся с небес идеального кодинга на землю ради ответа на простой вопрос, который мучает меня: почему некоторые люди не ставят пробелы?
>А почему так вышло, что они небезопасные?
Потому что Стив Балмер так решил. А вообще тебе нужно почитать про дотнетовский CLR, управляемый/неуправляемый код, всякую хуиту про ООП и отличия указателя от ссылки. Здесь всё же Си обсуждают.
>что все остальные IDE
Может быть местные гуру меня поправят, но Си - это не "эй поцоны, я ДЭВЭЛОПЮ код на макбуке в няшной ИДЭ с дарк интефейсом". Си - это системное программирование, линукс кернел и ымбыдед. Поэтому либо пользуешься специализированными IDE вроде Keil4 или VisualDSP++, которые облегчают процесс разработки говнокода под конкретные платформы. Либо превозмогаешь себя и пишешь код в блокнотике, параллельно постигая make и gcc.
В качестве блокнотика могу посоветовать VS Code, если уж так любишь майкрософтоподелия
>А вообще тебе нужно почитать про дотнетовский CLR, управляемый/неуправляемый код, всякую хуиту про ООП и отличия указателя от ссылки.
>Либо превозмогаешь себя и пишешь код в блокнотике, параллельно постигая make и gcc.
Постой, шеф. Я открыл только первую книгу по программированию.
Потому что у каждого свой стиль.
>Visual Studio - это не среда для разработки на Си. Это среда разработки на Managed C++
Чо? Можно же писать на unmanaged C++, и на С89С95/АМD1 офк. А если прикрутить clang/c2, то еще и С11 будет
Строчка 34: объясните подробно, пожалуйста, почему так передавать второй аргумент в функцию нельзя? И правильно ли я использую двумерный массив в таком случае вообще? Это задачка на моделирование "черепашьей графики".
С помощью класса
можешь показать в коде? допустим у меня есть массив а[5]. Как мне его увеличить?
> А почему так вышло, что они небезопасные?
Такими сделали. Когда дизайнилась стандартная библиотека, об уязвимостях еще не думали. И "небезопасность" таких функций не в использовании указателей, как говорят ньюфаги выше, а в отсутствии контроля границ или недостаточной сигнализации о том, что данные в буфер не влезли: например, печально известная gets() пишет данные в буфер, но не позволяет ни указать его максимальную длину, ни сигнализировать о том, что буфер переполнился. А, например, какая-нибудь snprintf, сделанная позже, и, вроде бы, правильно, позволяющая указать максимальный размер буфера, возвращает не количество записанных в буфер символов, а нахуй не нужное количество символов, которое могло бы быть записано в буфер бесконечного размера. При этом, чтобы узнать, что буфера не хватило, тебе нужна явная проверка, а если ты поленишься (очень многие ленятся), то в твоей программе появляются truncation-уязвимости (приходит тебе такой аттачмент в письме foo(многобуков).exe.jpg, пишет такая программа его на диск, делает snprintf(filename, MAX_PATH, "%s/%s", temp_folder, attachment_name), а оно не влезает, обрезается, и на диск летит уже foo(многобуков).exe). И вот Microsoft для решения этой проблемы придумала подмножество _s (safer) функций, которые фэйлятся, если что-то не влезло, и даже пропихнула их в стандарт (Annex K), но оно никем, кроме Microsoft не поддерживается, и там есть проблемы с runtime constraint handlers, и, в общем, почти никто ими не пользуется, кроме самой Microsoft. И ты не пользуйся, но о проблемах стандартной либы помни.
commands - одномерный массив, ты не можешь индексировать его дважды. Алсо, несмотря на то, что ты там при инициализации понаставил фигурных скобок, он остался одномерным, и инициализаторы просто записались в него по порядку ([0] = 2, [1] = 5, [2] = 12, [3] = 3...). Сделай либо нормальный двумерный массив commands[COMMANDS][2], либо массив указателей на массивы int, можно с compound literals (С99) примерно так: (int *array[] = { (int[]){ 1 }, (int[]){ 5, 12 }, итд }).
Почему говорят, что "функция возвращает void", если на самом деле она ничего не возвращает? Как говорить правильно? Что такое на самом деле void? Как он работает?
Формально void это даже тип данных. Если это слово стоит перед функций, то значит функция ничего не возвращает. Т.е так и говорить, "функция ничего не возвращает", или возвращает пустоту
бамп вопросу
https://ru.wikipedia.org/wiki/Кольцевой_буфер - вот что мне нужно, только чтобы увеличивался/уменьшался при необходимости
Потому что внутрь процессора менеджер кучи как-то не получилось запихать, а Си - достаточно низкоуровневый язык.
У меня в массивe *sys_siglist[] в строках забиты описания сигналов, даже имя не вычленить.
А большая часть функций, которые что-то печатают о сигналах (например, strsignal), обращаются именно к нему.
Придётся делать, как в kill сделали (массив структур sys_signame)?
https://github.com/karelzak/util-linux/blob/master/misc-utils/kill.c
Каждый сигнал с ifdef'ом инициализировать, это же мрак.
А куда пропал оф. тред плюсов?
Нужно прочитать символ 'a', 'm', 'e', 's' или 'd'. На остальные вывести сообщение об ошибке.
Заранее спасибо.
goto l1;
while (ch != 'a' && ch != 'm' && ch != 'e' && ch != 's' && ch != 'd' ){
printf ("Введите корректный варинт\n('a', 's', 'm', 'd', 'e')\n");
l1:do {
ch = getchar();
}while(!isalpha(ch));
}
goto не для долбоебов, но и не для этого случая.
do { ch = getchar(); } while (ch != EOF && ch != 'a' && ch != 'm' и т. д)
if (ch == EOF) { поток ввода кончился } else { нам дали требуемый char }
Спасибо ещё раз.
#include <stdio.h>
int main(void) {
int r, pi, circ;
printf("Radius: \n");
scanf("%d", &r);
printf("Diameter is %d\n", r 2);
pi = 3.14159;
circ = 2 r * pi;
printf("Circumference is %f\n", circ);
}
> int pi
В советской россии пи равняется трем, ага.
int - это integer, целое. Не дробь. Дроби хранят в float или double, это типы с плавающей точкой. Можно еще в фикседпоинте, или даже явно в виде числителя/знаменателя, но тебе это пока рано.
Соответственно, double pi (так как десятичная дробь), double circ (так как после умножения дроби на целое ты чаще всего хочешь дробь), и все у тебя будет.
Алсо, лучше сделать pi не переменной, а константой:
#ifndef MATH_PI
#define MATH_PI 3.14159265358979323846
#endif
(или сделать #define _USE_MATH_DEFINES и подключить math.h, оно тебе определит M_PI в числе прочего, но это слегка нестандартная хуйня).
Ахда, не работает конкретно потому, что в printf ты передаешь int, а спецификатор %f хочет дабл, такие дела.
Пасиба, брат. Я когда делал просто вписал Пи ручками и все получилось. А еще такой вопрос, вот такие рисунки можно делать только если в каждый новый принт новую строку рисовать, т.е. рисовать все четыре одновременно или можно сделать по отдельности фигуры и проще?
Можешь создать массив достаточных размеров, а потом распечатать его:
#define SCREEN_WIDTH 80
#define SCREEN_HEIGHT 24
char screen[SCREEN_HEIGHT+1][SCREEN_WIDTH+1];
// Очищаеш (плюс сразу переводы строк втыкаешь, чтобы быстрее выводить).
for (size_t y = 0; y < SCREEN_HEIGHT; y++) {
for (size_t x = 0; x < SCREEN_WIDTH; x++) {
screen[y][x] = ' ';
}
screen[y][SCREEN_WIDTH] = '\n';
}
screen[SCREEN_HEIGHT][0] = '\0';
// Рисуеш.
screen[10][10] = '*';
// Выводиш.
puts(&screen[0][0]);
Но вообще у тебя задание скорее всего предполагает именно одновременную отрисовку в едином цикле (т.е., в зависимости от Y координаты ты рисуешь звездочки и нужное количество пробелов в текущей строке для каждой фигуры, потом перевод строки, потом следующую строку так же и т. д.). Можешь тоже буфер сделать шириной с фигуру, тогда не придется ебаться с пробелами.
говноед - это тот, кто дрочит на инструментарий
в анус себе свои преференции запихай и пиздуй на пары
да, я их все помню. а если у тебя вызывается 500 штук этого говна, то ты не тру погромист.
мимоэксделфибог
А где оно глючит-то? Если ты про /n, то да, у тебя кривые руки - escape-последовательности пишутся с бэкслешем: \n.
Он просто не знает еще, что IDE - не компилятор. Его делфя успешно скрывала от него существование dcc.exe.
Тогда бы не скомпилировалось
Спс
Не, скорее ты простой дурачёк, который никогда не работал со средними/большими проектами, лол
Когда я это запускаю на целевой машине, она мне пишет not found. Поэтому я думаю что как-то не так скомпилировал. И ещё бинарник запускается на x64 убунте, это нормально вообще?
аноны, помогите с кодом, я нихуя не понимаю, как работают глобальные переменные, очень прошу, я заебался, уже всё перепробовал. Я думаю тут мне помогут, не смотря на то, что это кресты всё-таки..
Unit1.h
блаблабла
extern bool HUI;
Unit1.cpp
#include "Unit1.h"
HUI = true;
Unit2.cpp
#include "Unit1.h"
if(HUI == true) { Label1->Caption = "Работает!"; }
else { Label1->Caption = "Соси хуй"; }
При этом коде я всегда сосу хуи, как не модифицируй, может там какие ссылки-хуилки надо или указатели, которые я тоже пытался вставить безуспешно. А с недавних пор, если создавать пустой проект, вообще пишет unresolved external, ошибку гуглил, всё что советуют делал, безуспешно
Умоляю, анон, помоги, как сделать, чтобы переменную видел весь проект и использовать можно было из любого места, прошу, анон, вот тебе ваванджапан в реверсе и негативе авансом.
спасибо за ответ, анон, но не помогло.
теперь другая проблема, ебучий builder c++ ругается на Unresolved external и в основном проекте, раньше только в пустом ругался, в котором я пытался разобраться в этой проблеме. решения нет, хз пока у кого спросить про эту ошибку. всё равно спасибо
int
sum (int a, int b)
Вот это вот функция. Это же 89, верно ? Зачем и кому сейчас это надо ?
Ты про int на отдельной строке? Или про что? Возвращаемый тип на отдельную строку лепят в некоторых проектах, где названия возвращаемых типов длинные, плюс еще атрибуты всякие прописываются типа конвенции вызова. Если писать в одну строку, декларацию все равно придется разбивать.
>Есть код на C, нужно скомпилировать под ARM архитектуру.
Подробнее, что за платформа, какая ось.
Планшет на андроиде и плата с стм32 - оба подразумевают ARM, но вот компиляция будет разной.
Шо ты несешь. Различия только в выборе архитектуры команд (в STM только thumb) и в доступности всяких флоатов. В остальном, компилятор - он и есть компилятор.
Блядь. Я думал это формальное описание старого стандарта. Вот я дебил. Ладно. Спасибо!
Устройство на базе процессора AT91SAM9260-QU, ось линукс с ядром 2.6.22. Пока пытаюсь просто скомпилировать простейший код, который бы заработал.
на _HUI который и является булевой переменной, я просто так и не понял причину этой ошибки в принципе, почему она возникает ВООБЩЕ интересно, а не только у меня, суть ошибки.
>>1060466
а вот это я не пробовал, как буду дома, сделаю. Удалить exe и obj? или еще какие? сделаю вечером и отправлю сюда скрин
>Пока пытаюсь просто скомпилировать простейший код, который бы заработал.
Простейший код - это записать единичку в указатель на регистр, управляющий светодиодом. Скидывай сюда код и вывод компилятора.
>>1060511
Устройства под линупсами поддерживают нэйтивную компиляцию. Бэйрметал - кросс онли.
>This specifies the name of the target ARM processor. GCC uses this name to determine what kind of instructions it can emit when generating assembly code. Permissible names are: `arm2', `arm250', `arm3', `arm6', `arm60', `arm600', `arm610', `arm620', `arm7', `arm7m', `arm7d', `arm7dm', `arm7di', `arm7dmi', `arm70', `arm700', `arm700i', `arm710', `arm710c', `arm7100', `arm720', `arm7500', `arm7500fe', `arm7tdmi', `arm7tdmi-s', `arm710t', `arm720t', `arm740t', `strongarm', `strongarm110', `strongarm1100', `strongarm1110', `arm8', `arm810', `arm9', `arm9e', `arm920', `arm920t', `arm922t', `arm946e-s', `arm966e-s', `arm968e-s', `arm926ej-s', `arm940t', `arm9tdmi', `arm10tdmi', `arm1020t', `arm1026ej-s', `arm10e', `arm1020e', `arm1022e', `arm1136j-s', `arm1136jf-s', `mpcore', `mpcorenovfp', `arm1156t2-s', `arm1156t2f-s', `arm1176jz-s', `arm1176jzf-s', `cortex-a5', `cortex-a8', `cortex-a9', `cortex-a15', `cortex-r4', `cortex-r4f', `cortex-m4', `cortex-m3', `cortex-m1', `cortex-m0', `xscale', `iwmmxt', `iwmmxt2', `ep9312'.
И это только один флажок gcc, для выбора архитектуры ARM.
Про всякие хитровыёбанные платы, которые требуют BSP, я уже и не говорю.
у меня c++ builder 6, он работает только под виндой. Я знаю, что я говноед, но так реально проще
/lib/ld-linux.so.3 на месте? Уж очень похоже на это
https://unix.stackexchange.com/questions/378301/linux-executable-fails-with-file-not-found-even-though-the-file-is-there-and-i
Попробуй флажок -static для компилятора. У тебя динамический эльф собирается на новой версии ядра, а запустить пытаешься на старой.
Частная разработка завода. Плата модуля ЦП в гибком мультиплексоре.
Слушай, file показывает что была использована библиотека ld-linux.so.3, которой на целевой машине нет. Может ее туда подсунуть и тогда все заведется? Только вот суффикс 3 в имени библиотеки что означает? Версию ядра?
Подсунул библиотеку. Теперь Input/Output error.
>Может ее туда подсунуть и тогда все заведется? Только вот суффикс 3 в имени библиотеки что означает? Версию ядра?
Если ты хочешь взять ld-linux.so.3 со своей виртуалки, и подсунуть под арм платы - мне кажется это не самая разумная идея. Если ты только не найдёшь эту библиотеку собранную под твой арм.
Ты же где-то исходники для ядра линукса брал? Если ты работаешь на этом же заводе - у тебя должны быть сорцы. Ковыряй мэйкфайл, смотри с какими ключами и какой компилятор запускается. Illegal instruction - насколько я помню, означает, что файл система сожрала, но на уровне исполнения произошла ошибка. Может -msoft-float нужно указать, может уточнить -march или -mcpu.
Собирать программу с нового ядра - под старое можно, но если честно, я никогда подобным не занимался. Вангую, что одними опциями компилятора тут не отделаться.
Да я сам этим никогда не занимался. Работаю в конторе веб-разработчиком, внезапно шеф вспоминает что у нас есть мультиплексор, собранный на заводе в другом городе. А поскольку единственный программист в штате - это я, то и поручили разобраться с этой штукой мне. А я с железками вообще никогда не работал. Исходники ядра есть, мне это мало о чем говорит. Содержимое мейк-файла на пикрил. Все эти ключи я уже пробовал. В линуксе на самой плате нет практически нихера, так что приходится компилировать на убунте в надежде что заведется на этой железке.
И что, скомпилированное с -static и -march=arm9tdmi точно также вызывает illegal instruction?
Можно ещё конечно readelfом сравнить то, что успешно исполняется на плате и то, что получается после компиляции у тебя.
Да, с этими флагами все так же illegal instruction. Вот, например, сравнение моего бинарника и того, что работает на плате.
Рабочий бинарник: https://pastebin.com/v8rnaMhW
Тестовый бинарник: https://pastebin.com/KStx0FEa
В чем преимущества и недостатки этого языка по сравнению с другими языками?
В чем косяк того, что я написал?
https://pastebin.com/mpD7p1QL
malloc возвращает адрес, подходящий для любой переменной, поэтому частично можно на это положиться, если на целевой машине переменные размером более 1 байта требуют выравнивания.
На x86 выравнивание не обязательное, но на 8 байт тебя все равно выровняют. В целом, тебе, конечно, никто ничего не гарантирует, но на любой 32-битной машине malloc вернет тебе адрес, который кратен минимум четырем.
>>1060977
0 четный.
На сколько хочешь, даже на матрицу
Потому что четное число по определению - это число, у которого остаток от деления на 2 равен нулю. Ну или можешь сказать, что это 2 умноженное на любое целое число.
Нет, это перавильное замечание. Если ты не француз и не матлогик, натуральные числа ноль не включают.
>В целом, тебе, конечно, никто ничего не гарантирует, но на любой 32-битной машине malloc вернет тебе адрес, который кратен минимум четырем.
Благодарю. А что бы наверняка, нет какой-нибудь опции проверить это, типа #ifdef MALLOC_ALIGN_EVEN ?
это стандарт выравнивание будет до самого большого типа, которому необходимо выравнивание. или тебе обязательно нужно знать?
В С11 можешь узнать alignof(max_align_t). alignof в stdalign.h, max_align_t в stddef.h. До C11 с гарантией никак, но можно смотреть на выравнивание структур (если до проверки на него никто не повлиял директивами или ключами компилятора). В struct test_alignment { char x; double d; }; дабл скорее всего будет выровнен до его натурального выравнивания, поэтому sizeof(struct test_alignment) - sizeof(double) скорее всего даст тебе выравнивание меньшее или равное выравниванию, гарантированному malloc().
Тогда поезжай во Францию, может хоть там тебе расскажут о существовании отрицательных чисел, из которых, ходят слухи, некоторые даже бывают четными.
Прошу прощения, не удосужился прочесть всю переписку. Ты прав.
Всё это немного выходит за рамки языка Си и ближе к красноглазикам. Продублируй вопрос в /s/ на всякий случай.
А ещё лучше, переконфигурируй glibc под целевое ядро и будет тебе счастье.
Разобрался с этой ерундой. Взял с https://www.uclibc.org/ образ root_fs_arm.ext2, примонтировал его, сменил корневой каталог на root_fs_arm.ext2/bin/su используя эмулятор qemu и там бинарник скомпилировался как надо, на целевой плате все работает. Спасибо за помощь. Сам бы я хер разобрался с этим всем.
>И "небезопасность" таких функций не в использовании указателей, как говорят ньюфаги выше
Ну извините. Мой кукарек основан на опыте быдлокодинга на C#. В сярпе "небезопасность" - это именно использование поинтеров. https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/unsafe
char str[150] = "abcd";
нормально присваевается, а
char str[150];
str[150] = "abcd";
выдает ошибку.
В первом случае ты объявляешь массив чаров, заполняешь первые 4 элемента, остальные заполнятся автоматически нулями.
Во втором ты говоришь, что элемент 150 равен "abcd". Но одному элементу обязана соответствовать 1 символ.
А как тогда правильно присвоить "abcd", если массив уже объявлен в виде char str[150];
Мне нужно, чтоб эффект был как в первом случае.
memcpy
Еще добавлю что если в убунте проверить библиотеку таким образом: "grep -r mq_close librt-0.9.29.so", то ответ будет "Двоичный файл librt-0.9.29.so совпадает". А если сделать то же самое для библиотеки в тулчейне, то ответом будет пустая строка. Будто бы эти функции не реализованы в версии библиотеки librt-0.9.27.so. Я пробовал подменять библиотку в тулчейне с 27 на 29 версию, но компилятор все равно не видит этих функций.
arm-linux-uclibc-gcc -march=armv5te -mtune=arm9tdmi -Wall -static -o slotinfo slotinfo.c -lpthread -lrt
int i;
char mass[252];
i=1; mass[0]='z';
scanf ("%c", &mass);
i = 2;
while ( mass[i-1] != '\n' ) {
scanf ("%c", &mass);
i++;
}
printf ("%d\n", strlen(mass));
Почему после введения ab и нажатия enter выдается результат 20 вместо ожидаемого 2?
Не пойму, откуда там аж 18 лишних взялось.
И если 'z' и '\n' учесть, то 4 всего ожидается.
Ясно, теперь заработало как надо.
А автоматически завершающий \0 по какому принципу ставится, раз strlen все-таки срабатывал?
strlen срабатывал, потому что mass у тебя в стеке. И рано или поздно среди мусора в стеке встретится нулевой байт.
Автоматически, естественно, за тебя \0 никто не поставит (ну кроме случаев, когда у тебя строковый литерал "foo", тогда да, он, как полноценная строка, включает в себя и \0 тоже).
Как распределяется этот мусор? Почему-то \0 каждый раз в одном и том же месте встречается, иначе бы 20 каждый раз после введения ab не выдавалось.
> Как распределяется этот мусор?
Да ты охуел с такими вопросами. Все, что тебе нужно знать - это undefined behavior, и его нужно избегать, а не искать закономерности. Возьми gdb и посмотри содержимое стека, если уж так интересно.
> J.2 Undefined behavior
> The value of an object with automatic storage duration is used while it is
indeterminate
> 6.7.9
> If an object that has automatic storage duration is not initialized explicitly, its value is
indeterminate.
Ты тут новичок, да?
>indeterminate
На деле-то оно оказалось в моем случае достаточно детерменированным. Но методом тыка я уже разобрался, от чего зависит стабильное появление \0 в определенном месте мусорной кучи, когда его явно не задали в коде.
Если переместить их до -o, то компилятор еще и заголовочный файл <semaphore.h> теряет в довесок к <queue.h>.
Нормальный у тебя порядок опций был, не слушай его. А вот -static скорее всего гадит, так как librt, возможно требует динамической линковки.
Компилятор CodeBlocks Mingw
Хреново если так. Ибо без статика у меня на ARM-машине бинарник вылетает с ошибкой not found. Думаю оно имеет ввиду что не найдена библиотека.
Тебе на каком языке то писать надо?
если С, то про cout, cin забудь, в С есть только printf,
Если C++, то #include <iostream>
Препод в вузе дал эти операторы, и в методичке его они есть, охуеть.
Спасибо, сам теперь удивляюсь своей тупости.
Avr
Сейчас в России мейнстрим - STM32, у них ко всему прочему очень удобные отладочные платы с встроенным отладчиком. Полно семинаров/вебинаров от производителя, материалы все выложены. Здесь http://www2.hitex.com/download-isg неплохие мурзилки. Также постарайся не подсесть на ломаный софт типа IAR и Keil.
Такое дело, я в беларуси, и записался в лабораторию в универе, а там avr, хотелось бы узнать интересно ли это
memcpy
Что здесь не так? В гугле по ошибке всё на английском и тема не та.
Тебе даже номера строк указали, где ты облажался. Поставь себе линукс и гцц, там сообщения на русском специально для дебилов, не желающих учить английский. Закрывать открытые фигурные скобки за тебя кто будет? А n(<15) - это что за заклинание?
Б-же, сам уже ору. Я ведь смотрел в упор на эту строку и всё равно не видел ничего
С этим то аноном все ясно, похапе фрилансер 300к/сек и ничего, что про стек впервые слышит, но у меня вот реально проблема. Пишу на си, начинаю скучать по шаблонам и всякому ООП, тяне к плюсам. Начинаю писать на плюсах, охуеваю от этих блядских шаблонов и всякого ООП, тянет назад к сям. Пишу на чем-то другом - хочется вернуться к сям. Это как-то лечится?
Не надо так делать. Читай Кернигана и Ритчи. Базарю.
Хуя какой я богачь, аж завидно :(
Ладно ООП, С из другого мира, но шаблоны...
даже generic macro добавили, чтобы шаблоны не добавлять
Стандартные секции типа bss, rodata, text и data - с ними всё ясно. Но где можно почитать про остальные секции, которые генерируются компилятором/линковщиком? Все эти reginfo, sbss, MIPS.abiflags, pdr и так далее?
Игорю пишу. Оно того стоит?
> Игорю пишу. Оно того стоит?
Да, имеет некоторый смысл. Всякие коллекции (особенно с шаблонами) не придется переизобретать по сто раз на дню, перегруженные операторы сделают математику гораздо более читаемой, а виртуальные методы и наследование действительно нужны в играх (да, на сишке тоже можно, но на сишке и прыгать вокруг этого всего нужно больше). А вот переходить только ради того, чтобы использовать ключевое слово class и методы вместо ключевого слова struct и функций с явным this в сишечке - не стоит.
Как ни странно, но нихуя.
Всё таки нашёл, что искал. Вся эта хуита описана в SYSTEM V APPLICATION BINARY INTERFACE для семейства MIPS.
Оставлю для потомков ссылку, вдруг кто-нибудь тоже искать будет.
http://math-atlas.sourceforge.net/devel/assembly/mipsabi32.pdf
О сборке и установке принято писать в файлах README и INSTALL, которые прилагаются к исходникам конкретного софта.
Поподробнее плиз. Ну есть тут например описание, и что дальше то делать , как например собирать со своим проектом, как это дело линковать, как создать .so библиотеку из этого всего с помощью gcc
https://github.com/FFmpeg/FFmpeg/blob/master/INSTALL.md
Тогда тебе надо для начала пройти школьный курс информатики.
Мне кажется, тебе нужен cmake. В каждой папке проекта ты создаешь конфиг, в котором описываешь действия над локальными файлами и связи с другими частями проекта. Например тебе нужно собрать экзешник, так ты перечисляешь исходники, указываешь расположение хедеров и подпроектов, в которых собираются библиотеки, прописываешь инструкции по установке (что и куда скопировать после сборки). cmake на основании дерева таких конфигов генерит множество более низгоуровневых конфигов, например тех же Makefile, но не обязательно.
autoconf (configure), упомянутый в ffmpeg похож, но ебанутее
Туториалов по cmake полно, но документация написана очень специфически, нужно время чтобы привыкнуть, без примеров очень сложно.
Вот есть бесплатная книга http://www.stolyarov.info/books/programming_intro/vol2
Начиная с 441 страницы рассказываются основы сборки программ.
https://pastebin.com/petDuZbE
Печатает мне пустую строку, а
https://pastebin.com/tumWJ9ZS
этот корректно заменяет все 'c' на 'b'?
У тебя здесь s = '\0'; первое же вхождение "с" заменяется на нуль-терминатор. printf выводит всё говно до первого символа '\0', а он у тебя получается на в самом начале.
Замени "ccabc" на "bbabc" и он тебе выведет "bbab".
offsetof
int size = snprintf(NULL, 0, format, ...);
char* buffer = malloc(size);
sprintf(buffer, format, ...);
ЖМУ ПИНУС!!!!
ШВАБОДКА, ПЕТУХИ!!!
switch_threads:
push eax
push ecx
push edx
push ebx
push ebp
Ты тредом не ошибся?
> Какие регистры принадлежат контексту и требуют сохранения?
Очевидно, что все, которые доступны для записи. pushad, pushfd, стейт FPU/SSE тоже, отладочные, сегментные регистры тоже имеет смысл сохранять.
>>1065290
> без необходимости обмазываться крестами/жабой/шарпом/питоном
А что, в 2017 существуют такие программисты, которые пишут на каком угодно языке, но только на нем одном?
>А что, в 2017 существуют такие программисты, которые пишут на каком угодно языке, но только на нем одном?
Мой вопрос исключил лишь определенные языки, а не вообще все кроме си.
В ideone код не работает, в Dev-C++ запускается, вызывает сигнал SIGSEGV, т.е. насколько я понимаю, признает стек переполненным и затыкается.
Проблема в том, что по ТЗ тест должен выдать результат - например, число итераций, которое вызывалась рекурсивная функция или подсчитанный объем стека в байтах. То есть, после переполнения программа должна продолжаться. Отсутствие эксепшенов в Си слегка вгоняет меня в ступор. Как продолжить работу программы при переполнении?
Была мысль с помощью malloc оценивать свободное пространство, и если malloc возвращает null, сворачивать рекурсию, но такое не заработало.
Вообще такая задача вызывает у меня массу вопросов, например, есть ли смысл проведения подобного теста. Логика тут вообще такая: функция вызывается рекурсивно и на каждой итерации N создается 3N переменных. Отсюда сразу еще и такой вопрос: надо ли очищать через free память на каждой итерации?
Надеюсь, кто-нибудь поможет.
> переполнения стека процессора
В процессоре нет стека.
> тест
Хуевый тест. Это все очень сильно зависит от ОС.
> То есть, после переполнения программа должна продолжаться.
Ты слегка охуел. После подобных ошибок программа должна тихо сдохнуть. Тем более после сегфолта. Но ты можешь попробовать, во-первых, сделать свой counter volatile, во-вторых, установить обработчик SIGSEGV с помощью signal (signal.h) и всю работу делать в обработчике. Но гарантий не будет никаких. В-третьих, можешь подумать о setjmp/longjmp для возврата из обработчика сигнала в main. Это не по стандарту, но в целом работает.
Лучше зделой программу, которой ты передаешь аргументом глубину рекурсии и вторую программу, которая запускает первую и бинарным поиском выбирает максимальную глубину, при которой дочерняя программа перестает валиться. Если у тебя никсы, можешь форками обмазаться, суть одна и та же.
> Была мысль с помощью malloc оценивать свободное пространство
В винде, например, есть лимит на размер стека. Т.е., свободной памяти еще гигабайты, а у тебя стек оверфлоу.
Многие системщики. Хотя сейчас железо позволяет портировать кресты дохуя куда, потому как правило, пишут только самые низкоуровневые вещи, потом портируют компилятор цэ2плюса и далее пишут на плюсах. Более того, тут Rust завезли, который, по слухам, пиздат до невозможности, умеет почти что в сборщик мусора, но без рантаймов (все полезности делает компилятор) и еще всякие плюшки. Думаю, если все действительно так радужно, скоро начнут писать низкоуровщину на нем. Тащемто, он для этого и проектировался, чтобы писать не на сях там, где можно писать только на сях и ассемблере.
Почему после ввода любой буквы начинается бесконечный цикл с default? Ведь буквы же в Си имеют и числовое представление. После ввода любой цифры больше трёх default нормально срабатывает, мне нужно, чтоб и с буквами также было.
> Почему после ввода любой буквы начинается бесконечный цикл
Платина.
1) Потому что буквы не подходят под формат %d.
2) Потому что ты не проверяешь возвращаемое значение scanf.
3) Потому что в input при вводе буквы ничего не присваивается, там мусор.
4) Потому что после ввода буквы ты не очищаешь поток ввода, и там по-прежнему остается буква.
> Ведь буквы же в Си имеют и числовое представление
Если %с скажешь, будет у тебя числовое представление буквы, но тогда и конвертировать цифры из строки в число для тебя никто не будет.
>3) Потому что в input при вводе буквы ничего не присваивается, там мусор.
>4) Потому что после ввода буквы ты не очищаешь поток ввода, и там по-прежнему остается буква.
Тогда почему вместо мусора в бесконечном цикле отображается последняя введённая цифра, если в коде перед scanf в цикле поставить printf("%d\n",input);, затем после запуска ввести цифру, а потом букву?
Потому что цифра подходит и присваивается, а буква не присваивается, и значение input сохраняется. Посмотри, сколько тебе scanf возвращает.
Если после ввода буквы scanf ничего не присваивает переменной input, тогда оставшаяся часть цикла должна сработать как при предыдущем значении input. Что мешает-то?
int a, b, m, n, z;
m = n = 5;
z = a = b = 0;
z--, ( a = b ) = z + ( m != n );
printf ("%d %d %d %d %d\n",
a, b, m, n, z);
MingW последний с c11 стандартом пропускает это, C99 выдает ошибку на =(без скобок считает)
Или еще
int x;
x = 5; ++ x =10;
printf ("%d\n", x);
C11 меняет константу(я еще не проверял в дебагере), ну он точно выдает 10, C99 не пропускает эту ошибку.
Оба твоих примера не скомпилируются. Оператору = нужно lvalue слева, поэтому никаких инкрементов, никаких скобок туда втыкать нельзя. И, конечно же, ничего в C11 по этому поводу не менялось, и в дальнейшем тоже не изменится. Подозреваю, что ты, как и многие итт, перепутал Си с крестами. В крестах так можно.
Скорее дефолтный Debian.
Слушай я сам вкатился в Сишку после 10 лет опыта в С++, но по шаблонам скучал только первые пару месяцев и недоумевал почему их не добавили в стандарт, а потом понял почему и решил что правильно сделали не дай бог им там появиться.
Ну ты и сам поймешь потом, просто для примера возьми и сравни исходники какого-нибудь крупного С проекта, типа ядра линукс или гцц, и сравни их с каким нибудь проектом на С++, ты охуеешь насколько С++ уебищный и непонятный язык по сравнению с СИ, во многом ( если не в основном ) благодаря шаблонам.
Как сказал один мимохуй где-то в интернетах: Если ты за 2 минуты чтения хедера не понял полностью как это все работает, то можешь смело выбрасывать такой код в помойку. И это правильно сказано, хочу заметить.
Вообще, советую забыть вообще, что такое С++ и что ты когда-то что-то писал на нем, когда будешь вкатываться в СИ. Это абсолютно разные языки, несмотря на то, что типа С++ продолжение СИ, это не так, С++ это издевательство и глумление над СИ, его проектировали больные люди, возьми к примеру хотя бы создателя STL, ну а чтоб полностью убедиться в этом открой исходники Boost.
Я вот уже где-то год, пишу в основном на СИ, после тех бездарно потраченых 10 лет на С++. И до сих пор переодически нахожу вещи введеные в самых первых стандартах, куда более продуманными и логичными по сравнению с последними высерами в стандартах С и С++.
Я даже не использую С11, потому что там нету ничего полезного, ну может кроме stdatomic.h которые спокойно заменяются GNU built-ins в GCC и Clang ( и мб Intel ) ( а другие компилеры и не нужны ).
Даже посмотри на комментарии в стиле С++ даже они уебищны сами по себе, превращая код в кашу их каких-то пометок, будто на туалетном листе и сравни блочные комментарии ANSI C, которые предназначены для подробного описания кода цельными блоками в основном в хедерах над фунциями и структурами данных, а не пометками посреди кода, которые только ухудшают его читаемость.
Еще т.к я бывший плюсовик, то естественно привык объявлять переменные по ходу надобности, прямо по среди кода. Недавно осознал что, отцы K&R все-таки не просто так это сделали и не из-за каких-то там ограничений или чего-то подобного, а потом типа появился спаситель С++ и разрешил хуярить все в перемешку, потом отупевшие от этого люди в стандарте добавили это в ISO С99.
А теперь поясню почему разделение кода и данных это хорошо:
Во-первых, это СУЩЕСТВЕННО повышает читаемость кода.
Во-вторых, это не дает тебе лепить большие толстые функции > ~100 строк, ведь чем больше функция тем больше в ней задействованно переменных, и тем труднее за ними уследить в одной области видимости, в купе с обработкой ошибок через goto.
Как говорится в linux kernel code style guide - Functions should be short and sweet, and do just one thing.
..
if you have a complex function, and you suspect that a less-than-gifted first-year high-school student might not even understand what the function is all about, you should adhere to the maximum limits all the more closely. Use helper functions with descriptive names (you can ask the compiler to in-line them if you think it’s performance-critical, and it will probably do a better job of it than you would have done).
Another measure of the function is the number of local variables. They shouldn’t exceed 5-10, or you’re doing something wrong. Re-think the function, and split it into smaller pieces. A human brain can generally easily keep track of about 7 different things, anything more and it gets confused. You know you’re brilliant, but maybe you’d like to understand what you did 2 weeks from now.
...
Вот эти золотые слова, должны быть основой любого code style любого проекта.
А если этих правил предерживаться, то Mixed declarations and code абсолютно не нужен, и должен быть отключен в компиляторе через -Werror=declaration-after-statement, если используется стандарт поддерживающий это.
В общем, можно еще долго дискутировать на тему, чем СИ лучше С++ и не зря все серьезные проекты пишутся на СИ, а не С++. Со временем ты поймешь все эти истины и вообще больше не захочешь видеть С++ никогда в жизни, если уж что-то надо быстро и просто накалякать что-то на коленке, то лучше взять более приспособленные языки типа явы или C#, а не С++.
Слушай я сам вкатился в Сишку после 10 лет опыта в С++, но по шаблонам скучал только первые пару месяцев и недоумевал почему их не добавили в стандарт, а потом понял почему и решил что правильно сделали не дай бог им там появиться.
Ну ты и сам поймешь потом, просто для примера возьми и сравни исходники какого-нибудь крупного С проекта, типа ядра линукс или гцц, и сравни их с каким нибудь проектом на С++, ты охуеешь насколько С++ уебищный и непонятный язык по сравнению с СИ, во многом ( если не в основном ) благодаря шаблонам.
Как сказал один мимохуй где-то в интернетах: Если ты за 2 минуты чтения хедера не понял полностью как это все работает, то можешь смело выбрасывать такой код в помойку. И это правильно сказано, хочу заметить.
Вообще, советую забыть вообще, что такое С++ и что ты когда-то что-то писал на нем, когда будешь вкатываться в СИ. Это абсолютно разные языки, несмотря на то, что типа С++ продолжение СИ, это не так, С++ это издевательство и глумление над СИ, его проектировали больные люди, возьми к примеру хотя бы создателя STL, ну а чтоб полностью убедиться в этом открой исходники Boost.
Я вот уже где-то год, пишу в основном на СИ, после тех бездарно потраченых 10 лет на С++. И до сих пор переодически нахожу вещи введеные в самых первых стандартах, куда более продуманными и логичными по сравнению с последними высерами в стандартах С и С++.
Я даже не использую С11, потому что там нету ничего полезного, ну может кроме stdatomic.h которые спокойно заменяются GNU built-ins в GCC и Clang ( и мб Intel ) ( а другие компилеры и не нужны ).
Даже посмотри на комментарии в стиле С++ даже они уебищны сами по себе, превращая код в кашу их каких-то пометок, будто на туалетном листе и сравни блочные комментарии ANSI C, которые предназначены для подробного описания кода цельными блоками в основном в хедерах над фунциями и структурами данных, а не пометками посреди кода, которые только ухудшают его читаемость.
Еще т.к я бывший плюсовик, то естественно привык объявлять переменные по ходу надобности, прямо по среди кода. Недавно осознал что, отцы K&R все-таки не просто так это сделали и не из-за каких-то там ограничений или чего-то подобного, а потом типа появился спаситель С++ и разрешил хуярить все в перемешку, потом отупевшие от этого люди в стандарте добавили это в ISO С99.
А теперь поясню почему разделение кода и данных это хорошо:
Во-первых, это СУЩЕСТВЕННО повышает читаемость кода.
Во-вторых, это не дает тебе лепить большие толстые функции > ~100 строк, ведь чем больше функция тем больше в ней задействованно переменных, и тем труднее за ними уследить в одной области видимости, в купе с обработкой ошибок через goto.
Как говорится в linux kernel code style guide - Functions should be short and sweet, and do just one thing.
..
if you have a complex function, and you suspect that a less-than-gifted first-year high-school student might not even understand what the function is all about, you should adhere to the maximum limits all the more closely. Use helper functions with descriptive names (you can ask the compiler to in-line them if you think it’s performance-critical, and it will probably do a better job of it than you would have done).
Another measure of the function is the number of local variables. They shouldn’t exceed 5-10, or you’re doing something wrong. Re-think the function, and split it into smaller pieces. A human brain can generally easily keep track of about 7 different things, anything more and it gets confused. You know you’re brilliant, but maybe you’d like to understand what you did 2 weeks from now.
...
Вот эти золотые слова, должны быть основой любого code style любого проекта.
А если этих правил предерживаться, то Mixed declarations and code абсолютно не нужен, и должен быть отключен в компиляторе через -Werror=declaration-after-statement, если используется стандарт поддерживающий это.
В общем, можно еще долго дискутировать на тему, чем СИ лучше С++ и не зря все серьезные проекты пишутся на СИ, а не С++. Со временем ты поймешь все эти истины и вообще больше не захочешь видеть С++ никогда в жизни, если уж что-то надо быстро и просто накалякать что-то на коленке, то лучше взять более приспособленные языки типа явы или C#, а не С++.
> А теперь поясню почему разделение кода и данных это хорошо:
> Во-первых, это СУЩЕСТВЕННО повышает читаемость кода.
Долго держался, но все же проиграл с поехавшего.
Мне тоже показалось, что что-то неладно, но если там и правда
>5-7 автоматическиъ переменных на фукнкцию
то лучше их объявить в начале, и правда
> Если ты за 2 минуты чтения хедера не понял полностью как это все работает, то можешь смело выбрасывать такой код в помойку.
Как по мне если ты чего то не понимаешь, скорее всего ты тупой.
Знатно просрался с этой пидорашки
Нет, конечно тебе будет казаться это неудобным после того как везде пихают уже mixed declarations.
Но поверь опыту действительно лучших программистов в мире - разработчиков ядра линукс, в которые входят люди из разных топовых компаний типа гугла, интела, амазона и т.д с топовыми образованиями. Они то просто так не станут придерживаться такому code style, который отточен и проверен годами.
Почитай исходники линукс, все функции там действительно маленькие, и с ходу понятные.
Тем более, в си и с++ разные методики освобождения ресурсов, если в с++ используют RAII, шаред поинтеры и т.п. когда можно не парясь сделать return посреди функции или бросить исключение и ресурсы автоматически очистятся, то в си так сделать нельзя, в си ошибки обрабатываются обычно через goto на секции с освобождением ресурсов и представь как легко ошибиться, если у тебя в коде каша из переменных. А если у тебя код разбит на маленькие функции по несколько переменных, то начиная читать код ты сразу видишь какие ресурсы у тебя в функции есть и легко проверить все ли ресурсы были освобождены по выходу из нее.
Если ты бы когда нибудь писал на ассемблере, то понимал бы как легко ошибиться даже с памятью на стеке.
В общем, си это тебе не хуйня для обезьян типа крестовиков и всех остальных чернорабочих.
С++, как и другие ООП языки не требует особой подготовки, поэтому на них выгодно делать проекты в коммерческих компаниях, где можно как можно с меньшими затратами заменить Васю на Петю, порог вхождения низкий.
>>1071953
Вынужден тебя разочаровать, это далеко не всегда так.
Как я уже цитировал выше, Линуса:
>if you have a complex function, and you suspect that a less-than-gifted first-year high-school student might not even understand what the function is all about
Твой код должен быть понятен, даже студенту школьнику, если ты конечно не говнокодишь лично для себя.
Я за 10 лет работы С++ прогером, успел навидаться такого говнокода, что приходилось иногда по нескольку часов разбираться, что там куда и откуда эти шаблоны и классы ведут. Ведь многие прогеры на с++, часто вообще полностью пренебрегают чистотой кода, и хуярят лиш бы работало. А чо? Язык позволяет и похуй.
Я считаю, единственный возможный вариант использования С++ это СИ с классами либо какие-то вариации MISRA С++, Где запрещены STL, шаблоны, исключения, виртуальные функции, и т.п и тем более полностью запрещен С++11.
Но если ты рядовой быдлокодер, не заморачивайся и ебаш как попало с шаред поинтерами и т.п. А лучше вообще возьми пыху или JS там с каким-нибудь electron'ом и вообще все будет в шоколаде.
Нет, конечно тебе будет казаться это неудобным после того как везде пихают уже mixed declarations.
Но поверь опыту действительно лучших программистов в мире - разработчиков ядра линукс, в которые входят люди из разных топовых компаний типа гугла, интела, амазона и т.д с топовыми образованиями. Они то просто так не станут придерживаться такому code style, который отточен и проверен годами.
Почитай исходники линукс, все функции там действительно маленькие, и с ходу понятные.
Тем более, в си и с++ разные методики освобождения ресурсов, если в с++ используют RAII, шаред поинтеры и т.п. когда можно не парясь сделать return посреди функции или бросить исключение и ресурсы автоматически очистятся, то в си так сделать нельзя, в си ошибки обрабатываются обычно через goto на секции с освобождением ресурсов и представь как легко ошибиться, если у тебя в коде каша из переменных. А если у тебя код разбит на маленькие функции по несколько переменных, то начиная читать код ты сразу видишь какие ресурсы у тебя в функции есть и легко проверить все ли ресурсы были освобождены по выходу из нее.
Если ты бы когда нибудь писал на ассемблере, то понимал бы как легко ошибиться даже с памятью на стеке.
В общем, си это тебе не хуйня для обезьян типа крестовиков и всех остальных чернорабочих.
С++, как и другие ООП языки не требует особой подготовки, поэтому на них выгодно делать проекты в коммерческих компаниях, где можно как можно с меньшими затратами заменить Васю на Петю, порог вхождения низкий.
>>1071953
Вынужден тебя разочаровать, это далеко не всегда так.
Как я уже цитировал выше, Линуса:
>if you have a complex function, and you suspect that a less-than-gifted first-year high-school student might not even understand what the function is all about
Твой код должен быть понятен, даже студенту школьнику, если ты конечно не говнокодишь лично для себя.
Я за 10 лет работы С++ прогером, успел навидаться такого говнокода, что приходилось иногда по нескольку часов разбираться, что там куда и откуда эти шаблоны и классы ведут. Ведь многие прогеры на с++, часто вообще полностью пренебрегают чистотой кода, и хуярят лиш бы работало. А чо? Язык позволяет и похуй.
Я считаю, единственный возможный вариант использования С++ это СИ с классами либо какие-то вариации MISRA С++, Где запрещены STL, шаблоны, исключения, виртуальные функции, и т.п и тем более полностью запрещен С++11.
Но если ты рядовой быдлокодер, не заморачивайся и ебаш как попало с шаред поинтерами и т.п. А лучше вообще возьми пыху или JS там с каким-нибудь electron'ом и вообще все будет в шоколаде.
Не не не, я не сомневаюсь что есть случаи когда говнокод - это говнокод. С этим ничего не поделаешь. Но заявление про 2 минуты - это уже как-то попахивает максимализмом. Да и вообще это таоке, мол мне лень разбираться в коде, лучше сам напишу всё заново. В итоге вместо 1 говнокода в конторе теперь 2.
>ну а чтоб полностью убедиться в этом открой исходники Boost.
... - сказал человек, ни разу не открывавший исходники STDlib.
>его проектировали больные люди
Почти все программисты отчасти больные люди. Плюсы проектировали, пытаясь сохранить совместимость с C, и благодаря этому язык получил развитие. Было ли это компромиссом по сравнению с чьим-то идеалом? Да.
>Со временем ты поймешь все эти истины
"Понять истины" - это словосочетание сроду "нырнуть в камни". Если то, что ты изрекаешь, называется истиной, то её можно познать. Чтобы познать истину, достаточно критического склада ума и того, чтобы кто-то её продемонстрировал. Считаешь, что всё сказанное тобой истина и негативно характеризует именно плюсы - вперёд, демонстрируй, мы посмотрим.
>отцы K&R все-таки не просто так это сделали и не из-за каких-то там ограничений или чего-то подобного, а потом типа появился спаситель С++ и разрешил хуярить все в перемешку, потом отупевшие от этого люди в стандарте добавили это в ISO С99.
Я хочу сделать две переменные, инициализатор одной я могу вычислить одним выражением, а для инициализации другой мне нужно несколько строк кода или луп. Что предлагают отцы? Олсо, что предлагают отцы, если я хочу определить функцию в функции? Ну, знаешь, такую, которая вне этой функции не понадобится, а назвать для улучшения читаемости кода хочется.
>А теперь поясню почему разделение кода и данных это хорошо:
Лучше поясни, почему предоставленная свобода является свойством языка, а не тех, кто на нём пишет. Никто не мешает тебе сделать свой стиль кода и придерживаться его (очевидно, что ты можешь позволить себе это, если ты перешёл с плюсов на Си), ты даже можешь написать свой анализатор, который будет тебе пинка давать в нужном месте.
Либо докажи, что на Си нельзя написать нечитаемую работающую мешанину.
>Ну ты и сам поймешь потом, просто для примера возьми и сравни исходники какого-нибудь крупного С проекта, типа ядра линукс или гцц, и сравни их с каким нибудь проектом на С++, ты охуеешь насколько С++ уебищный и непонятный язык по сравнению с СИ, во многом ( если не в основном ) благодаря шаблонам.
Си - уёбищный и непонятный язык по сравнению со Schema.
Из шаблонов мне не нравится специализация, методика разворачивания вариативного списка аргументов, следовательно, всё это я не использую. Так тоже можно.
>и тем труднее за ними уследить в одной области видимости, в купе с обработкой ошибок через goto.
>А теперь поясню почему разделение кода и данных это хорошо:
Звучит иронично, потому что в плюсах ты и данные мог отделять (один блок определений на несколько методов), и ошибки мог обрабатывать не через гото, а вызовом методов и лямбд или даже с помощью исключений.
>пометками посреди кода, которые только ухудшают его читаемость.
>Еще т.к я бывший плюсовик, то естественно привык объявлять переменные по ходу надобности, прямо по среди кода.
Жирными мазками эпатируешь, блядь.
>ну а чтоб полностью убедиться в этом открой исходники Boost.
... - сказал человек, ни разу не открывавший исходники STDlib.
>его проектировали больные люди
Почти все программисты отчасти больные люди. Плюсы проектировали, пытаясь сохранить совместимость с C, и благодаря этому язык получил развитие. Было ли это компромиссом по сравнению с чьим-то идеалом? Да.
>Со временем ты поймешь все эти истины
"Понять истины" - это словосочетание сроду "нырнуть в камни". Если то, что ты изрекаешь, называется истиной, то её можно познать. Чтобы познать истину, достаточно критического склада ума и того, чтобы кто-то её продемонстрировал. Считаешь, что всё сказанное тобой истина и негативно характеризует именно плюсы - вперёд, демонстрируй, мы посмотрим.
>отцы K&R все-таки не просто так это сделали и не из-за каких-то там ограничений или чего-то подобного, а потом типа появился спаситель С++ и разрешил хуярить все в перемешку, потом отупевшие от этого люди в стандарте добавили это в ISO С99.
Я хочу сделать две переменные, инициализатор одной я могу вычислить одним выражением, а для инициализации другой мне нужно несколько строк кода или луп. Что предлагают отцы? Олсо, что предлагают отцы, если я хочу определить функцию в функции? Ну, знаешь, такую, которая вне этой функции не понадобится, а назвать для улучшения читаемости кода хочется.
>А теперь поясню почему разделение кода и данных это хорошо:
Лучше поясни, почему предоставленная свобода является свойством языка, а не тех, кто на нём пишет. Никто не мешает тебе сделать свой стиль кода и придерживаться его (очевидно, что ты можешь позволить себе это, если ты перешёл с плюсов на Си), ты даже можешь написать свой анализатор, который будет тебе пинка давать в нужном месте.
Либо докажи, что на Си нельзя написать нечитаемую работающую мешанину.
>Ну ты и сам поймешь потом, просто для примера возьми и сравни исходники какого-нибудь крупного С проекта, типа ядра линукс или гцц, и сравни их с каким нибудь проектом на С++, ты охуеешь насколько С++ уебищный и непонятный язык по сравнению с СИ, во многом ( если не в основном ) благодаря шаблонам.
Си - уёбищный и непонятный язык по сравнению со Schema.
Из шаблонов мне не нравится специализация, методика разворачивания вариативного списка аргументов, следовательно, всё это я не использую. Так тоже можно.
>и тем труднее за ними уследить в одной области видимости, в купе с обработкой ошибок через goto.
>А теперь поясню почему разделение кода и данных это хорошо:
Звучит иронично, потому что в плюсах ты и данные мог отделять (один блок определений на несколько методов), и ошибки мог обрабатывать не через гото, а вызовом методов и лямбд или даже с помощью исключений.
>пометками посреди кода, которые только ухудшают его читаемость.
>Еще т.к я бывший плюсовик, то естественно привык объявлять переменные по ходу надобности, прямо по среди кода.
Жирными мазками эпатируешь, блядь.
>Слушай я сам вкатился в Сишку после 10 лет опыта в С++
Собственно дальше можно было не читать.
>Олсо, что предлагают отцы, если я хочу определить функцию в функции?
Ебать говноед.
Дальше не читал.
Если ты хочешь определять функции в функции, то тебе точно не в семейство языков СИ.
Все функции должны лежать в единицах трансляции кучей и не быть никак связаны, так нам завещали авторы первой версии стандарта. Аминь!
Ты не чувствуешь, что ты сопротивляешься природе, объявляя локальные переменные вместо глобальных?
Он преувеличил про 2 минуты, но наша задача не допустить "ну если не тупые поймут" принципов. Мы всегда хотим по максимуму упростить код.
>лежать в единицах трансляции кучей и не быть никак связаны
Не особо понял, что ты имел ввиду.
У функций есть разный linkage - external и internal.
Что тебе мешает связать функции из разных единиц трансляции?
Чот толсто
>Если ты за 2 минуты чтения хедера не понял полностью как это все работает, то можешь смело выбрасывать такой код в помойку.
10 лет опыта, и в коде не разбираться, да даже если это говнокод, то это всё прекрасно разбирается.
Возникла необходимость кроссплатформенно (на уровне исходного кода) создавать окно и получать его идентификатор (пикрелейтед 1). Делать это было решено с помощью GLFW, однако тут я внезапно столкнулся с некой проблемой - линковкой.
Для компиляции пользуюсь gcc из набора MinGW (пикрелейтед 2). Путь к библиотекам прописал, сами библиотеки он тоже видит (если, например, ошибиться в названии, то начинает ругаться на не найденную билиотеку), но при этом выбрасывает "undefined reference" на вызов любой функции из GLFW.
Исходный код - пикрелейтед 3.
Спаси, анон, как эту ебанину фиксить?
>Что тебе мешает связать функции из разных единиц трансляции?
Конкретно мне мешает то, что в плюсах есть гораздо более удобный способ классифицирования функций и вложения их. Да, действительно, можно компенсировать отсутствие неймспейсов, классов и лямбд бОльшим количеством файлов с кодом, но ЗАЧЕМ?
Че ты там компенсировать собрался я не понял.
Ебани лучше на пхп че нить, там вообще можно ХТМЛ сразу в код вставлять, прикинь охуеть да?
У тебя все переменные глобальные? Вот прикинь, точно так же не все функции должны быть глобальные.
Че за хуйню несет? Пиздец.
Иди учи матчасть. Функции у него не линкуются, перменные глобальные везде, функции глобальные. Ебануться ты про какой вообще язык говоришь?
Ну не стукай, я не сишник. Что не так?
>Функции у него не линкуются
Сам придумал, сам посмеялся?
>функции глобальные
В C есть "неглобальные" функции?
>перменные глобальные везде
Это вообще-от вопрос был. Судя по тому, как ты отказываешься на него отвечать, переменные у тебя неглобальные. Теперь объясни мне, почему переменные не должны быть глобальными, а функции должны.
И вообще вырази свою точку зрения лучше, чем "дальше не читал".
> В C есть "неглобальные" функции?
Я не он, но предположу, что статические в некотором роде неглобальны, так что инкапсулировать можно с помощью статика.
>В C есть "неглобальные" функции?
Представь себе.
Ну ты наверняка не слышал даже о линковке символов в С, и не представляешь как выстроить программу на С.
Понятие не имеешь о модульности, о заголовочных файлах, о юнитах компиляции, о модификаторе static, о формате ELF, о его секциях, о том что представляет собой бинарный файл и как система его читает.
Советую ознакомиться со всеми этими вещами, тогда может быть ты перестанешь нести откровенный бред и научишься наконец-то программированию, а не макакингу.
В С есть все, что необходимо для построения самых сложнейших систем. Если даже на чистом ассемблере пишут полноценные ОС типа калибри и минует, то о чем вообще речь?
Я не собираюсь тебе тут расписывать все детали построения программ на С, потому что в инете полно материала об этом и это не описать в двух словах. Нужно понимать как вообще работает все на низшем уровне от структуры бинарника, до модификаторов видимости символов в С.
Если ты не хочешь в этом разбираться, тогда С не для тебя. С это довольно низкоуровневый язык, который требует глубокого понимания предметной области, чтобы на нем писать, что-то сложнее хелоу вордов.
Ты уже и меня заебал своей тупостью. В си вообще нет ни глобальных функций, ни переменных, иди почитай стандарт. Но при этом мы все тут понимаем, что имеет в виду анон выше. Торчит ли при этом у тебя фунция голым задом из модуля не имеет никакого значения.
Ты не туда воюешь. Си я более-менее знаю и пердолить статики, указатели, маллоки, битшифты, препроцессор, рекурсивные макроопределения, хвостовую рекурсию и прочее я умею.
>Ну ты наверняка не слышал даже о линковке символов в С
Она такая же, как в плюсах (минус пердолинг с названиями экспортов в таблицах), так что слышал.
>Понятие не имеешь о модульности
В плюсах то же самое. Испугал ежа голой жопой.
>о заголовочных файлах, о юнитах компиляции, о модификаторе static
В плюсах то же самое. Глобальная переменная тоже может быть невидимой извне, неглобальной она от этого не становится. Все функции в Си "глобальные" (о чём я тебе и говорил).
>о формате ELF, о его секциях, о том что представляет собой бинарный файл и как система его читает.
К языку С не относится касательно, к стандарту языка С - никак. Нужно будет знать что-то о формате ELF или WinPE - открою спецификацию и прочту, это святыня какая-то?
>В С есть все, что необходимо для построения самых сложнейших систем.
Тебе для построения сложнейших систем необходимы только кнопки 0/1 и бумага с ручкой.
>Если даже на чистом ассемблере пишут полноценные ОС типа калибри и минует, то о чем вообще речь?
Это ты мне скажи, о чём ты ведёшь речь. Я задал дискусионный вопрос автору высера, ты из всего моего линного поста выделил именно его.
>Торчит ли при этом у тебя фунция голым задом из модуля не имеет никакого значения.
Вот как раз это имеет огромное значение при проектирование приложений.
Я вообще не понимаю, что вы тут хотите мне доказать? Что язык С не соответствует каким-то вашим ожиданиям и представлениям о локальных и глобальных переменных?
>>1072251
>Глобальная переменная тоже может быть невидимой извне, неглобальной она от этого не становится. Все функции в Си "глобальные"
Блять, поясни пожалуйста тогда что ты понимаешь под локальный и глобальной переменной, потмоу что по моему у тебя об этом не правильное представление.
Алсо, ты можешь сделать перменную локальной в пределах юнита компиляции, ты можешь сделать переменную локальной в пределах области видимости функции, цикла, условия и вообще любого блока видимости.
>Я вообще не понимаю, что вы тут хотите мне доказать?
Лично я сюда зашёл для того, чтобы привнести рациональность в пост 10летнего крестовика.
>>1072292
>Блять, поясни пожалуйста тогда что ты понимаешь под локальный и глобальной переменной, потмоу что по моему у тебя об этом не правильное представление.
Локальное - это то, что определено в структе или компаунд стейтменте. В стандарте вообще не используются слова global (только в одном месте: http://port70.net/~nsz/c/c99/n1256.html#F.8.1p1) и local, так что по отношению к стандарту неправильным моё представление быть не может.
>Алсо, ты можешь сделать перменную локальной в пределах юнита компиляции
Здесь наши с тобой опыты расходятся. В моём опыте никто и никогда не говорил о невидимых извне переменных, как о локальных. В качестве пруфа моей нормальности прими ссылку на стаковерфлоу:
https://stackoverflow.com/search?q=[c]+local+variable
>Локальное - это то, что определено в структе или компаунд стейтменте. В стандарте вообще не используются слова global (только в одном месте: http://port70.net/~nsz/c/c99/n1256.html#F.8.1p1) и local, так что по отношению к стандарту неправильным моё представление быть не может.
>>1072292
>язык С не соответствует каким-то вашим ожиданиям и представлениям о локальных и глобальных переменных?
То, что ты там себе навыдумывал про свои идеалы локальных переменных, не значит абсолютно ничего.
Я не понимаю, как по твоему должно было быть?
По моему, все очень логично.
extern - глобальная переменная.
static - локальная в пределах компиляции.
auto - локальная на стеке.
__thread - локальная в пределах треда.
Тебе этого мало? Я просто даже не представляю, какие виды локальных переменных еще могут быть По моему опыту в различныъ ЯП кроме С/С++, типа Явы, С#, D, питон, перл, луа, пхп, яваскрипт, хаскель, математика, матлаб. Нигде виды переменных особо не отличаются, ибо это то, что есть в С, это уже более чем достаточно.
>Тебе этого мало?
Во избежание дальнейшего разговора на неинтересную мне тему я не буду напоминать тебе о том, что мой дискуссионный вопрос, дальше которого ты не читал, был не о переменных.
>Нигде виды переменных особо не отличаются
Бред сивой кобылы. Ты говоришь о видимости? Видимость переменных может:
1) вообще не зависеть от места их определения, а лишь от того, было выполнено определение или нет - Perl (с версии 5 скоуп управляет только хранением, а не видимостью), Шелл до какой-то версии (в баше можно приписать local. В Посиксе этого нет)
2) зависеть от скопа (функция, глобальный, суперглобальный), от static (значение совсем другое) и от того, было ли выполнено определение - PHP
3) зависеть от того, было ли объявление выше в скопе (без учёта вложенности блоков), при этом у каждой функции свой скоп - Джаваскрипт
4) версия Си - скоп на каждую фигурную скобку
5) чистая функциональщина
И это я ещё про единицы трансляции не говорил: в PHP вообще нет доступа к переменным извне и нет способа определения одной переменной на всех. Что значит "не отличаются"?
>Я не понимаю, как по твоему должно было быть?
По-моему должно быть так, что если есть несколько функций, которые работают с одними и теми же данными, то у меня должен быть инструмент для их обобщения. Такой инструмент у меня есть.
>extern - глобальная переменная.
Допустим, что я понял твою криво выраженную мысль. Дай ссылку на текст, в котором под глобальностью подразумевается именно это.
>Бред сивой кобылы. Ты говоришь о видимости? Видимость переменных может:
Ладно может с пхп и яваскрип я что-то напутал ибо последний раз писал на этом еще в школе.
Но говоря про С только видимость определяет тип переменной. Т.к в С нету объектов, а есть только базовые типы и структуры состоящие из них, то есть переменные при выходе из их области определения не нужно очищать, вызывать деструкторы и т.п ( кроме переменных на стеке, где память указываемая ими, может быть перезаписана после выхода из области видимости в силу специфики работы стека ).
Но ты понимаешь, что С это низкоуровневый язык где предоставляющий тебе самому управление памятью, а в других языках, инициализация и деинициализация переменных может влечь за собой аллокейты из кучи и другие действия, типа сборки мусора и т.п?
В С как в ассемблере, хочешь глобальную переменную, определяй ее в секции .data, хочешь локальную переменную вычитай сколько нужно из rsp, хочешь динамическую память, дергай ядро ОС.
>По-моему должно быть так, что если есть несколько функций, которые работают с одними и теми же данными, то у меня должен быть инструмент для их обобщения.
Ну так и что, тебе мешает такой инструмент реализовать без глобальных переменных? Используй контекстный метод, передавай структуру в эти функции в качестве аргумента.
Я сейчас работаю над одним достаточно крупным проектом на С, и у меня там нет ни одной переменной определенной за пределами функции.
Вообщ,е использовать глобальные переменные не очень хорошая идея, в любом языке программирования.
Глобальные переменные - это костыли для использования не очень хорошо спроектированных интерфейсов, которые не позволяют передать свой контекст во внутрь.
> Дай ссылку на текст, в котором под глобальностью подразумевается именно это.
У тебя своей головы нету, чтобы без чужого мнения это самостоятельно понять?
Ты когда объявляешь переменную в глобальном неймспейсе, она по умолчанию extern.
А что не так?
Проблемы у тебя. Показывай код.
>двумерного массива указателей "int ✬✬arr;"
Это называется "двумерный динамический массив", если тебе так хочется.
А ты массив-то вообще инициализируешь?
Хватит уже про Си рассказывать, я без тебя знаю его и до фига всего другого, и про экстерн я тоже знаю. Даже если ты очень знающий и скиластый, ты должен с собеседником говорить, а не сам с собой и своими мыслями.
>У тебя своей головы нету, чтобы без чужого мнения это самостоятельно понять?
Ты так и не открыл ссылку, по которой находится список вопросов и ответов о языке C, в которых люди употребляют слова "local" и "variable". Попробуй прочитать эти упоминания, держа в уме твоё личное определение глобальности. Пока ты этого не сделаешь, говорить с тобой не о чем.
>Ну так и что, тебе мешает такой инструмент реализовать без глобальных переменных?
Какие ещё глобальные переменные, блядь? Ты совсем охуел? Прочти ещё раз цитату >>1072042 из моей портянки, которую ты осуждаешь, слова "переменная" там нет. И это, если ты не знал, в С++ (языке семейства С++) с 11 года есть лямбды, подмножество которых совместимо с C-функциями.
Я вообще не понимаю, чего вы тут обсуждаете. Вложенные функции есть в гцц в виде расширения. Лямбды, видимо, будут в C2x.
Обсуждаем термин "глобальная переменная", который во всём мире означает "определённый вне функций", а именно у этого почтенного индивида означает "external linkage".
Заодно практикуюсь в общении с людьми, которые учат меня, разговаривая сами с собой.
шарю лютейшую годноту от реально гения в плане разъяснениыя. Да, он ебанный индус, да блядь его произношение это пиздос, но блядь, как же он ахуенно разъясняет и объясняет то, что вы будете читать в 1к страничных книгах.
https://www.youtube.com/watch?v=si-KFFOW2gw&list=PLVlQHNRLflP8IGz6OXwlV_lgHgc72aXlh
После этого рекомендую пробежатся уже по King C.C. A modern Approach C (2008), что бы закрепить материал.
Потом советую пройтись по C in Nutshell, для более продвинутого закрепления и понимания сишечки.
Потом советую прочитать: Reese R. - Understanding and Using C Pointers - 2013
что бы варится нормально с указателями, различными динамическими структурами и всем этим самым сложным, что создает кучу проблем, но не будет создавать для вас, потому что будете понимать как это устроено.
Потом обязательно Practical C Programming 3rd Edition
И Ben Klemens - 21st Century C, 2nd Edition - 2014
Ну и к этому моменту вы будете свободно плавать в синтаксисе и понимании языка для выражения всего чего можно, вот тут и начинается само программирование, и погружение в программирование и написание годноты и чего только захотите:
Principles of Data Structures Using C
Ну а дальше ищите книги по структурам данным, по различным алгоримам, и пишите алгориты, и различные реализации, паттерны и прочий шлак, и реализовывайте, реализовывайте всякие алгоритмы и прочий скам, подключайтесь к различным проектам.
Но до этого ОБЯЗАТЕЛЬНО загуглите нормальные туториалы по дебагингу, профайлингу, поиску и нахождению ошибок и так далее.
Ну а дальше уже дело практики - писать нужно дохуя и много.
=======================
Теперь что касается шапки - шапку писал отбитый нахуй долбоеб.
К&R крайне критикуемая книга, которую книгой назвать нельзя, она нахуй вообще ни на что не годится, это некий референс документ, а для референса всегда есть Prinz P., Kirch-Prinz U. - C Pocket Reference - 2002
Различные праты, и прочий скам на русском - так же не рекомендую, они перевирают кучу всего, и дохуя всего не работает. Начните с индуса выше, что бы было визуальное представление как все устроено. А только потом читайте книги, они будут даваться вам в десятки раз легче, когда уже в голове визуализацию выстроил индус.
Ну а дальше винапи, и прочий скам, можете на С++ перекатиться, можете продолжить дрочитьСи.
Самое главное к чему вы должны прийти это писание кода и тестов к нему. Не пишите тесты - значит вы хуёвый дегенерат нахуй никому не нужен, и знания ваши никчемны.
Не можете понять что такое Binary Heap - вы нахуй не нужны в программировании.
===============
касательно мотивации - к сожалению с Си без вовлечения в какой-то проект где он используется будет крайне тяжело если сравнивать например с C#
Потому что либ практически нет (вернее они есть, но не для простых инетересных и понятных вещей) плюс будете 90% времени не писать код, и фиксить баги и чужие краши. Поэтому программированию особого не научитесь.
Если хотите именно научится программированию - то питон это ваше все как первый язык, либо Go, и то, лучше всеже питон, потому что то, что вы будете писать месяц на Си, на сотнях строк кода, в питоне умещается лаконично в 20 строчек без вдавания в детали.
В Питоне вы именно программируете, и изучаете эти структуры, и прочий шлак, без траты просто пиздец какого куска времени на борьбу с указателями, памятью и прочей хуйней на которую находясь на этапе новичка - вы не должны тратить и ебать свой мозг, потому что это очень тяжело.
Это как получившего только что школьника права и категорию Б, посадить за штурвал истребителя, и показать - как взлетать, и сказать "Ну ты там в воздухе разберешься", так не бывает.
Удачи зайчики.
шарю лютейшую годноту от реально гения в плане разъяснениыя. Да, он ебанный индус, да блядь его произношение это пиздос, но блядь, как же он ахуенно разъясняет и объясняет то, что вы будете читать в 1к страничных книгах.
https://www.youtube.com/watch?v=si-KFFOW2gw&list=PLVlQHNRLflP8IGz6OXwlV_lgHgc72aXlh
После этого рекомендую пробежатся уже по King C.C. A modern Approach C (2008), что бы закрепить материал.
Потом советую пройтись по C in Nutshell, для более продвинутого закрепления и понимания сишечки.
Потом советую прочитать: Reese R. - Understanding and Using C Pointers - 2013
что бы варится нормально с указателями, различными динамическими структурами и всем этим самым сложным, что создает кучу проблем, но не будет создавать для вас, потому что будете понимать как это устроено.
Потом обязательно Practical C Programming 3rd Edition
И Ben Klemens - 21st Century C, 2nd Edition - 2014
Ну и к этому моменту вы будете свободно плавать в синтаксисе и понимании языка для выражения всего чего можно, вот тут и начинается само программирование, и погружение в программирование и написание годноты и чего только захотите:
Principles of Data Structures Using C
Ну а дальше ищите книги по структурам данным, по различным алгоримам, и пишите алгориты, и различные реализации, паттерны и прочий шлак, и реализовывайте, реализовывайте всякие алгоритмы и прочий скам, подключайтесь к различным проектам.
Но до этого ОБЯЗАТЕЛЬНО загуглите нормальные туториалы по дебагингу, профайлингу, поиску и нахождению ошибок и так далее.
Ну а дальше уже дело практики - писать нужно дохуя и много.
=======================
Теперь что касается шапки - шапку писал отбитый нахуй долбоеб.
К&R крайне критикуемая книга, которую книгой назвать нельзя, она нахуй вообще ни на что не годится, это некий референс документ, а для референса всегда есть Prinz P., Kirch-Prinz U. - C Pocket Reference - 2002
Различные праты, и прочий скам на русском - так же не рекомендую, они перевирают кучу всего, и дохуя всего не работает. Начните с индуса выше, что бы было визуальное представление как все устроено. А только потом читайте книги, они будут даваться вам в десятки раз легче, когда уже в голове визуализацию выстроил индус.
Ну а дальше винапи, и прочий скам, можете на С++ перекатиться, можете продолжить дрочитьСи.
Самое главное к чему вы должны прийти это писание кода и тестов к нему. Не пишите тесты - значит вы хуёвый дегенерат нахуй никому не нужен, и знания ваши никчемны.
Не можете понять что такое Binary Heap - вы нахуй не нужны в программировании.
===============
касательно мотивации - к сожалению с Си без вовлечения в какой-то проект где он используется будет крайне тяжело если сравнивать например с C#
Потому что либ практически нет (вернее они есть, но не для простых инетересных и понятных вещей) плюс будете 90% времени не писать код, и фиксить баги и чужие краши. Поэтому программированию особого не научитесь.
Если хотите именно научится программированию - то питон это ваше все как первый язык, либо Go, и то, лучше всеже питон, потому что то, что вы будете писать месяц на Си, на сотнях строк кода, в питоне умещается лаконично в 20 строчек без вдавания в детали.
В Питоне вы именно программируете, и изучаете эти структуры, и прочий шлак, без траты просто пиздец какого куска времени на борьбу с указателями, памятью и прочей хуйней на которую находясь на этапе новичка - вы не должны тратить и ебать свой мозг, потому что это очень тяжело.
Это как получившего только что школьника права и категорию Б, посадить за штурвал истребителя, и показать - как взлетать, и сказать "Ну ты там в воздухе разберешься", так не бывает.
Удачи зайчики.
да я тоже проигрываю постоянно. Но согласись, все по делу, и с дельными примерами, ничего вообще лишнего и нет задач "а давайте посчитаем на нашем первом занятии факториал такого-то числа, либо единицы измерений математической формулой поизменяем.
А у меня котик.
Бамп вопросу. Использование конкретно GLFW вообще необязательно, сойдёт любая легковесная кроссплатформенная библиотека, которая сможет создать мне окно и дать его идентификатор.
Бред неосилятора.
Сейчас бы учить что-то с видосиков
Ты сам жирный.
https://ideone.com/MNI6wN
Прога должна считать сумму всех отрицательных чисел, произведение между максимальным и минимальным значением и затем сортировать по возрастанию. Сумму и сортировку делает, а произведение делает, но не так - добавляет в вычисление либо максимальное, либо минимальное значение, смотря какое первее стоит. Что не так в коде? И как сделать так, чтоб если между максимальным и минимальным нет чисел, писало что-нибудь типа "произведение = 0"?
> *imin=i;
Не делай так. i не инициализирована.
> добавляет в вычисление либо максимальное, либо минимальное значение
Очевидно, что тебе нужно начинать цикл не с frirst, а с first + 1.
> И как сделать так, чтоб если между максимальным и минимальным нет чисел, писало что-нибудь типа "произведение = 0"?
if (first + 1 >= end) { return 0; } (естественно, swap перед этим по необходимости).
Братан, закину денежку тебе если ты мне это в код вставишь
в общем, будет работать?
а блин, не понятно ещё как сколько принты стека отжирают. а без них как-то скучно.
как-то же это всё люди делают.
https://stackoverflow.com/questions/20059673/print-out-value-of-stack-pointer
как-то грустно это всё. нахуй нужны тогда эти джампы, чисто чтобы вылезти из глубокой рекурсии, ну да. но не вылезти и вернуться. хотя нет, вернуться же можно.
а что если, вызывая новое приложение, прыгать к самому последнему и из его кода делать call....
просто я вот думаю, как сделать удобней возврат после запроса в обработчик. ну вот, допустим он вызывает опять приложение app0(void p) - где *p для значений этого инстанса. и как вот туда ему прыгать, к контексту внутри? switch ? гццшный goto массив? я не знаю.
наверно действительно проще треды. может у этого название есть, типа блокирующиеся треды в одном потоке. хер знает.
> может у этого название есть, типа блокирующиеся треды
В нормальных ОС это есть искаропки. Называется фиберы, реализуют кооперативную многозадачность. И да, чем тебе не нравится ебля контекста ручками? Это единственный адекватный подход. И вообще, чего ты добиться хочешь и зачем? И ты заебал своим бложеком, иди-ка ты в /dr/. Или пиши нормально.
> типичный пассивно-агрессивный пидоран
я не удивлён. в прочем, я ничего расписывать не буду, чисто попукал в мёртвый тред.
>>1074803
ладно-ладно. не обижайся, это было познавательно.
https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
> #define crBegin static int state=0; switch(state) { case 0:
> #define crReturn(i,x) do { state=i; return x; case i:; } while (0)
> #define crFinish }
> int function(void) {
> static int i;
> crBegin;
> for (i = 0; i < 10; i++)
> crReturn(1, i);
> crFinish;
> }
> #define crReturn(x) do { state=__LINE__; return x; \
> case __LINE__:; } while (0)
прикольный вариант.
Можешь еще green threads погуглить. А фиберы из Windows, очевидно же.
В современных ОС - только память процесса, да и то с оговорками: придется проглатывать исключения при попытке доступа к невыделенной памяти и придется как-то обойти свой собственный код. Чтобы затереть всю память (как делает, например, BIOS при проверке памтяи), нужен нереальный (flat real mode) или правильно настроенный защищенный режим, чтобы процессу была доступна последовательно вся физическая память.
Спасибо, то есть даже если под рутом на линуксе делать, никаких глобальных форматирований не стоит ожидать?
Драйверы тоже разные есть. User mode и kernel mode. Последние с оговорками могут.
> Будет null pointer dereference и сегфолт.
NULL pointer - это абстракция из стандарта Си. В любой ОС можно сделать так, чтобы никаких сегфолтов не было. В частности, в XP (и вроде бы даже в 7 SP1 до некоторых пор) можно было выделить память по 0 прямо из юзермода, без особых привелегий.
В таком выражении будет печататься значение для t или для s?
При чем тут абстракции языка? Ты понимаешь, что переменная это всего лишь указатель на адрес памяти?
Если ты напишешь на С:
char mem = 0;
mem = 0;
То на ассемблере это будет выглядеть примерно так:
mov ax,0
mov [ax],0
Что является обращением к памяти по адресу 0, что на системе с виртуальной памятью в user mode вряд ли возможно, т.к процессу назначается не нулевой стартовый адрес.
В общем, такое невозможно в принципе сделать в загруженной ОС.
Вот почитай http://wiki.osdev.org/Memory_Map_(x86)
У постфиксного ++ приоритет выше всего, поэтому берется адрес из s, потом s инкрементируется, потом адрес дереференсится звездочкой, потом аналогично вычисляется левый аргумент, и = пишет в него значение из правого. Более понятный аналог:
float temp = (t[0] = s[0]); // Ну или звездочки, но их макака съест.
printf("%f ", temp);
++s;
++t;
На свой вопрос сам ответишь.
> При чем тут абстракции языка?
При том, что по соглашению и из-за распространенности Си операционные системы не мапят первые 4 или 64 килобайта. Чтобы говнокод с NULL падал, как и положено. Но:
1) Ты вообще читал, что я написал? Никто не запрещает тебе выделить память самому. Если не из юзермода, то уж из кернелмода 100% возможно.
2) У тебя там 16-битные инструкции, а в том же DOS обращение по нулевому офсету было стандартной практикой, а с обращения к нулевому офсету нулевого сегмента (far null pointer) начиналась печать таблицы обработчиков прерываний. Например, в отладочных целях.
> Если не из юзермода, то уж из кернелмода 100% возможно.
Ни чего что кернел мод работает с виртуальной памятью тоже? И обычные kmalloc выделяют тебе виртуальную память?
Меня интересует случай, когда присваивание находится внутри printf.
Правильно ли я понимаю, что раз левый аргумент вычисляется последним, то его значение и напечатается, то есть в моем случае для t?
Я не понимаю, что ты пытаешься доказать. kmalloc - это тупой маллок, он не позволяет указать виртуальный адрес, по которому нужно выделить память.
>>1075017
> когда присваивание находится внутри printf.
От того, что оно синтаксически там находится, поведение не меняется.
> Правильно ли я понимаю, что раз левый аргумент вычисляется последним, то его значение и напечатается, то есть в моем случае для t?
Последним вычисляется присваивание, у = наименьший приоритет. Но = как и все операторы "возвращает" результат, он равен присваиваемому значению, и вот этот результат становится аргументом printf.
> Что является обращением к памяти по адресу 0, что на системе с виртуальной памятью в user mode вряд ли возможно
Вот специально для тебя наговнокодил. Требует рута, поэтому не ideone.
Что-то я не понял, что за mmap такой, который возращает код а не адрес памяти?
http://man7.org/linux/man-pages/man2/mmap.2.html
Посмотри, какой адресс тебе вернет mmap, то что там происходят я не знаю.
> который возращает код а не адрес памяти
А я-то думал, что с тобой не так. А ты просто читать не умеешь. У тебя по ссылке черным по белому написано, что MAP_FAILED = (void *) -1. Ну и, конечно же, mmap() возвращает мне адрес, по которому я замапил страницу, а замапил я ее по 0, поэтому он мне возвращает 0. Если запущу не под рутом, вернет MAP_FAILED.
Нет с возвратом я понял, потом.
Но ты же не знаешь точно какой адресс, тебе возвращает mmap т.к просто опускаешь возвращаемое им значение. Сомневаюсь, что там будет 0х0, тем более даже если это так, он все равно мапится на виртуальную память, так что смысла в этом не особо много, т.к. нулевой адрес в виртуальной памяти процесса, впринципе возможен, только он будет укзывать то на другой физический.
> Но ты же не знаешь точно какой адресс, тебе возвращает mmap
MAP_FIXED же. Я ему явно указываю, что хочу именно NULL.
> так что смысла в этом не особо много
> он будет укзывать то на другой физический
А вот тут ты прав. Чтобы пройтись по физическим страницам последовательно, нужна другая магия. Называется /dev/mem, ее точно так же можно замапить, но оно не везде доступно, и те регионы, которые через него видно, целиком и полностью зависят от ядра. Но через кернелмод можно и это обойти.
>он все равно мапится на виртуальную память, так что смысла в этом не особо много, т.к. нулевой адрес в виртуальной памяти процесса, впринципе возможен, только он будет укзывать то на другой физический.
и к чему это всё? кого ебёт что там в физической памяти. мы живём в мире с единорогами и радугами.
но я читал про это как-то, хотя мне всегда казалось, что NULL может менять своё значение в зависимости от платформы, на деле вроде нет. но опять же, это пространство языка, не будет тебе malloc выделять 0 и ладно.
>/dev/mem
Ну во-первых он отключен по умолчанию.
Да и потом, не думаю что из protected mode можно что-то записать в такую низкоуровневую память < 1MB. Думаю, что процессор не даст что-то туда записать и сделает прерывание.
> Думаю, что процессор не даст что-то туда записать
Процессору абсолютно похуй, какой адрес выставлять на адресную шину. Защищенный режим защищает один процесс от другого, а не компьютер от программ.
Ну попробуй, собери ядро с /dev/mem или напиши свой syscall или модуль ядра, и попробуй че-нить записать туда напрямую.
Я бы не говорил, если бы не пробовал. И с линуксом, и напрямую.
>>1074988 (OP)
>>1074988 (OP)
>>1074988 (OP)
>>1074988 (OP)
>>1074988 (OP)
>>1074988 (OP)
Вы видите копию треда, сохраненную 5 ноября 2017 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.