Это копия, сохраненная 20 июля 2017 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
Пожалуйста, пользуйтесь https://ideone.com/ или http://pastebin.com/ для вставки кода, если он длиной больше нескольких строк или содержит [i] или ∗.
Что читать:
- Классика от Отцов: http://www.cypress.com/file/56651/download
- Годное пособие для гуманитариев: 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 помогает читать сложные сишные декларации.
Прошлые треды:
- №19: https://arhivach.org/thread/248880/
- №20: https://arhivach.org/thread/254158/
- №21: https://arhivach.org/thread/260316/
Шапка: http://piratepad.net/bJ1SdmkZyu
За крестовопросы — бан.
Упырь свой мел. Ты не модератор, чтобы мне указывать
Даже препод не может ничего сказать, в гугле нихуя, поэтому прошу совет по решению тут, мб кто подскажет что нибудь
Сама задача:
В графе н айти максимальное (по количеству ребер) подмножество попарно несмежных ребер
>Ребят, попалась очень сложная задача в курсовике
>Даже препод не может ничего сказать, в гугле нихуя, поэтому прошу совет по решению тут, мб кто подскажет что нибудь
Сколько заплатишь?
Я не специально, лол
Никакого секрета тут нет, берешь все подмножества ребер, выбираешь из них попарно несмежные, и ищешь максимальное из них.
1. Попробуй сначала для определённого вида графов - отрезок, цепь, дерево.
2. Попробуй вывести алгоритмы сложения подмножеств несмежных ребёр.
3. Переформулируй задачу, скажем таким способом:
Среди всех рёберных раскрасок графа, необходимо найти раскраску, мощность множества ребер какого-то цвета максимально.
Алсо, с раскраской тут что-то сразу нагуглилось - https://ru.wikipedia.org/wiki/Паросочетание
И там сразу ссылки на алгоритмы поиска наибольших паросочетаний.
Наверное не совсем по теме треда, но попробую.
Читаю книжку "Практика программирования" 2004 года.
В 9 главе наткнулся на пикрелейтед.
Что за "Гриша" имеется ввиду?
"Фишка" перевода?
В исходниках https://9p.io/sources/extra/9hist/power/errno.h
> Egreg, / it's all greg's fault /
О чём речь-то???
Какая-то очень старая шутка из Plan9 судя по всему, имеется в виду Greg Chesson. Ну а перевод Greg = Гриша, ну петросянство, ну что поделаешь.
Да, я понял, что Greg сокращение от Gregory, по-нашенски Григорий.
Там даже в исходник есть имя ken кен томпсон видимо, но имена пишутся с большой буквы и это смутило%%.
Да и не совсем было ясно из комментарием. До и после идут обычные комментарии с пояснениями, тут раз какой-то greg.
Вот и смутило.
Как в VS компилировать код с минимальным размером кроме настроек пикрил?
Какие директивы компилятора нужно использовать, чтобы переменная в в PE-файле была в секции кода, а не инициализированных констант?
Можно ли встроить/переписать себе функции из WinAPI, чтобы не было привязки ко всяким Kernel32.dll, user32.dll, чтоб можно было просто вытащить секцию с кодом из исходного PE файла и вставить её целиком в другую и не ебаться с подгоном адресов функций, импортом и т.п.?
Так вышло, что мне нужно написать инжектор, но инжектить собираюсь не зловред, а протектор. В большинстве мануалов инжектят чистый ассемблерный код чисто для JMP в Х-код, но там подходы в основном для кода малого размера без особого выебонства, а мне нужно целую, блядь, программу, запихать в произвольный чужой PE - файл. Вот сижу и думаю, чё делать то с переменными, импортом и всем прочим. Наименьшим геморроем мне представляется просто взять и выдрать .text секцию из протектора и захуярить в защищаемый .exe в отдельную секцию хотя Касперски предлагает размазывать код оверлеем по паддингам секций, но чё то это попаболь, учитывая, что дедлайн через 2 недели, а помимо этого еще куча других дел с дальнейшим смещением точки входа на новую секцию (+ еще надо будет в конце внедренной секции добавить JMP на OEP, но это, надеюсь, не сложно).
> целую, блядь, программу, запихать в произвольный чужой PE
Родина дала им LoadLibrary(), но нет, надо изъебываться. В крайнем случае посмотри на reflective dll loader из метасплоита, например.
> чтобы переменная в в PE-файле была в секции кода, а не инициализированных констант?
https://msdn.microsoft.com/en-us/library/wxz26dz2.aspx
> Можно ли встроить/переписать себе функции из WinAPI
Hash-based import, только антивирусы тебя за это очень любить будут, и с SxS-либами в современных ОС все очень непросто.
>LoadLibrary()
Я думал об этом, но, во первых, идея хранить весь протектор в dll мне не нравится. Не могу объяснить почему, наверно потому что факт хранения целого подмодуля в отдельном .dll мне не по душе, хотя реальных аргументов особо нет. Во вторых, у executable, насколько я понял, один хрен выполнение начинается с точки входа программы, и потом уже загружаются библиотеки, у которых дёргают DllMain(), а мне нужно, чтобы сначала начинал работу протектор и только потом, если проверка выполнена успешно, начиналось выполнение самой программы. И тут еще нюанс есть (на мсдн в документации), в DllMain не рекомендуют хранить сложные вычисления, типа загрузчик может залупиться. Хотя сейчас я задумался, можно ведь и просто dll подкинуть в таблицу импортов, сдвинуть EP куда нибудь в оверлей секции (при этом расширив virtual size секции, чтобы это был уже не оверлей), там просто вызвать LoadLibrary(%протектор%.dll), GetProcedureAddress (%протектор.main()%), вызвать процедуру по полученному адресу, а потом JMP на OEP. Какие подводные камни помимо того, что в любом дизассемблере/дебагере вызов функции из dll как на ладони, затри участок NOP'ами оставив только JMP - и поехали. И тут еще вопрос появился - если я собираюсь упаковывать/криптовать код целевого приложения, чтобы нельзя было в дизасме/дебаггере нащупать, то загрузчик ведь не подставит адреса импортируемых функций, как быть?
Пасеба. Через #pragma comment() такие вещи позволяется делать?
>Hash-based import, только антивирусы тебя за это очень любить будут, и с SxS-либами в современных ОС все очень непросто.
нихуя не понял, у Касперски только про стандартный, bound и delay импорт читал, но после идеи с LoadLibrary(), если конечно я правильно понял твою подсказку, может вообще откажусь от первоначальной затеи.
Так, пожжи ебана, для LoadLibrary ведь вообще не надо либу протектора импортировать, так? Главное, шоб .dll был в папке с .exe? Но тогда мне надо, знать адрес LoadLibrary и GetProcAddress() из Kernel32.dll не говоря уж о том, чтобы она вообще была, хотя подкинуть её не проблема, есть чужая либа для работы с PE для этого, или загрузчик сам увидит, что я использую эти функции и любезно укажет внедренному коду загрузки протектора адреса этих функций?
> идея хранить весь протектор в dll мне не нравится
И зря. Минимум проблем в будущем.
> мне нужно, чтобы сначала начинал работу протектор и только потом, если проверка выполнена успешно, начиналось выполнение самой программы
CreateProcess(CREATE_SUSPENDED), вставляешь JMP на LoadLibrary по EP, но не забываешь о существовании TLS callbacks. А если exe тоже твой, то нахуя тебе внешний протектор вообще?
> DllMain не рекомендуют хранить сложные вычисления
Чушь. В DllMain нельзя вызывать некоторые функции из-за возможных проблем по причине вздернутого loader lock.
>>994878
> Hash-based import
> нихуя не понял
Посмотри любой шелкод для винды. Получаешь список загруженных длл из PEB, ищешь kernel32, парсишь импорты, ищешь LoadLibrary, грузишь нужные либы, парсишь импорты... Для ускорения процесса, обфускации и уменьшения размеров бинарника имена функций часто хэшируются.
>А если exe тоже твой, то нахуя тебе внешний протектор вообще?
exe не мой, писал же - произвольный чужой exe
>Чушь. В DllMain нельзя вызывать некоторые функции из-за возможных проблем по причине вздернутого loader lock.
Ага, вроде нельзя вызывать функции, вешающие основной тред, типа диалоговых окон. Вот только в случае ошибки проверки предполагается выводить окно типа "поцан ты денешку отдал за программу))?", и тут мне как раз хорошо зашёл бы MessageBox. + вроде не рекомендуется убивать хост-процесс из .dll.
>CreateProcess(CREATE_SUSPENDED)
Дк пользователь же будет запускать программу дабл кликом по .exe. Или в заголовках PE можно указать, чтоб процесс запускался повешенный?
> Дк пользователь же будет запускать программу дабл кликом по .exe.
> Или в заголовках PE можно указать, чтоб процесс запускался повешенный?
Можно сделать ланчер, который инжектит, что нужно. Можно сделать, чтобы при запуске конкретного exe запускался какой-нибудь другой (это отладочный механизм, не нравится антивирусам, но работает - гугли Image File Execution Options). Я хуй знаю, какие у тебя там требования, но очевидно, что если пользователь может запускать что-то даблкликом без протектора, он будет это делать, а протектор потрет.
Ананасы, если я буду писать код, в котором буду использовать системный вызов getaddrinfo для получения значения IP-адреса в виде 32-битного integer (если я всё правильно понял, то getaddrinfo записывает нужное мне значение в struct addrinfo строго в big-endian), то мне ведь не нужно ебаться с порядком байтов для портабельности, если единственной функцией, которая прямо использует полученное значение является вот это:
#define IP_TO_STR(ip_str, ipv4_addr) do { \
snprintf(ip_str, IP4_STR_LEN, "%u.%u.%u.%u", \
(unsigned char) ((ipv4_addr >> 0) & 0xff), \
(unsigned char) ((ipv4_addr >> 8) & 0xff), \
(unsigned char) ((ipv4_addr >> 16) & 0xff), \
(unsigned char) ((ipv4_addr >> 24) & 0xff)); \
} while (0)
Упс, не туда ответил
> IP_TO_STR
Да, порядок всегда будет сетевым (big endian), но зачем ты изобретаешь inet_ntoa?
На юниксах - нет (по крайней мере в мане thread-safe нигде не указано. А упоминание о использовании статического буфера есть). Другое дело, что есть inet_ntop, но мне она не подходит, т.к. не на всём нужном железе поддерживается.
https://github.com/bminor/glibc/blob/73dfd088936b9237599e4ab737c7ae2ea7d710e1/inet/inet_ntoa.c#L27
Ну да ладно, ты в общем-то прав.
1)Создание структурированного типа данных:
-Книга: название, предметная область, год издания
2)Действия над массивом структур:
-подсчет количества книг, относящихся к предметной области "Физика";
-нахождение книги с самым старым годом издания.
1) часть я сделал по крайней мере всё выводится, код: https://pastebin.com/yF0hgZ5T
2) прошу помощи у вас разобраться с этой хуетенью. В теории понимаю что нужно сделать - создать массив в виде отдельной функции которая будет считать эти книжки, но блять, нихуя не получается, нужно до завтра. Верю в тебя, анон!
А что не получается-то? Копипиздишь цикл с 24 строки.
> Посчитать по предметной области
Создаешь счетчик, присваиваешь 0. В цикле идешь по книгам, с помощью strcmp сравниваешь field текущей книги со строкой "Физика", если возвращается 0, увеличиваешь счетчик.
> нахождение книги с самым старым годом издания
Заводишь переменную oldest_index, присваиваешь 0. Идешь в цикле по книгам, если год текущей книги меньше года книги с oldest_index, записываешь в oldest_index индекс текущей книги.
Задача:
В заданном бинарном дереве посчитать количество вершин на N-ном уровне, считая корень вершиной 0-ого уровня
Саму программу я написал, но работает она не так, как нужно
Скорее всего ошибка в этой функции - https://pastebin.com/XPxGaaD4
Идея в том, что я разделяю уровни NULL'ом И когда мы находимся на нужном уровне выходим из цикла и просто достаем элементы из очереди до последнего NULL'а. res - результат
Put - функция для добавления элемента в очередь
Get - функция для взятия элемента из очереди
Empty - функция для проверки на пустоту очереди
Вот фулл код - https://pastebin.com/gLUVEhf0
Зло, когда нечитаемые. А это - вполне читаемый макрос. Хотя можно было бы и inline-функцию сделать.
>>995329
Хуй знает, у тебя все вроде норм, кроме того, что корень получается вершиной 1 уровня, а не 0, ну и т. д.
>>>995331
Вот-вот
while (!Empty(q))
{
z = Get();
res = res + 1;
}
Единственное в чем сомневаюсь, это этот цикл, правильно ли >while (!Empty(q)) в этом случае
Ну можно слегка поправить логику. Как-то так (на изменения вне ShowTree не смотри): https://pastebin.com/WyJwiuQN ideone только у меня сломался и ничего не постит?
Ну во захуярил счетчик с циклом, но консоль крашится, после того как я ввожу последний год 3 книги https://pastebin.com/tHewRGBP
1) У тебя там gets_s неправильно вызывается, где второй аргумент? И вообще лучше используй scanf везде, коли начал: scanf("%30s", libry[ i].name). И getchar() тогда из тела цикла убери, scanf сама пробелы и переводы строк пропускает.
2) k не инициализируешь.
3) strcmp() == 0 надо. strcmp как бы "вычитает" одну строку из другой, и когда их "разность" == 0, строки равны.
что неправильно вызывается? вот пик, всё выводится же нормально. k инициализирована, в pastebin чекни, ну или на скрине
> что неправильно вызывается?
https://msdn.microsoft.com/ru-ru/library/5b5x9wc7.aspx Посчитай аргументы там, а потом у себя. И ворнинги в компиляторе включи, блять.
> всё выводится же нормально
Счастливое совпадение.
> k инициализирована, в pastebin чекни
int k;
k = k + 1 это не инициализация. Ты по сути пишешь int k = мусор; k = мусор + 1.
Спасибо, всё захуярил
Ананасы, это вообще нормальный стиль, когда исолняемый файл динамически линкуется с shared либой и использует её функции, а либа в свою очередь использует внешнюю переменную бинарника (т.е. в либе имя переменной объявлено как extern)? Я вот до сегодняшнего дня не знал даже, что так можно делать (дергать переменные исполняемого файла из подключаемой библиотеки) и теперь не уверен - а правильный ли это подход?
И вообще - как оно работает? Я вот сделал objdump исполняемого бинарника и не увидел имени переменной, которая используется
А, нет, пизжу, увидел.
В общем-то забейте, я понял, что это - хуевая идея
Неужели ради одной большой хуйни целый цирк придумывать?
Спасибо огромное, очень помог
Только один вопрос
Что такое
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
>#define _CRT_SECURE_NO_WARNINGS
Это знаю, но чем это отличается от обычного
#define _CRT_SECURE_NO_WARNINGS
Ничем. Просто _MSC_VER определяется компилятором Microsoft Visual C++, и соответственно дефайн делается только для этого компилятора. Это в принципе не обязательно, но как бы намекает читающему, что во всем виноват Microsoft.
>В чем конкретная проблема-то?
Я понятия не имею, что нужно кроме хидеров для сборки под винду и чем после cmake это собирать.
>В Си нет.
Ух придерся. Ну ладно, мне нужно что-нибуть более-менее POSIX-совместимое (ну или хотя бы чтоб на большинстве эмбеддед и не очень линуксов работало).
gethostbyname, getaddrinfo и вся эта библиотечная ебала не подходит, т.к. а) они слишком перегружены всякой хуйней б) не являются по сути DNS-резолверами в) не гибкие (например, нельзя даже установить таймаут запроса). Дефолтный gethostbyname еще и кривой, т.к. не может в многопоточность.
Тут стандартными библиотечными функциями не отделаешься никак и нужно готовое решение, но я пока еще не сильно горю желаниям велосипед писать.
> Дефолтный gethostbyname еще и кривой, т.к. не может в многопоточность.
Опять ты начинаешь. Мы же уже выяснили, что может, если это линукс и glibc. В линуксе есть асинхронный getaddrinfo_a, и без проблем со статическим буфером заодно. Не нравится - спизди из той же glibc или uclibc. Ну и на гитхабе DNS-клиентов до жопы. Может кто и посоветует что-то конкретное, но у меня никогда не возникало необходимости в кастомном ресолвере.
1) Слишком много прыжков по оперативной памяти.
2) Синтаксис я/п можно взять и новый, от Ц++
3) Наследование реализации — зло.
Извиняюсь, обосрался.
Как обратиться к clr для элемента массива?
delete[] t;
С с++ выглядит на Си?
Просто free(t); ?
Да.
скажите, тут совсем ВСЕ ПЛОХО или это просто ПОЛНЙ ПИЗДЕЦ?
http://ideone.com/uUBXQe
Ну поехали:
1) T payload; Смысл есть, но это когда оно в хедере. Этакие шаблоны для бедных: задефайнил T, подключил хедер, получил реализацию для T (но только один раз в одном модуле). В остальных случаях лучше написать прямо или хотя бы делать T не дефайном, а вменяемым тайпдефом (PayloadType?).
2) Node ∗newNode(): где void в скобках? Это точно Си?
3) Касты для malloc() не нужны, он возвращает указатель на void.
4) Сообщения об ошибках посреди реализации библиотечного, по сути, кода. Но для лабы в принципе сойдет.
5) if (q == NULL) { puts("Out of memory!"); return ∗q;}: это типа все равно продолжать бесполезно, давайте умрем прям тут? Или опечатка?
6) qPush: это какой-то бессвязный список. Одним концом втыкаем элемент в очередь, второй конец очереди в воздухе висит. Где tmp->next инициализируется, я вообще не нашел.
7) &q->oldest == &q->recent: если адрес одной ячейки структуры равен адресу другой ячейки структуры, то... это union, блять. Потом там какой-то дабл-фри и опять бессвязный список. Что? Еще один фри? Ох, ебать!
8) Что там творится с рекурсией ниже 100 строчки, я вообще не распарсил.
9) Стека не увидел.
10) Начиная читать, я ожидал увидеть: Queue_AddToHead, Queue_RemoveFromHead и аналогично для Tail. Тогда реализация стека ограничилась бы использованием уже готовой Queue и молчаливым игнором пары функций для работы с одним из концов Queue.
11) В идеале я бы вообще выкинул весь мемори-менеджмент из кода Queue, оставив только лишь управление двусвязными списками, ну и проверку размера, если очень хочется. Тогда я мог бы сам решать, что туда класть и где выделять под это память:
typedef struct ListNode { struct ListNode ∗prev, ∗next; } ListNode;
void Queue_AddToHead(Queue ∗q, ListNode ∗node);
ListNode ∗Queue_RemoveFromHead(Queue ∗q);
typedef struct MyYobaType { ListNode listNode; int my_payload; char another_payload[10]; };
...
MyYobaType ∗item = malloc(sizeof(∗item));
... some init ...
Queue_AddToHead(q, &item->listNode);
MyYobaType ∗item2 = Queue_RemoveFromHead(q);
if (item2) {
...;
free(item2);
}
Так сделано в ядре винды, например.
Ну поехали:
1) T payload; Смысл есть, но это когда оно в хедере. Этакие шаблоны для бедных: задефайнил T, подключил хедер, получил реализацию для T (но только один раз в одном модуле). В остальных случаях лучше написать прямо или хотя бы делать T не дефайном, а вменяемым тайпдефом (PayloadType?).
2) Node ∗newNode(): где void в скобках? Это точно Си?
3) Касты для malloc() не нужны, он возвращает указатель на void.
4) Сообщения об ошибках посреди реализации библиотечного, по сути, кода. Но для лабы в принципе сойдет.
5) if (q == NULL) { puts("Out of memory!"); return ∗q;}: это типа все равно продолжать бесполезно, давайте умрем прям тут? Или опечатка?
6) qPush: это какой-то бессвязный список. Одним концом втыкаем элемент в очередь, второй конец очереди в воздухе висит. Где tmp->next инициализируется, я вообще не нашел.
7) &q->oldest == &q->recent: если адрес одной ячейки структуры равен адресу другой ячейки структуры, то... это union, блять. Потом там какой-то дабл-фри и опять бессвязный список. Что? Еще один фри? Ох, ебать!
8) Что там творится с рекурсией ниже 100 строчки, я вообще не распарсил.
9) Стека не увидел.
10) Начиная читать, я ожидал увидеть: Queue_AddToHead, Queue_RemoveFromHead и аналогично для Tail. Тогда реализация стека ограничилась бы использованием уже готовой Queue и молчаливым игнором пары функций для работы с одним из концов Queue.
11) В идеале я бы вообще выкинул весь мемори-менеджмент из кода Queue, оставив только лишь управление двусвязными списками, ну и проверку размера, если очень хочется. Тогда я мог бы сам решать, что туда класть и где выделять под это память:
typedef struct ListNode { struct ListNode ∗prev, ∗next; } ListNode;
void Queue_AddToHead(Queue ∗q, ListNode ∗node);
ListNode ∗Queue_RemoveFromHead(Queue ∗q);
typedef struct MyYobaType { ListNode listNode; int my_payload; char another_payload[10]; };
...
MyYobaType ∗item = malloc(sizeof(∗item));
... some init ...
Queue_AddToHead(q, &item->listNode);
MyYobaType ∗item2 = Queue_RemoveFromHead(q);
if (item2) {
...;
free(item2);
}
Так сделано в ядре винды, например.
Окей. Спасибо. То есть, тут нужно сразу оговорится, что я не настоящий сварщик, конечно. И это вообще моя первая штука на С, сложнее хеловорлда.
>Смысл есть, но это когда оно в хедере.
особенности домашки, препод просит все сдавать в одном файле.
Я понимаю, что в жизни в жизненном примере это должно быть иначе. Но это чисто попробовать, посмотреть как оно.
>где void в скобках? Это точно Си?
В первый раз слышу, если честно. IDE и коньпилятор ни словом не обмолвись. Ни ворнинга, нихуя.
>Касты для malloc() не нужны
ок, просто решил перестраховаться. Они остались после рефакторинга, на самом деле. изначально, вместо newNode(); был именно каст. потом я обернул в функцию и добавил инициализацию. а маллок так и остался.>>997752
> это типа все равно продолжать бесполезно, давайте умрем прям тут?
Вроде того. Ну, как я понял, эксепшенов в C нет, разбираться и читать как обрабатывать такую хуйню времени тоже небыло. Типа въебал плейсхолдер, чтобы компилилось, мол, если будет время - поправлю. Но нет. уже два ночи, хули. Сдавать завтра.
>Где tmp->next инициализируется, я вообще не нашел.
Он инициализируется как NULL при создании ноды. Хвост показывает в нулл, да. Когда к хвосту прибавляется еще один элемент, нулл становится поинтром на последний элемент (который теперь показывает на предыдущий и в нулл).
>&q->oldest == &q->recent: если адрес одной ячейки структуры равен адресу другой ячейки структуры, то...
ну типа очередь же. убиваю старейший элемент, и говорю следующему за ним, что он теперь самый старый. если самый молодой тот же что и самый старый, значит я добрался до конца очереди.
>Что? Еще один фри? Ох, ебать!
ЩВАБОДКА ЖИ. На самом деле, когда элемент списка больше не нужен, я его грохаю. Я совершенно не уверен, что я это делаю правильно, но, да, я не настоящий сварщик, я ленивое быдло котрое привыкло полагатся на коллекторы.
>Что там творится с рекурсией ниже 100 строчки, я вообще не распарсил.
Это тупая шутка, слабо имеющая отношение к коду вообще. Можно считать это инструментом дебага. Это говно рекурсивно бежит по n->next пока не уткнется в нулл поинтер и печатает payload в консоль. Почему рекурсивно? Да потому что пошли вы нахуй, вот почему. Этот код не делает ничего полезного и написан через жопу вполне осознано.
>Стека не увидел.
А его и нет. какой смысл писать то же говно чуть под другим углом, ели я вижу, что это полное говно, а новых идей нет. Тем более что времени не осталось.
>тогда реализация стека ограничилась бы использованием уже готовой Queue и молчаливым игнором пары функций для работы с одним из концов Queue.
Да, изначально я что-то такое и предполагал. Но почти на два часа увяз в поинтрах сраных. И до сих пор не могу сказать что понял, как с ними ебатся.
сам по себе Queue помнит первый и последний элемент. остальные просто линкуют друг друга. У меня нет как таковой головы и хвоста. у меня какой-то сраный котопес у которого голова с двух сторон.
Ну то есть как, структура Queue знает что у нее есть первый и последний элемент, где они лежат, и общую длину. каждый элемент знает чей хуй у него в жопе и у кого в жопе его хуй. По идее, я могу по такому списку бежать с любого конца. В это, по крайней мере была идея.
Но окей, спасибо, комментарии познавательные. Но, еще раз, это реально первый раз в жизни, когда я пишу что-то отдаленно похожее на реальный код в сях. И я не то, что бы когда-то собирался учить именно Си или реально кодить на нем. Я высокоуровневое быдло. Но кто-то решил что в жизни недостаточно боли, и решил показать некоторые премудрости кодинга на примере Сей. Ну, чтоб знал, сынку, откуда в твоих жавах массивы берутся. Это, конечно, интересно, и дохуя чего понял из того что раньше было просто ебаной магией, но я нет. Спасибо, но нет.
Окей. Спасибо. То есть, тут нужно сразу оговорится, что я не настоящий сварщик, конечно. И это вообще моя первая штука на С, сложнее хеловорлда.
>Смысл есть, но это когда оно в хедере.
особенности домашки, препод просит все сдавать в одном файле.
Я понимаю, что в жизни в жизненном примере это должно быть иначе. Но это чисто попробовать, посмотреть как оно.
>где void в скобках? Это точно Си?
В первый раз слышу, если честно. IDE и коньпилятор ни словом не обмолвись. Ни ворнинга, нихуя.
>Касты для malloc() не нужны
ок, просто решил перестраховаться. Они остались после рефакторинга, на самом деле. изначально, вместо newNode(); был именно каст. потом я обернул в функцию и добавил инициализацию. а маллок так и остался.>>997752
> это типа все равно продолжать бесполезно, давайте умрем прям тут?
Вроде того. Ну, как я понял, эксепшенов в C нет, разбираться и читать как обрабатывать такую хуйню времени тоже небыло. Типа въебал плейсхолдер, чтобы компилилось, мол, если будет время - поправлю. Но нет. уже два ночи, хули. Сдавать завтра.
>Где tmp->next инициализируется, я вообще не нашел.
Он инициализируется как NULL при создании ноды. Хвост показывает в нулл, да. Когда к хвосту прибавляется еще один элемент, нулл становится поинтром на последний элемент (который теперь показывает на предыдущий и в нулл).
>&q->oldest == &q->recent: если адрес одной ячейки структуры равен адресу другой ячейки структуры, то...
ну типа очередь же. убиваю старейший элемент, и говорю следующему за ним, что он теперь самый старый. если самый молодой тот же что и самый старый, значит я добрался до конца очереди.
>Что? Еще один фри? Ох, ебать!
ЩВАБОДКА ЖИ. На самом деле, когда элемент списка больше не нужен, я его грохаю. Я совершенно не уверен, что я это делаю правильно, но, да, я не настоящий сварщик, я ленивое быдло котрое привыкло полагатся на коллекторы.
>Что там творится с рекурсией ниже 100 строчки, я вообще не распарсил.
Это тупая шутка, слабо имеющая отношение к коду вообще. Можно считать это инструментом дебага. Это говно рекурсивно бежит по n->next пока не уткнется в нулл поинтер и печатает payload в консоль. Почему рекурсивно? Да потому что пошли вы нахуй, вот почему. Этот код не делает ничего полезного и написан через жопу вполне осознано.
>Стека не увидел.
А его и нет. какой смысл писать то же говно чуть под другим углом, ели я вижу, что это полное говно, а новых идей нет. Тем более что времени не осталось.
>тогда реализация стека ограничилась бы использованием уже готовой Queue и молчаливым игнором пары функций для работы с одним из концов Queue.
Да, изначально я что-то такое и предполагал. Но почти на два часа увяз в поинтрах сраных. И до сих пор не могу сказать что понял, как с ними ебатся.
сам по себе Queue помнит первый и последний элемент. остальные просто линкуют друг друга. У меня нет как таковой головы и хвоста. у меня какой-то сраный котопес у которого голова с двух сторон.
Ну то есть как, структура Queue знает что у нее есть первый и последний элемент, где они лежат, и общую длину. каждый элемент знает чей хуй у него в жопе и у кого в жопе его хуй. По идее, я могу по такому списку бежать с любого конца. В это, по крайней мере была идея.
Но окей, спасибо, комментарии познавательные. Но, еще раз, это реально первый раз в жизни, когда я пишу что-то отдаленно похожее на реальный код в сях. И я не то, что бы когда-то собирался учить именно Си или реально кодить на нем. Я высокоуровневое быдло. Но кто-то решил что в жизни недостаточно боли, и решил показать некоторые премудрости кодинга на примере Сей. Ну, чтоб знал, сынку, откуда в твоих жавах массивы берутся. Это, конечно, интересно, и дохуя чего понял из того что раньше было просто ебаной магией, но я нет. Спасибо, но нет.
> IDE и коньпилятор ни словом не обмолвись. Ни ворнинга, нихуя.
С пустыми скобками ты как бы говоришь "функция принимает какие-то аргументы", это старый стиль, он не запрещен в общем-то. В крестах эта же запись значит "функция не принимает аргументов". В общем, похуй.
> Он инициализируется как NULL при создании ноды
Читал жопой, каюсь. Но в общем-то, при oldest == NULL стоит присваивать к oldest, и к recent сразу один и тот же элемент.
> &q->oldest == &q->recent
Ты имел в виду запись без &, поверь. Иначе ты сравниваешь адреса памяти, где лежат указатели (а они лежат рядом в структуре, разница в байтах sizeof(struct Node ∗), в элементах = 1). Но смысла условия я не понял, хотя и предполагаю, что вместо первых двух free() ты хотел просто присвоить NULL (задумайся - ты удалил 1 элемент, а память освобождаешь трижды!). Последний free() ок.
> Ну, чтоб знал, сынку, откуда в твоих жавах массивы берутся
Ты так говоришь, как будто в жабе связанные списки по-другому делаются.
Ты просишь повторить четырежды, а сравниваешь с тремя повторами. Другое дело, что sizeof(char) == 1 по определению, памяти выделяешь мало (тебе нужно len ∗ count + 1, где 1 - это место под \0). Ну и без strcat можно было обойтись, не бегая каждый раз от начала строки в поисках ее конца, когда ты по факту знаешь, где начнется очередной кусок, и можно было бы хоть через memcpy копировать.
Скопировал криво. Здесь https://www.codewars.com/kata/string-repeat/train/c
этот код всё равно не работает и с + 1 , может в задании ошибка
Не заметил очевидную проблему. Когда ты выделяешь буфер через malloc(), его содержимое не определено. В том числе, там может содержаться какой-нибудь мусор. strncat() добавляет строку в конец этого мусора. Ты был прав, тебе на самом деле нужно было воткнуть ∗result = '\0'; (перед циклом), чтобы изначально буфер был пустой строкой, и strncat() работал правильно.
Друиды, помогите. Хочу вызвать LoadLibraryA по адресу в виртуальной памяти, при этом адрес я хочу получить сам, основываясь на данных таблицы импорта скомпилированного PE файла и ImageBase, который я получаю через FindImageBase(). Я скомпилировал приложение (код 1.png), вытащил из получившегося PE RVA функции LoadLibraryA. Как я понял, это RVA, в который будет записан VA той самой функции, но тем не менее получаемый адрес отличается от того, что я получаю по auto x = LoadLibraryA. ЧЯДНТ?
Это может быть как нибудь связано с relocation'ами? Типа, мне чтоб получить действительный RVA, нужно к значению из PE файла прибавить фактический ImageBase -
номинальный ImageBase?
Я у мамы хакир? GetProcAddress не модно у нынешних хакиров уже?
Контакты:
hekkus*@)hunANUSbkp5\PUNCTUMrCaGu
тг - @Hekkushun
Правила знаешь?
>что мало кому захочется возиться со мной бесплатно, но больших сумм предложить не могу (об этом лучше поговорить лично)
сиськами на камеру свети в качестве оплаты
> Если язык применяет подход с автоматической сборкой мусора , то можно ли использовать в ней либы из Си?
Можно. Сборка мусора собирает то, чего много (память). Всякие файлы, сокеты и прочие дорогие вещи все равно нужно закрывать явно, ибо их количество может быть ограничено, а сборщик мусора когда там еще отработает.
>>999014
Тут спрашивай.
Сам имею пхп-бекграунд, хочу вкатиться в С, подскажите нормальный учебник.
Читай для бегиннеров, делай задачки. После K&R или Праты можно уже брать простенькую реальную задачу и по ходу дела разбираться с тем, чего не знаешь. Ну или можно сверху еще Стивенса про юникс-программинг навернуть.
https://ideone.com/7RspWD - так всё работает
https://ideone.com/LttVQ8 - input_ptr теперь аргумент функции, а не глобальная переменная. Почему сегфолтится может кто объяснить?
(я хочу все глобальные переменные перенести в параметры, чтобы функцию run() можно было вызывать много раз)
Не запускал, но очевидное отличие между двумя версиями: когда ты когда ты запускаешь вторую версию, и рекурсивно вызванная run() меняет свой input_ptr, она меняет свой, локальный input_ptr, а внешняя run() этого изменения, конечно же, не видит, у нее тоже свой локальный input_ptr. Передавай указатель на указатель или сразу сообрази себе структуру с контекстом, в числе которого будет лежать и input_ptr тоже.
А мне представлялось, что указатель он на то и указатель, чтобы иметь один адрес в любой точке программы, теперь понятно.
Нет, указатель - это просто адрес адреса, никакими выдающимися свойствами не обладает.
https://ideone.com/SHTWFd
Такая хрень получилась в итоге. Пытался заменить 3 параметра для строки кода на один указатель, но не получилось из-за логики в циклах.
Итак, господа, написал кусок кода со следующей идеей: беру изображение, загружаю его в память как массив из w*h элементов типа unsigned long. Я хочу посчитать, сколько раз мне встречается каждый из возможных цветов, при этом я хочу несколько упростить задачу и все пикселы округляю, сдвигая их побитово на 4 вправо и потом на 4 влево. Получается охуительный массив с округлёнными пикселями, это я проверил и это хорошо работает.
Дальше я хочу посчитать, сколько раз встречается пиксел каждого цвета. Результаты заношу в табличку, но пока до этого не дошло и я просто вывожу в терминал через printf. Вижу два пути решения: либо я каждый пиксел проверяю на присутствие в таблице, и если он там есть - инкрементирую счётчик для него, а если нет - дописываю со счётчиком 1. Этот способ, я проверил, работает, но долго и хуёво. Второй способ: беру первый попавшийся пиксель, проверяю весь массив, высчитывая, сколько раз он там встречается, если вижу другой - выписываю в другой массив. Потом вызываю мою функцию уже с другим массивом, из которого те пиксели уже как бы вычтены. И так повторяется, пока в массиве не останется элементов. И, как я уже написал, к нему я список свой не прикрутил. Для маленьких изображений работает пиздато. Но если взять сколько-нибудь большое изображение, начинается пиздец, он выводит ошибку сегментации довольно быстро. Уменьшать количество цветов путём сдвига более чем на 4 не помогает, разбивать изображение на куски почему-то тоже: код нормально выполняется для нескольких первых кусков, потом посылает меня нахуй с помощью segmentation fault.
Функция http://ideone.com/Vlt4RU
Есть неебически простое и неебически быстрое решение. С целыми 32-битными пикселами не работает (на 32-битных машинах), но если откинуть альфу, вполне норм. Суть:
1) Выделяешь массив uint32_t count[N]. Размер массива = 256 x 256 x 256 = 0x1000000 элементов. По 4 байта на элемент - это 64 мегабайта. Это много, зато быстро (да и нужно ненадолго). Выделять лучше calloc-ом, чтобы потом не пришлось бегать по нему и обнулять. Создаешь еще счетчик total = 0.
2) Идешь по входному массиву пикселов: берешь i = pixel & 0xffffff (т.е., без альфы) и просто делаешь (count++ || total++). В результате получаешь total равным количеству цветов в массиве, можешь на его основании выделять дальнейшие буферы и т.п.
3) Идешь по получившемуся массиву count (индекс - цвет, count[индекс] - количество). Выписываешь все ненулевые элементы. Можешь сортировать там по ходу дела (или после) по количеству использований, приводить к палитре и т.п. (фиг знает, зачем тебе это понадобилось), дело твое.
4) Очевидно, что если тебе нужны округленные или пикселы, тебе понадобится меньший массив count, но суть не изменится (если использовать старшие 4 бита каждого компонента (i = pixel_b >> 4 | pixel_g >> 4 | pixel_r >> 4), то 24 бита = 16, 163 компонента[/s] = 4096 элемента размером 4 КиБ x sizeof(uint32_t) = 16 килобайт массив).
Спасибо, охуенно работает. Обработка пикрелейтед: https://pastebin.com/pGuTDKGx
То есть примерно в два раза быстрее вышло. На некоторые другие файлы выходит быстрее, например, вместо 0.111 получается 0.033.
Не подскажешь способ узнать через терминал память, которую жрёт этот процесс? Время я узнаю запуская time ./test, а вот что с памятью - хз, гуглится не очень хорошее что-то.
Сейчас единственный способ узнать реальную память, которую процесс жрёт - это въебать в него сразу файлов 100 и пока он будет охуевать - отследить через pid.
> Не подскажешь способ узнать через терминал память
Ну можешь открыть для себя удивительный мир профилирования: http://valgrind.org/docs/manual/ms-manual.html
Алсо, time -v вроде умеет показывать максимум (только не тот, который в баш встроен, а который отдельной утилитой).
Спасибо, буду разбираться.
>>999392
>После K&R
Начал я его читать. Что-то я не пойму, неужели это самая крутая книга по С? Там прямо с первой страницы кормят говном 80-ых в виде main() {}, когда по современному стандарту может быть только int main() { return 1; } . Аноны, помогите, посоветуйте книгу хорошую по современному этапу развития языка, не хочу окунаться в какую-то неразбериху и потом переучиваться. Разве это сложно просто дать нормальную книгу?
> Там прямо с первой страницы кормят говном 80-ых в виде main() {}
Вот не начинай только. В первых тредах уже были срачи, они ничем хорошим не кончились. Да, синтаксис старый, да в C11 implicit int убрали. Но не все пишут на C11, в жизни все равно придется со старым кодом сталкиваться. В качестве введения в язык книга вполне сойдет.
> может быть только int main() { return 1; }
Если говорить о современных стандартах, то ты void в аргументах забыл. Ну и return 1 - это return EXIT_FAILURE.
> Разве это сложно просто дать нормальную книгу?
Прата. Есть в шапке. Я всегда советовал читать обе. И потом еще десяток. И мануал к компилятору. И вообще все что видишь.
Да я только вкотился в этот ваш С. Так как должна выглядеть самая простая функция main? Я как ньюфаг совершенно сконфужен. В книге мне говорят одна, на stackoverflow другое, CLION предлагает по умолчанию третье. Ненавижу эту путаницу, когда вкатываешься куда-либо.
нашёл по обычному С, посмотрю её, но всё равно бешусь от путаницы
Ты бы еще в плюсы или фортран покатился. Это говно за свои пятьдесят лет обросло тысячами ревизий, которые меняют то как надо этот язык. А вот информационную сферу от говна атлантов никто не чистил.
Соответственно, запросы в гогель бьешь не через C, а через C11. И книжки ищешь, в которых указано, что автор выучил весь новый стандарт перед тем как начать вываливать буквы.
> Так как должна выглядеть самая простая функция main?
int main(void);
int main(int argc, char ∗argv[]); // Или char ∗∗argv, это синонимы в данном случае.
И дополнительно реализация языка может предлагать еще какие-то варианты. Например, int main(int argc, char ∗argv[], char ∗envp[]); очень часто поддерживается. Но стандартных только два.
Минимальное тело main() пустое: {} (начиная с С99 разрешили в main(), и только в ней! не писать return - это равносильно возврату 0).
Можно еще void main(), тогда в конце return 0 подставит компилятор. А для выхода с кодом ошибки использовать exit().
void main() - это кресты. Не путай людей.
Я слышал, что все приложения, использующие данные либы стараются использовать .dll для быстрой поддержки секурити обновлений, и не вшивают OpenSSL статически (в том же Qt)
Однако где тогда находятся эти .dll в браузерах или в том же стиме?
Во-первых, в Chromium уже года три как свой форк: https://www.chromium.org/Home/chromium-security/boringssl . Во-вторых, собрано статически, ибо постоянные автообновления. В третьих, собрано статически, ибо каждая первая малварь норовит подменить длл на свою и выискивать твои банковские карточки и прочие пароли в трафике - со статическим билдом такое провернуть тоже можно, но уже слегка сложнее.
Анон, каковы шансы того, что функция ниже будет соптимизована таким способом, что переменная flag будет проверяться перед началом цикла, а не при каждой итерации?
void func(bool flag)
{
for (int i = 0; i < 1000; i++)
{
if (flag)
{
//do something
}
else
{
//do something else
}
}
}
И при обновлении они не вставляют куски кода, а просто банально заменяют конечный исполняемый файл? Или есть и другие трюки?
Шансы есть. Наблюдаемое поведение не изменится, значит у компилятора развязаны руки (зависит от того, что будет в do something, очевидно). Расскажи, что ты хочешь сделать, почему тебе оптимизации могут помешать?
>>1000189
Ну да. Какие могут быть трюки, когда установленный браузер весит больше, чем 15 лет назад весила вся ОС с офисом и прочим софтом?
Фриланса на сях почти нет. Пиши письма счастья в интересующие конторы, работающие с железками, вне зависимости от наличия вакансий. Не забудь няшный гитхабчик, где на сях есть что-нибудь кроме хелловорлда.
Ебусь с указателями. Именно это почему то довольно сложно идёт.
А есть ли какие то мнемонические правила?
Что именно ты хочешь запомнить и зачем?
А работа не связанная с железом и вот этим вот всем есть? Как вообще выглядит путь программиста на С в 2017? Не лучше ли учить С++? Помогает ли знание С при вкате в С++? Поясните вообще
На си можно делать что угодно, но как правило это эмбеддед + системное программирование. Ядра линупса, винды и макоси написаны на сях, например.
Начинать в принципе похуй с чего, но си проще крестов. В крестах вагон ненужной хуйни, которую страуструп зачем-то в них принес. Знание си помогает при вкате в кресты и наоборот.
> Что вообще можно делать на С?
Все.
> Писать под микроконтроллеры?
В том числе.
> А работа не связанная с железом и вот этим вот всем есть?
Пишу сервера под Linux и либы для обработки сигналов. Ну почти.
> Как вообще выглядит путь программиста на С в 2017?
Учишь Си, учишь кресты, учишь питон (или что-то другое скриптовое, что тебе по душе), учишь асм под интересующие архитектуры, разбираешься в предметной области.
> Помогает ли знание С при вкате в С++?
Местами помогает (синтаксис-то частично общий, но он дай бог процентов 10 от того, что нужно знать в крестах). Ну и надо понимать, что это другой язык и не скатываться в "си с классами".
> не скатываться в "си с классами"
Да нет, это как раз самый правильный вариант использования крестов.
>>1000730
Просто хочу вот слезть с веб-мартыханства во что-то более серьёзное (для души, бабосы на мартыханстве рубить продолжу), но вместе с тем не хочу оказаться у разбитого корыта микроконтроллеров и инжереской фигнёй с драйверами(ну не лежит душа к железу). Хочу для себя что-то выучить, на чём можно игру написать десктопную или просто окунуться в машин лёрнинг. Чтоб была свобода выбора и не поганая гонка фреймворков. Надеюсь, понятно объяснил.
Путь выбрал такой - сначала учу С и шлифую его, потом перехожу на кресты и начинаю писать для себя всякие искусственные интеллекты. всё правильно? не лучше ли сразу выбрать какой-нибудь пистон или swift?
> view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp);
> cameraPos + cameraFront
Как это возможно?
OpenGL, glm. Переменные "cameraPos" и "cameraFront" это "vec3", а "vec3" это, по идеи, массив из трёх элементов типа "float". Сложение двух массивов -- особенность крестов или я чего-то не понимаю?
> Расскажи, что ты хочешь сделать, почему тебе оптимизации могут помешать?
Не помешать, наоборот помогут. Кривой код переписывать лень, поэтому надеюсь, что компилятор сделает всю работу за меня.
Ну, например, когда есть рабочая машина состояний с определенным состояниями и подсостояниями, а теперь нужно сохранять еще одно состояние, которое будет висеть поверх других. Мне вот из-за скудности мышления сложно представить как это говно переделать так, чтобы код остался читабельным (т.е. без примитивного boolean флага, который будет сохранять это состояние) и без багов. В интернетах пишут о всяких СУПЕР-, паралельнх состояниях и т.п.
> В интернетах пишут о всяких СУПЕР-, паралельнх состояниях и т.п.
меньше этих пидарасов хипстерских читай, если появилась какая то еба значит проеб в архитектуре и алгоритме. если хочешь пиздецпиздецсложна мокнись в парсеры, особенно парсеры регулярок типа https://github.com/laurikari/tre
там тебе и стеки и переходы и прочии ништяки
>>1002101
Ну я лично столкнулся не с проебом в архитектуре, а с необходимостью делать слишком сложный алгоритм (но поделать с этим ничего не могу) для текущей машины состояний и вижу два решения: перелопачивать архитектуру, на что ни времени, ни компетенции нету, т.к. нужно это всё было сделать вчера, либо же использовать вот эти хипсторские решения, которые позволят более-менее сносно решить задачу.
Поэтому хотелось бы почитать книжечку для ньюфани без нормального опыта, где описаны решения некоторые well-known решения типичных задач.
Ну а регулярки – это уже слишком умно. но ты заинтересовал этой ёбой, надо на досуге почитать.
И вообще скорее всего я сам не знаю, что мне блять надо.
>И вообще скорее всего я сам не знаю, что мне блять надо.
скорее всего тебе надо стек в который ты будешь пихать нех при переходах
Алсо, чего можно почитать по общим каким-то устройствам и принципам работы ртосов?
Алсо, где можно почитать принципы разработки ПО для встраиваемых систем желательно не в виде сферических абстракций, а в виде реальных примеров с пояснениями почему делают так, а не по-другому?
Язык C в XXI веке
Advanced Topics C
C Primer Plus
Искусство программирования на C (лучше английский оригинал)
ADvanced Data Structures (Peter Brass)
В общем моя подпрограмма добавления элемента в таблицу просто создает упорядоченную таблицу и все. Нужно добавить какой то цикл, что бы она сразу упорядочивала. Не могу понять как.
Делал с пузырьковой сортировкой, но препод послал и сказал тип дедлай, что бы подпрограмма добавления элемента сразу создавала упорядоченную таблицу.
https://pastebin.com/zZDh98Pz
Вот код, на вход подается что то вроде 12345678 name 100 (code, name, numb), упорядочить нужно по numb
>если тут есть кто то в такое время
Слишком рано?
>создает упорядоченную таблицу и все
А в чём проблема создавать сразу же упорядоченную таблицу, что собственно от тебя и требуют. Алгоритм очень простой. Добавляется новый элемент в таблицу, для него с помощью, например, бинарного поиска, ищется позиция. В зависимости от алгоритма поиска, нужно будет добавить элемент или перед текущим, или после него. У тебя есть столбец, по которому нужно будет сортировать. Вот по нему и сортируй. Возможно, для твоего случая может подойти функция qsort из стандартной библиотеки.
Запили умный дом или какую другую йобу на контроллерах. Сделай систему управления чем-нибудь, выложи на кикстартер, собирай профиты.
Учти, что в эмбедддед порог вхождения выше, желающих работать - меньше, следовательно вакансий меньше, т.к. банально некому работать. В веб же суются голодные бабуины за копеечную зарплату пилить формочки для внутреннего говнорынка. И кто такой СИСТЕМНЫЙ ПРОГРАММИСТ?
Вот как раз из свежего:
>Высшее техническое образование, полученное в приличном техническом ВУЗе РФ. Если в названии вашего ВУЗа присутствуют слова "социальный", "гуманитарный", "экономический",
>"финансовый","политический", "строительный" - просьба не беспокоить, так как нам нужны сотрудники ориентированные на телеком!
Просто мякотка, учитвая, что ещё и средняя макака без какого-либо образования может зарабатывать больше.
У тебя embedded по-английски. Не во всех российских компаниях кадровички знают английский. Часто ищут просто инженер-программиста, разработчика встраиваемых систем и т.д.
Да даже на иностранных площадках, embedded developer - нифига не канон. Может быть и Firmware/RTOS/DSP/Automotive/C/C++ developer и чего ещё только не выдумывают. И в 99% случаев это будет embedded.
>по созданию ПО серверного и терминального оборудования видеоконференцсвязи, а также облачной видеоконференцсвязи
>Желателен опыт работы с системами жесткого реального времени.
Мне кажется, эти уёбки не понимают сути hard real-time.
Ну вот, как я подозревал. Под вакансией СИСТЕМНОГО программиста (заметь, в описании даже и близко нет намека на то самое системное программирование) сейчас подрозумевается работа рознорабочим в какой-то унылой умирающей конторке из нулевых/90х.
>Под вакансией СИСТЕМНОГО программиста (заметь, в описании даже и близко нет намека на то самое системное программирование) сейчас подрозумевается работа рознорабочим в какой-то унылой умирающей конторке из нулевых/90х
Совсем не факт. Сейчас ОС крутится в каждом электрочайнике.
>>1002519
>>1002522
>>1002524
>>1002534
>>1002538
>>1002539
>>1002543
>>1002545
>>1002549
Хорошо, как вкатиться в это ваше системное embedded программирование? Что надо знать и уметь?
От предпочтений зависит. Можно вкатиться в железо и максимально байтоебить (знание матана и электроники обязательно). Можно выучить юниксы, RTOS, многопоточность и уютно писать на сишечке. Лучший вариант: выучить и то, и другое.
Advanced programming in the unix environment подойдет. С OpenMP пока повремени, разберись для начала с нативными средствами (posix threads , потоки и их синхронизация во FreeRTOS, например)
> Возможно, для твоего случая может подойти функция qsort из стандартной библиотеки.
Не подошла
Спрошу ещё раз, может кто нибудь ответит
Вот полный код всей программы - https://pastebin.com/kt9BBRzA
С пузырьковой сортировкой все работает идеально, но нужно упорядочивать таблицу именно в этой функции - https://pastebin.com/zZDh98Pz
Вообще не понимаю, как это сделать
qsort и бинарный поиск не подходят
>в эмбедддед порог вхождения выше, желающих работать - меньше, следовательно вакансий меньше
А я думал, что у нас просто давным давно рынок потребительской электроники по пизде пошел и дальше только хуже, поэтому embedded никому не всрался кроме 3.5 контор, работающих на фсб и армию, и пары что-то пытающихся запилить стартапов.
>Не подошла
НЕ ЗЛИ МЕНЯ. У меня второй день не получается сделать бесполезную работу, а ты пишешь, что у тебя что-то не получается. Что у тебя не получается? Не можешь разобраться с параметрами? Первый параметр - твой массив таблиц, второй - количество элементов, третий - размер одного элемента, а четвёртый - твоя функция сравнения. В начале функции add_table вызываешь qsort, читаешь документацию, в которой написано, до или после этого элемента надо вставить новый элемент или брутфорсишь до правильного, благо там всего 2 варианта, с помощью memmove перемещаешь массив на один элемент, перед этим не забыв увеличить его с помощью realloc, memcpy для элемента на новое место. Всё, элементарно. Что ещё не понятно?
>У меня второй день не получается
Да я тоже не могу дописать это уже несколько дней, поэтому и написал сюда
>Не можешь разобраться с параметрами?
с qsort я разобрался, я понимаю как она работает и какие аргументы ей нужны
>Всё, элементарно
Просто попробуй сам написать дописать эти пару строк и поймешь, что то, что ты написал никогда в жизни не сработает в данном случае
> бинарный поиск не подходят
Или ты поясняешь, что не так с бинарным поиском, или идешь нахуй.
Да. У тебя есть пустой массив, тебе на вход приходит элемент, ты бинарным поиском вычисляешь нужное место в массиве и втыкаешь его туда, повторяешь. После каждой итерации массив остается отсортированным (пустой массив и массив из одного элемента, очевидно, тоже можно считать отсортированными).
А, окей
Пойдет такой https://pastebin.com/dh9K1cZp ?
Просто немного не понимаю, как правильно аргументы написать при вызове в данном случае, мне же не просто t[X] надо, а t[X].numb
Ну ты поправь его так, чтобы при отсутствии совпадения (т.е., когда low становится > high) возвращался предполагаемый индекс, а не -1. По этому индексу и будешь втыкать элемент.
С промышленной электроникой все в порядке. Всегда нужны кастомные решения, курс рубля на дне, необходимость сертификации, в т.ч. лоббируемая, все это работает на местных. Пациент определенно жив.
Даже потребительский сегмент: освещение, автосигнализациию.
>>1002565
Правильный выбор. В более железной части чистому программеру жизни нет, прислуга за все.
Как на C узнать текущее время системы (Linux), желательно не используя библиотеку <time.h>? Нужно считать и записать время системы+60 секунд, и затем сравнивать это значение с текущим.
Но какая-то из сторонних библиотек конфликтует с time.h, ругаясь на функцию nanosleep(без time.h всё компилируется и работает) Код содержащий nanosleep не мой, разбираться почему как часть с nanosleep работает и куда этот nanosleep в оригинале ведет - некогда
> Но какая-то из сторонних библиотек конфликтует с time.h, ругаясь на функцию nanosleep
Покажи, как ругается. Конфликт со стандартным хедером - это полный пиздец. Скорее всего, ты просто либу собрал неправильно или на другой машине. Но в принципе, это все быстро решается костылем из дефайна.
Держи. Вот кусок кода в котором нанослип вызывается:
while ( bcm2835_gpio_lev(pin) == laststate) {
counter++;
nanosleep(1); // overclocking might change this?
if (counter == 100)
break;
}
Тебе говорят, что nanosleep вызывается неправильно - он хочет два аргумента, а передают только один. Вызови правильно:
nanosleep(&(struct timespec) { .tv_nsec = 1 }, NULL); (ну или сколько тебе там ждать, хуй знает).
Я понимаю что мне говорят. Но без подключения time.h работает именно с одним аргументом. Я хз что он вызывает нанослипам в одном из подключенных заголовков.
Ну грепни заголовки, узнаем, откуда оно это берет. Ну и в крайнем случае, тебе никто не мешает сделать так (в качестве очень костыльного костыля, потому что лень/некогда разбираться):
#define nanosleep yoba_nanosleep
#include <time.h>
#undef nanosleep
Но в идеале надо править кривой код, а не городить костыли. Алсо, если погуглить этот твой код, в 99% случаев там nanosleep закомментирован нахуй, в остальном 1% там usleep.
Алсо, ты уверен, что ты с -Wall компилируешь? А то вот такой код тоже "работает", пока не подключишь stdlib.h:
int main(void) { qsort(0); }
Ну я других настроек gcc не подсовывал, но да, вот с -Wall Как-то немало варнингов.
>>1002917
У меня там чей-то код с хабры, для работы с датчиками DHT-11/DHT-22. Указанный на хабре сурс - лежит.
Как твой пример с дефайнами работает?
Алсо, если не сложно, поясни как мне получить при подключении time.h время от начала работы программы или системы в секундах или милисекундах?
> скриншоты
Я не о том говорил. Есть такая штука, как implicit function declaration (запрещена в C99, наконец-то) - наследие древних темных времен. Когда компилятор встречает вызов функции, о которой он не знает (т.е., еще не видел ее объявление или определение), он считает, что фунция возвращает int, а принимает любые аргументы. Т.е., контроль типов и количества аргументов у таких функций не производится (не с чем сравнивать правильность), производятся только стандартные promotions, типа char->int или float->double. И когда ты не подключая time.h вызываешь nanosleep, gcc (видимо) считает, что это неявная декларация и позволяет тебе передать один инт в качестве аргумента, только вот функция от этого не перестает хотеть два указателя. Если скомпилированный код после этого работает - он работает по счастливой случайности. Если же ты подключаешь time.h, gcc "узнает", как должен выглядеть вызов nanosleep, и говорит тебе, что ты не прав.
> Как твой пример с дефайнами работает?
Дефайн заменяет один идентификатор на другой. Когда препроцессор встречает time.h extern int nanosleep(что-то там), он производит макроподстановку, и получается extern int yoba_nanosleep(что-то там). После того, как time.h обработан, undef говорит, чтобы препроцессор перестал заменять идентификатор nanosleep на что-либо.
> поясни как мне получить при подключении time.h время от начала работы программы или системы
Ну стандартные способы получения времени - это time() и timespec_get(), но они возвращают таймстамп от 1 января 1970. Если тебе критично именно с начала работы системы, то clock_gettime(CLOCK_MONOTONIC) или всякие: http://man7.org/linux/man-pages/man2/sysinfo.2.html или http://man7.org/linux/man-pages/man2/clock_gettime.2.html и т. п.
Оке, спс.
>Если тебе критично именно с начала работы системы
Некритично вообще. Сравниваю просто два времени - одно (когда-то_записанное +60) и снятое_только_что.
Тайм что возвращает? long? В секундах или милисекундах?
>пример с дефайнами
Так толком и не понял. Он по сути заменяет в time.h имя nanosleep на yoba_nanosleep?
>implicit function declaration
Оке. Всё что я из этого вынес - надо заранее объявлять переменные.
VerQueryValue и товарищи. Это из ресурсов, из version info берется.
У кого-нибудь удавалось скомпилить ncurses под minix?
Если у меня есть указатель в проге, которым я в конце проги уже не пользуюсь, но мне нужен указатель, что лучше сделать:
-создать новый с понятным названием, или
-ссылка вида:
type &newName = oldName
И так будет правильно написать для такого кода:
struct Elem {...}
int main() {
Elem *oldName;
...
Elem &newName = odName;
}
?????
Прост у меня заморочка на тему сейва четырех байтов, но я хз, освобождает ли компилятор место из-под указателя, если далее он юзаться не планирует. А ссылка вродь памяти не занимает совсем.
#define newName oldName
Шютка. Не вздумай так делать. А вообще, судя по коду, тебе в плюсотред.
Тем не менее, могу заранее сказать, что я бы на твоем месте не пытался предугадать действия компилятора в отношении автоматических переменных, ибо занятие это неблагодарное. Подобные фокусы рано или поздно приведут к тому, что ты в один прекрасный момент отстрелишь себе ногу. А из отстреленной ноги вырастет тело Страуструпа и отымеет тебя в задницу.
Хочешь надежно застолбить четыре байта? Создай статическую переменную.
А вообще, создать новый указатель не такая уж плохая идея. Компилятор не еблан и он не будет держать на стеке порожняком четыре байта, которые можно пустить в дело.
>А вообще, судя по коду, тебе в плюсотред.
Мне в психушку надо. Ибо пишу типа на си, юзая некоторые плюшки из плюсов, и приправляя WinAPI32. Усё по методичкам нашего универа, по методике преподов.
Да и вообще, делить С и С++ на разные треды - бред, ИМХО.
>Хочешь надежно застолбить четыре байта? Создай статическую переменную.
Не, меня интересует именно судьба всяких int SortList, и похожих переменных и указателей, заюзанных где-нить в начале и далее не используемых. Жалко мне эти байтики.
>А вообще, создать новый указатель не такая уж плохая идея. Компилятор не еблан и он не будет держать на стеке порожняком четыре байта, которые можно пустить в дело.
Збс, значит буду объявлять каждый раз, когда потребуется.
Алсо, слышал, что если вначале объявить переменную и сразу синициализировать, типо int i = 0; то получим переменную не в куче а в стеке, т.е. статическую. И у меня подозрение, что VS2015 нихуя не освободит.
>делить С и С++ на разные треды - бред
не, у крестов слишком много оверхеда
qt, boost, темплейты и прочее, куча говна
>меня интересует именно судьба всяких int SortList
Такие переменные существуют в стеке, пока они нужны. Если переменная не используется, то место, которое она раньше занимала, используется для других нужд при наличии необходимости.
>если вначале объявить переменную и сразу синициализировать, типо int i = 0; то получим переменную не в куче а в стеке
Если ты объявляешь эту переменную внутри функции, то она по-любому будет на стеке. Чтобы создать переменную в куче, надо сначала явно выделить под нее место в этой самой куче.
>т.е. статическую
Переменные, для хранения которых компилятор сам резервирует место на стеке, относятся к автоматической памяти, а не к статической. Статическая память это либо глобальные переменные (т.е. объеявленные вне функций), либо явно объявленные с ключевыми словами static или extern. Инициировать статические переменные нулем не имеет смысла, поскольку они и так обнуляются на этапе загрузки программы.
>Да и вообще, делить С и С++ на разные треды - бред, ИМХО.
ООП моча не нужна, template говно тем более. Си простой и ясный язык, как Форт, как Лисп. Не надо сюда тащить всякое говно.
Java, C# (с вынесением медленных участков в нативные библиотеки на Си), Free Pascal/Lazarus, Oberon, Rust, Go, Swift, Fortran. Полно вариантов.
+ Ada еще
Это тебя яндекс в жопу выебал?
Ну я про case и говорю.
Если цикл что-то типа
switch (opcode) {
case OP_NOP:
...
case OP_RET:
...
}
То сделать массив функций:
typedef void OpcodeFn(VirtualMachineState state);
OpcodeFn opcodeFuntions[] = {opcodeNop, opcodeRet, ...};
void opcodeNop(VirtualMachineState state)
{...}
void opcodeRet(VirtualMachineState *state)
{...}
...
И в цикле просто вызывать opcodeFuntioncs[opcode]
Заодно и работать будет быстрее.
typedef void OpcodeFn(VirtualMachineState ·state);
OpcodeFn opcodeFuntions[] = {opcodeNop, opcodeRet, ...};
void opcodeNop(VirtualMachineState ·state)
{...}
void opcodeRet(VirtualMachineState ·state)
{...}
Этот паттерн, кстати, называется "шитый код". Применялся во многих реализациях Форта, в интерпретаторах Бейсика на 8-битных компьютерах (например, ZX Spectrum), в Фокале на БК-0010.
>Free Pascal/Lazarus, Oberon
Умерли.
>Rust
Пока еще малопопулярен, нет IDE, дебаггеров и прочих незаменимых инструментов.
>Go
Не годится в больших проектах
>Swift
Нет на винде и на линуксе
>Fortran
Умер
>Java, C#
Единственный годный вариант, но джава умирает, а С# живет в основном в asp.net
>в российском госсекторе используется
Я говорю о нормальных проектах, а не о поедании говна за деньги из бюджета.
Fortran не умер, просто мало распространен. Есть хороший оптимизирующий компилятор от Intel, неплохой GNU Fortran в составе GCC. Есть ООП, рекурсия, вроде даже лямбды:
https://stackoverflow.com/questions/21471640/fortran-return-an-anonymous-function-from-subroutine
Intel Fotran и GNU Fortran поддерживают параллельность через OpenMP.
>мало распространен
Так можно про любой язык сказать, даже про тот же хаскель. Я же говорю про язык для продакшена, для которого написаны сотни библиотек, есть годные инструменты, а главное - на нем пишется и будет писаться много новых проектов. Для фортрана было написано много библиотек в свое время, и он использовался для научных вычислений. Теперь его заменил питон, и фортран оказался не нужным.
> Я же говорю про язык для продакшена, для которого написаны сотни библиотек, есть годные инструменты, а главное - на нем пишется и будет писаться много новых проектов.
ПИТОН
Высокая производительность?
typedef struct {VMT ptrdiff_t; short int data;} T;
typedef struct {VMT ptrdiff_t; short int data; long int other_data;} T1;
Собственно вопрос допустимо ли приводить T1 к T? Не перевыравняет ли компилятор что-либо по своим усмотрениям?
Спасибо.
Сунь в union. Тогда можно будет обращаться к common initial sequence любой из этих структур.
>Не перевыравняет ли компилятор что-либо по своим усмотрениям?
Может да, а может и нет. Используй #pragma pack
>Не перевыравняет ли компилятор что-либо по своим усмотрениям?
Скорее всего нет. Но если делать все максимально кроссплатформенно и по стандартам, то правильнее всего так:
typedef struct {VMT ptrdiff_t; short int data;} T;
typedef struct {T base; long int other_data;} T1;
> Собственно вопрос допустимо ли приводить T1 к T?
По стандарту нет. Ибо strict aliasing, разные типы, гроб-гроб-кладбище, авторы компиляторов опять ломают язык ради оптимизаций. По факту да, можно так делать (и делают!), но лучше выделить одинаковую часть структур в отдельный тип.
>>1008395
> Используй #pragma pack
Нинужно. Выравнивание всегда одинаковое у конкретного компилятора на конкретной платформе.
> Проблема в том, что мне ООП навязало свою модель проектирования приложения, и с Си она собственно никак не коррелирует.
ООП ортогонально языку.
Так на сишке тоже можно писать ООП.
typedef struct {
int width;
int height;
void data;
} Image;
typedef struct {
Image ×image;
int x;
int y;
BOOL visible;
} Sprite;
Sprite Sprite_new() {
Spritesprite = (Sprite)malloc(sizeof(Sprite));
if (sprite) {
sprite->image = NULL;
sprite->x = 0;
sprite->y = 0;
sprite->visible = FALSE;
}
return sprite;
}
void Sprite_show(Sprite *sprite) {
if (sprite) sprite->visible = TRUE;
}
void Sprite_move(int x, int y) {
if (sprite) {
sprite->x += x;
sprite->y += y;
}
}
Так на сишке тоже можно писать ООП.
typedef struct {
int width;
int height;
void data;
} Image;
typedef struct {
Image ×image;
int x;
int y;
BOOL visible;
} Sprite;
Sprite Sprite_new() {
Spritesprite = (Sprite)malloc(sizeof(Sprite));
if (sprite) {
sprite->image = NULL;
sprite->x = 0;
sprite->y = 0;
sprite->visible = FALSE;
}
return sprite;
}
void Sprite_show(Sprite *sprite) {
if (sprite) sprite->visible = TRUE;
}
void Sprite_move(int x, int y) {
if (sprite) {
sprite->x += x;
sprite->y += y;
}
}
typedef struct {
int width;
int height;
void data;
} Image;
typedef struct {
Image image;
int x;
int y;
BOOL visible;
} Sprite;
Sprite Sprite_new() {
Sprite sprite = (Sprite)malloc(sizeof(Sprite));
if (sprite) {
sprite->image = NULL;
sprite->x = 0;
sprite->y = 0;
sprite->visible = FALSE;
}
return sprite;
}
void Sprite_show(Sprite sprite) {
if (sprite) sprite->visible = TRUE;
}
void Sprite_move(Sprite *sprite, int x, int y) {
if (sprite) {
sprite->x += x;
sprite->y += y;
}
}
typedef struct {
int width;
int height;
void data;
} Image;
typedef struct {
Image image;
int x;
int y;
BOOL visible;
} Sprite;
Sprite Sprite_new() {
Sprite sprite = (Sprite)malloc(sizeof(Sprite));
if (sprite) {
sprite->image = NULL;
sprite->x = 0;
sprite->y = 0;
sprite->visible = FALSE;
}
return sprite;
}
void Sprite_show(Sprite sprite) {
if (sprite) sprite->visible = TRUE;
}
void Sprite_move(Sprite *sprite, int x, int y) {
if (sprite) {
sprite->x += x;
sprite->y += y;
}
}
Странно, почему сбивается разметка, в прикрепленном треде все норм...
Запощу тут чтобы не проебать, ихнорируйте меня
http://web.eecs.utk.edu/~plank/plank/classes/cs360/general.html
Для заметок лучше использовать E-mail, там можно отправлять письма самому себе.
Да я понимаю, просто я на чужой машиенрии сейчас
Нет таких. Либо легкий, либо IDE, либо кроссплатформенный, либо FOSS. Я, например, предпочитаю SublimeText для более-менее простых проектов и полноценные "тяжелые" IDE для больших и сложных вещей. Для хелловорлда подходит любой блокнот, да.
Интерфейс тупой, бесполезный и перегруженный.
Anjuta попробуй, ничего лишнего и работает быстро.
Статические переменные же не в стеке хранятся.
Не кроссплатформенный, Pelle опять вымер на два года, никаких фич IDE нет - по сути просто блокнот с редактором ресурсов и кнопочкой "компилировать".
>С чем файлы-то
с байтами =) ну на самом деле дамп пиздецкого массива структур, размер структур всегда одинаков
Два чая, в сишке в отличие от C++/C#/Java автокомплит и рефакторинг не нужны.
Автокомплит нужен, если ты не под микроконтроллеры и прочий эмбеддед пишешь. Я вот сейчас хуй сам вспомню, как в каком порядке вызывать аргументы функций usb-core в линуксах, хотя писал под него меньше месяца назад.
и ты такой с автоконплитом хуяк хуяк и накодил? один хуй нужно ман просмотреть или копипастить со своего кода.
Когда накидываешь драйвера для однотипных устройств - да, хуяк-хуяк и накодил с автокомплитом.
https://spb.hh.ru/vacancy/21401883
Ты не подскажешь, в чём может быть проблема?
Делаю такое:
gcc "$(FULL_CURRENT_PATH)" -o "$(NAME_PART) ".exe
cd "$(CURRENT_DIRECTORY)"
$(NAME_PART).exe
Мой HelloWorld компилится, потом стартует процесс программы, но выхлопа ноль, никакого окна не возникает
Ты повёлся на слово «MISRA» как рыба на блесну, штолле? Но ведь это же:
- Люксофт (т.е. анкеты и IQ-тесты)
- Зарплата не указана (и ведь это редкий в наших краях специалист)
- Какие-то уебанские технологии, XBank, eDebug, Turbo-Ohuelli надо знать (а если не знаю — мне самому свою з/п называть, да?)
Короче, хватит. Пошутили и хватит! Нет такого языка программирования.
Edebug is a source-level debugger for Emacs Lisp programs, with which you can:
Step through evaluation, stopping before and after each expression.
Set conditional or unconditional breakpoints.
Stop when a specified condition is true (the global break event).
Trace slow or fast, stopping briefly at each stop point, or at each breakpoint.
Display expression results and evaluate expressions as if outside of Edebug.
Automatically re-evaluate a list of expressions and display their results each time Edebug updates the display.
Output trace information on function calls and returns.
Stop when an error occurs.
Display a backtrace, omitting Edebug's own frames.
Specify argument evaluation for macros and defining forms.
Obtain rudimentary coverage testing and frequency counts.
неа,
Вакансия Программист-разработчик C / C++ 250.000 Gross, ПО и драйвера ККТ, МСК
https://www.linux.org.ru/forum/job/13490618?lastmod=1497939633401
Но он почему-то не хочет сохранять мои скрипты, после перезапуска ничего нет
>- Зарплата не указана (и ведь это редкий в наших краях специалист)
У нас есть Анкета, в которой каждый кандидат указывает желаемую з/п. Мы стараемся учитывать предпочтения каждого=)
Вот код с функциями и пояснением:
https://pastebin.com/0DNkMMK0
Фулл код:
https://pastebin.com/P2LgQASf
И при этом ничего не компилится.
Нет права на запись в директорию, куда предполагается поместить бинарник твоей программы.
А, есть закономерность.
Если не открою эту папку в explorer, то никогда не даст gcc записать в папку, а если открыт explorer, то можно, вестимо, всем туда писать.
Б Е З О П А С Н О С Т Ь
Ага, так и нашёл файлик с конфигом для всей этой параши
Аналогичная хуйня на Server 2008R2. Собирал, собирал - и ошибки запрещенного доступа., Через некоторое время разрешало. ИЧСХ на семерке на ноуте такого нет.
Антивируса нет, индексация была нагуглена и отключена, как и теневые копии. Так что точно нет.
Если воспроизводится до сих пор, не можешь взять FileMon/ProcessExplorer и узнать точную причину?
Завтра гляну.
есть джва байтовых массива по 10 байт, нужно присвоить один другому. хочу обойтись без пидерских memcpy и циклов, а двумя операторами присваиваний, int64+int16. как это синтаксически будет выглядеть?
http://ideone.com/y6DhfC
Обернуть массив структурой, которая копируется по значению. Но это лютый говнокод, за который следует отбивать руки. Кроме того, не стоит забывать, что вся эта ебанина творится на стеке.
з.ы. звездочки макака захавал
>как это синтаксически будет выглядеть?
union Convert {
char c[10];
struct {
uint64_t a;
uint16_t b;
} s } c1, c2;
c1.c = { ... };
c2.s = c1.s;
Будет работать, хотя теоретически компилятор поля структур может разнести на произвольное расстояние. Правильнее через memcpy.
>memcpy
впизду, смотри >>1010404, утакуот работает
((uint64_t•)block1)[0] = ((uint64_t•)block2)[0];
((uint16_t•)block1)[4] = ((uint16_t•)block2)[4];
Type punning - плохой стиль. По стандарту надо через memcpy (лучший вариант) или юнионы (худший).
>плохой стиль
ойойой, это мне подняло скорость выполнения на треть, хотя всеравно этого мало...
Сам посмотри, с mempcy компилятор копирование вообще выкидывает, а через поинтер делает mov через sse:
https://godbolt.org/g/Qn8A4g
ну на самом деле у меня блок по 192байта и фактически я развернул цикл, а memcpy так не сможет. хотя вызовов memcpy не много, много вызовов memcmp, развернутый цикл выигрывает. кстати на 32 битных машинах, наверное 64 приведение обосрется...
мудрый анон, любой флаг оптимизации конпелятора ломает мою байтоебную прогу, это норма?
Таки норма. Оптимизация может покорежить и не-байтоебскую программу. Например, компилятор может выкинуть вызов memset(data, 0, data_size), если он расположен перед выходом из функции.
Есть способы с этим бороться, но для каждой конкретной программы и компилятора они свои.
теперь я спокоен, спасибки
Нет, это не норма. Прочитай стандарт, научись в -fno-strict-aliasing. Применяй байтоеблю правильно.
надо
и у меня вопрос #include <stdio.h>
#include <math.h>
main ()
{
int a;
float b;
scanf("%d\n",a);
b=a(3.156 pow(10,7));
printf("%f\n",b);
}
почему число нужно вводить дважды если scanf 1
Нужна небольшая помощь с задачкой не бесплатно офк
Перевод строки убери из строчки форматирования.
слишком мало?
да не, мб ты не так понял, там просто функцию написать надо и использовать её на чем то использовать я сам смогу
В общем есть 100 билетов, в каждом одно задание, ~70 я прорешал, а некоторые прям вообще хз
бывают такие - https://pastebin.com/zFKSFPVb
А бывает и такое:
В текстовом файле дана последовательность чисел. Написать рекурсивную подпрограмму, которая находит максимальный элемент непустого однонаправленного списка. Используя эту подпрограмму, удалить из заданной последовательности все элементы с максимальным значением.
Как с помощью рекурсии это сделать не понимаю
> Как с помощью рекурсии это сделать не понимаю
#define max(x, y) ((x) > (y) ? (x) : (y))
int find_max(list ptr elem) {
if (!elem) return INT_MIN;
int foo = elem->value;
int bar = find_max(elem->next);
return max(foo, bar);
}
Ну или на хвостовую перепиши, чтобы было return find_max(elem->next, current_maximum);
Просто типо из этих двух я уверен, что мне выпадет вторая, поэтому и написал сюда тип подстраховаться
1)В текстовом файле дана последовательность чисел. Написать подпрограмму, которая в однонаправленном списке из каждой группы подряд идущих равных элементов оставляет только один. Используя эту подпрограмму, преобразовать заданную последовательность.
2)В текстовом файле дана последовательность чисел. Написать подпрограмму, которая проверяет, упорядочена ли последовательность действительных чисел, хранящаяся в двунаправленном списке. Используя эту подпрограмму преобразовать заданную последовательность следующим образом, если она упорядочена, то, не нарушая упорядоченности, вставить в нее элемент со значением p, иначе удалить элемент с номером k.
сейчас попробую, спасибо
1) Втыкаешь внутренний цикл, крутящийся, пока следующий элемент есть и равен стартовому.
> Используя эту подпрограмму
Беги оттуда. У тебя препод - любитель втыкать не относящиеся друг к другу действия в одну функцию[s/] подпрограмму.
2) Крутишь цикл, пока next не NULL, проверяешь, что значение next больше значения текущего элемента. Попутно считаешь порядковые номера, запоминаешь указатели элемент с индексом k и элемент со значением p. Когда выйдешь из цикла, в зависимости от next !=/== NULL, принимаешь решение, какое действие с каким из указателей сотворить. И сотворяешь.
Не, ну первую то я офк легко решил.
>Беги оттуда. У тебя препод - любитель втыкать не относящиеся друг к другу действия в одну функцию[s/] подпрограмму.
Да у меня вообще пиздец, у меня препод дает нам постоянно операторы с крестов new delete etc, а наш курс называется просто "Программирование на языке Си"
И вообще все преподавание это написание синтаксиса какой нибудь функции на доске и выдача лаб. Мб поэтому я так туплю.
>>1012051
>(list ptr elem)
Немного не понимаю, что это?
Быть может (struct list *elem)?
Тайна сия велика есть. Но можно возвращать не max, а указатель на максимальный элемент. Соответственно по возврату из функции в вызывающей функции этот элемент грохать как-нибудь. Но опять же однонаправленный список... хуй знает.
Удалить все элементы из списка (кольцевого двусвязного) с черными номерами, считая, что нумерация начинается с 1 отправлено первого элемента?
> Сап, возможно ли с помощью этой подпрограммы - https://pastebin.com/g8ziudsN
> Удалить все элементы из списка (кольцевого двусвязного) с черными номерами, считая, что нумерация начинается с 1 отправлено первого элемента?
Ты точно по-русски говоришь?
Ананасы, как вы в POSIX запускаете процесс, который должен запуститься, сделать своё дело и завершиться, но при независимых довольно нестандартных обстоятельствах может и повиснуть (либо очень долго выполняться)?
Я вижу два решения:
1. fork и waitpid с таймаутом (не совсем надежно, в худшем случае может остаться зомби), но зато можно получить код завершения процесса при успешном выполнении (что в моем случае было бы полезно)
2. вызвать fork дважды, делать exec с последнего child, первый child убить. Надежно, но сложно получить код завершения (и тут я думаю — а нужен ли он мне...).
А я ананас.
Не вижу проблемы.
>в худшем случае может остаться зомби
С чего бы это? Ты SIGCHILD не обрабатываешь?
https://pastebin.com/UKg6ydbH
Немного поясню - неверно считает хэши от всяких бинарников, от exe до mp3 и прочее.
signed char?
Глянул объявление - unsigned char. Другой вопрос, почему через этот самый unsigned char оно не работало, а через byte - вполне.
Магия
Врешь ведь. У тебя там винда и отсутствие флага "b" в fopen. Поэтому в бинарниках >>1012416 проблемы с \r\n. А из-за unsigned char проблем быть не может (с правильно написанным кодом, который знает про integer promotions).
Хотя нет, я был не прав, rb есть, но unsigned byte явно vs. typedef все равно влиять не должны. Зато есть другие проблемы типа f.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY (надо через & тестить, могут быть другие атрибуты), странного чтения посимвольно, хотя fread может поблочно, еще более странной конструкции для вычисления размера (у тебя int 32-битный, чего ты вообще пытаешься добиться?), отсутствия проверки, открылся ли файл и отсутствия fclose в принципе (количество открытых файлов ограничено, см. FOPEN_MAX - однажды следующий не откроется, и ты будешь считать чексумму мусора в памяти). Ну и FindNextFile BOOL возвращает.
Для пикрил примера без goto пишется, что приходится вводить ещё одну переменную с дополнительными проверками.
Ну а вообще, какой из двух вариантов на пикрил будет быстрее? Насколько дорого обходится желание "прыгнуть" в определённый участок кода?
goto бесплатный (превращается в jmp). Переменную компилятор скорее всего оптимизирует в тот же jmp (но без гарантий). Код с пика можно переписать без goto и переменной: при совпадении нужные действия и возврат, а при выходе из цикла у нас ничего не нашлось.
Нет, присваивать не нужно, тогда уж лучше перемеменная. Я имел в виду
for (...) {
for (...) {
if (...) {
// found
...
return;
}
}
}
// not found.
return;
Спасибо. Энивей, это была лишь заготовка, и всякие проверки прикручены.
Спросил у бро-программиста (не российского), каким, на его взгляд, должен быть стартовый язык, потому что возврат к Python мне сейчас не кажется очень хорошей идеей, а на двачах в основном советуют JS. Бро процитировал мне Дийкстру про Basic, уточнил, что это более чем относится и к JS'у, поэтому, для общей подтяжки алгоритмики и более глубокого понимания происходящего, он советует стартануть с C, как когда-то делал он.
Собственно, вопрос. Как думаете, стоит ли действительно вкатываться с Pure C, или это не самая лучшая идея при наличии на другие языки огромного количества всяких человеко-ориентированных обучалок для энтри-левела?
(бро, впрочем, расценивает Java как неплохой энтри-язык, с поправкой на то, что именно С быстрее всего сломает мне старые шаблоны и заставит мыслить как программист, а не codemonkey)
Всякие речи про ломание шаблонов это хуйня полная, язык программирования это средство, учи что хочешь, что нужно будет на первой работе, что понравилось, пробуй разные языки, а потом если захочешь, то почитаешь про архитектуры и прочую лабуду, без которой 99% кодмакак живут и радуются жизни.
Начни с Си, хорошенько поебись с низкоуровневыми фичами и указателями, потом спокойно иди на питон и изучай всё остальное, включая ооп и алгоритмы. Ты слабо представляешь, какая беда у средних программистов с пониманием указателей.
После основ этих двух будешь готов к любому языку, а на Js ты будешь больше ебаться с несовершенствами Js, что тебе совсем не нужно, как новичку. Java тоже неплохо, но Питон меньше всего отвлекает от высокоуровневой сути.
Python - это такой современный Бейсик, с более широкими возможностями (ООП, ФП и т.д.). Он легок для вкатывания, но калечит мышление.
Начинать нужно с языка, который даст тебе представление об устройстве компьютера.
И это - только Си. Раньше еще был Паскаль, но он умер, а дедушка Вирт впал в маразм и несет какую-то ахинею (последним нормальным языком от него был Модула-2, наработки из которого вошли в Turbo Pascal и Delphi).
> Java тоже неплохо
Java и C# ни в коем случае не годятся для первого языка, ибо совмещают сложность C/C++ (статика и т.д.) с высокоуровневостью (тормоза, песочница и т.д.) JS/Python/Ruby/PHP/Perl.
Для многих прикладных задач эти языки удобны, но начинать нужно с других, лучше с Си.
Герберт Шилдт. Полный справочник по C
Зачем ты разговариваешь с зеркалом?
Придумай задачу, например калькулятор или интерпретатор brainfuck, и реализуй. Потом читай больше об этом и узнаешь о других способах того же самого действия.
А то я это пропустил, а сейчас думаю, что зря.
Читаю пикрил и...
> x & ~077
Почему 077? Не зависит от длины слова? Длины слова?
> Запись x & ~077 лучше, чем x & 0177700
>...
Короче, нужны совсем основы побитовых операций
Чот хуйня, первый раз вижу ~ в C
> Почему 077
Восьмеричная система, 077 = 63 = (1 << 6) - 1, т.е., ставим 6 младших битов в 1.
> Не зависит от длины слова? Длины слова?
sizeof(int). Не зависит потому, что слева от наших 6 единичек может быть сколько угодно нулевых бит, и ~ успешно их все инвертирует.
За булевой логикой в вики. Начни с двоичной системы и обратного дополнительного кода.
написал что G++.exe подозрителен ну я такой ну ладно исправлю думал ничего не будет и теперь cmd видит gcc но не видит команду g++ что делать?
idp generic
не дает переустановить
выдает это
В карантине, скорее всего, g++.
Через менеджер карантина антивируса восстанови g++, потом настрой антивирус так, чтобы он вообще не трогал папку с твоими поделиями и папку с mingw.
Я не люблю это писать, но вон из профессии. Если уж ты с антивирусом справиться не можешь, и не знаешь, как решить access denied в системе, зачем ты ползешь ее программировать? Начни с простого - разберись в ОС как юзер.
Нафиг оценивать скиллы в сишке по умению совладать с шиндой, если шинда вообще не показатель ни для кого?
Чтобы писать код для ОС, нужно представлять, как она работает. Если ты представляешь, как она работает, ты знаешь, отчего бывает access denied. Если нет - стоит выбрать какой-нибудь жаваскрипт, в котором взаимодействовать с ОС не нужно.
> Определите swap(t,x,y) в виде макроса, который
осуществляет обмен значениями указанного типа t между аргументами
х и у. (Примените блочную структуру.)
В интернете либо решения с использованием следующих глав, либо решено только для случая int.
https://pastebin.com/jrTjfqg4
Там вообще бредятина ужасная, скорее всего, но просто со слов K&R о макроподстановках я так и понял.
Кое-что исправил, ругается, когда встречает строку
> for (i=0; i<sizeof(x); TEMP=x, x=y, y=TEMP, i++); \
error: subscripted value is neither array nor pointer nor vector
for (i=0; i<sizeof(x); TEMP=x, x=y, y=TEMP, i++);\ ^
https://pastebin.com/KBkDme2T
От тебя ожидалось всего лишь что-то типа:
#define yoba_swap(type, foo, bar) do { \
type temp = foo; \
foo = bar; \
bar = temp; \
} while (0)
Естественно, для массивов не сработает, но для всего остального - вполне. Суть макросов в том, что все выполняется на этапе компиляции, поэтому твое решение со сравненим строк в рантайме ничем не оправдано. Нет, ну можно конечно с VLA из C99 замутить обмен чего угодно:
http://ideone.com/kmidbZ хотя это извращение, и код далек от оптимального.
>>1014531
Во-первых, у тебя условие неправильное. Ты пишешь: если t совпадает со строкой "int", и t совпадает со строкой "double" strcmp возвращает 0 при совпадении, не говоря уже о том, что t не может быть двумя разными строками одновременно, и размеры объектов равны а вот нифига, препроцессор тебе развернет SIZEX в sizeof(x), но аргумент туда уже не подставит, т.е., что бы ты не передал в swap, на выходе всегда будет sizeof(x), то...
Во-вторых, объекты, которые обмениваются значениями, могут не быть массивами, и в этом случае твой цикл слегка не в тему, что собственно у тебя и происходит.
> char s[]={'i','n','t'};
Значение знаешь?
Спасибо, довольно подробно.
> Значение знаешь?
Ну, если char s[]="int", то char s[]={'i','n','t','\0'}.
А зачем do {...}while(0) ?
Выглядит просто как причина открыть фигурные скобки, ибо по-любому выполнится один раз.
Но зачем?
do {} while (0) - это минимальный statement, после которого можно воткнуть ; без последствий:
#define YOBA(a, b, c) { что-то там }
if (expr)
YOBA(1, 2, 3);
else
YOBA(4, 5, 6);
После препроцессирования получаем:
if (expr)
{ что-то там };
else
{ что-то там };
И компилятор недоумевает, а откуда взялся else, ведь перед ; if с его точки зрения уже кончился. В свою очередь после while точка с запятой к месту, и ничего не ломает.
> Ну, если char s[]="int", то char s[]={'i','n','t','\0'}.
Отлично, но зачем?
> Отлично, но зачем?
Сейчас уже нет смысла об этом говорить, я совсем по-другому себе всё это представлял.
Ну и не проще ли просто не ставить ; при вызове макроподстановок? Так можно заодно и отличать их от вызовов функций
1) Макрос #define SMTH(x) ((x) + 3) и вызов printf("%d\n", SMTH(1) / 2). Если тут точку с запятой поставить в макросе, сломается вызов.
2) Часто макросами заменяют короткие функции, иногда даже в одном проекте одно имя может быть функцией или макросом, в зависимости от настроек проекта и платформы (тот же getchar() в стандартной либе очень часто макрос), т.е., чтобы узнать, ставить ли точку с запятой, тебе нужно понять, вызываешь ли ты функцию или макрос (сам вызов-то выглядит одинаково). Т.е., тебе нужно запоминать это для каждого имени или каждый раз ходить смотреть.
3) Читается хуже, пидорасит подсветку в IDE.
Поэтому проще всего оставить обычные подстановки для #ifdef и констант (типа #define M_PI 4.0), а все остальное делать function-like макросами, и не ставить в них финальную точку с запятой. Этот подход вызывает наименьшее количество путаницы.
Ну, тут такое дело. Хочу написать приложение. С локализацией. В чем бы мне хранить все эти китайские иероглифы вместе с арабской вязью? В char-то не влезают.
А как мне потом по этому массиву понять, сколько же там всего символов? Ну или, скажем, как получить n-ый символ?
Мало редактируешь текст - UTF-8, много редактируешь текст хранишь в UTF-8, а обрабатываешь в UTF-32. C wchar_t осторожнее.
Сколько символов в строке "ó"? А в строке "ó"? А третий с нуля символ в строке "xyz" какой?
Один. Два байта.
Мне там макака свинью подложила. В первом случае была o с акцентом, во втором символы o и акцент. В третьем все еще веселее, он даже у макаки работает.
Принципиальной разницы нет. Ты еще к символами прицепись и расскажи про глифы и кодовые позиции.
Почему запись (✻s++ = *t++) сдвигает указатель на 1, а не увеличивает на 1 то, на что он указывает?
Прошу прощения, нашёл ответ в faq, надо почаще туда смотреть, лол.
Дважды не угадал. Во-первых, NULL в сишечке - это ((void *) 0), а ты, наверное, имел в виду то, что в ASCII называется NUL, он же '\0'. Во-вторых, разговор был о юникоде, поэтому тебе стоило скопировать ту строчку куда-нибудь и разобрать по байтикам. Там несколько пробелов нулевой ширины перед буквами.
UTF-8 хорош для передачи и хранения. В винде нативный апи - UTF-16. С UTF-16 слегка проще/быстрее работать, меньше проблем с невалидными последовательностями, но все равно остаются суррогатные пары, о которых нужно помнить, ну и порядок байт еще (поэтому лучше UTF-16 оставить для обработки, а передавать UTF-8). А так как памяти сейчас дохуя, то некоторые используют сразу UTF-32, чтобы устранить даже минимальную еблю на этапе обработки, ну и 11 бит еще на всякие флаги остаются, тоже удобно иногда.
Лолшто? Ты разбиваешь текст на слова и хранишь каждое слово в своей кодировке? Или как?
Ты чё ёбнутый? Берёшь и работаешь с буквами в каком-нибудь кои8-р.
А почему не придумать какой-то способ переключения кодировок неявный? Там какой-то идентификатор и переключающий символ.
Потому что проблем гораздо больше, чем даже с UTF-8. Простейший пример: ты отрезал 3 первых символа строки, в том числе переключающий символ. В какой кодировке строка? Когда я был молодой и глупый я тоже такое изобретал. При попытке практического использования все проблемы-то и вылезли.
FILE fp;
int eof=0;
char scur;
int snum=0;
} file[MAXFILES];
Во всём массиве будет file.eof==0 ?И можно будет менять это значение?
В Си такого синтаксиса (= 0 в определении структуры) нет, можешь сделать struct { ... } file[MAXFILES] = { 0 }, и тогда во всем массиве будут нули (компилятор скорее всего memset воткнет явно или инлайном). И да, значение можно будет менять, конечно же.
А , т.е. он сам тип определит, а если {0, 0}, то он воткнёт 0 и snum, и eof.
А если {NULL ,0, NULL, 0}, то и указателям, да?
Нет. { 0 } - это по сути короткая запись для { [0] = { .fp = 0 } } (т.е., первому элементу массива, первому элементу структуры присвоить ноль), но частично структуры инициализировать нельзя, поэтому компилятор забьет все оставшиеся элементы массива и члены структур нулями тоже. { 1, 2 } - присвоит значения первым первым двум членам первого элемента массива, остальное забьет нулями.
> А если {NULL ,0, NULL, 0}, то и указателям, да?
Так ты не сделаешь, нет такой выборочной инициализации элементов массива или структуры, да еще и с пропусками. Можно явно:
{ [0] = { .eof = 0, .snum = 0 }, [1] = {.eof = 0, .snum = 0 }, итд }, но это бессмысленно, потому что компилятор все равно забьет все остальное нулями.
Хочешь инициализировать именно eof и snum, и ничего больше - делай явно:
for (...) { files[ i ].eof = 0; files[ i ].snum = 0; }
но выиграешь только на больших массивах. Если у тебя порядка пары килобайт, инициализация всего массива разом = { 0 } или мемсетом будет быстрее.
Вот в шапке много всяких книг, но в них только в них синтаксис языка объясняют. Как практиковаться, может есть список проектов с возрастающей сложностью. Вот хочу написать что нибудь, а что писать и как не знаю. Не могут изучать язык по книгам. Нужны реальные задачи. Где взять реальные задачи анончики?
Тоесть помогать каким-то проектам или пилить свои?
Прочитай книгу с синтаксисом. Не зная синтаксиса идти что-то реализовывать глупо.
> как практиковаться
Расскажи, зачем ты учишь язык? Какая область тебе интересна?
Даже уже комом в горле этот синтаксис. Мне интересно программирование начиная от процессора и заканчивая сетью. Изучал разные языки и понял, что мне мешает эта прослойка между ними ОС и процессором. Хочу понять что на низком уровне. Как транслируются программы, в частности те же языки программирования. Как работают компиляторы, как работает параллелизм на уровне ОС, на уровне процессора, на уровне компиляторов-интерпретаторов. Как реализуются сетевые протоколы.
Проблема в том, что без практики у меня не усваивается, а такие глубокие темы в основном описываются теоретически, либо вообще нет информации.
> заканчивая сетью
Ну вот и напиши DHT-клиент для Kademlia. Сложно, заебешься (придется узнать о TCP/IP, придется узнать про сокеты, придется парсер bencode написать, про структуры данных узнать какие-нибудь, архитектура, обработка ошибок, вот это все), хотя сам принцип прост.
В общем, похуй что будет твоим "главным" проектом, используй его просто как повод покопаться в различных темах - пиши по пути хелловорлды для изучаемых технологий, не читай просто так. Узнал про какую-то функцию - используй, использовал, поигрался - удолил, читаешь дальше.
> такие глубокие темы в основном описываются теоретически, либо вообще нет информации
Овердохуя информации, если можешь в английский. Вплоть до видеотуториалов на ютубе.
Алсо, пикрелейтед.
А я на 77-ом уровне.
Напиши интерпретатор брейнфака. Сместо стека (для циклов) я использую массив int и int с порядковым номером.
Спасибки. Эти челленджи с warosu.org? Нагуглил v2-v3 кроме v1.4 того что на твоей пикче.
https://pastebin.com/SL2hZhRD
должна в теории сравнивать некоторое кол-во файлов, если находит различие в определённой строке (в т.ч. если один из файлов уже кончился), то выводит сообщение с номером строки и выводит строки с этим номером.
Но если ей подсунуть два одинаковых файла, то функция fstobuf (очередная строка файла в буфер, возвращает указатель на строку в буфере) каким-то образом добавит 13-ый символ (возврат каретки, щито?!) в каждую строку, а функция strcmp, получив (в теории) одинаковые строки, выдаст единицу, хотя выглядит она (strcmp) довольно просто, должна возвращать ноль, если строки одинаковы.
Ужос.
Будет ли auto в данном коде работать как var? Функция вызываемая мной возвращает NTSTATUS, по идее я хочу чтоб _status после вызова стал типом NTSTATUS и мне не пришлось обьявлять для этого дополнительную переменную.
Вот код :
https://pastebin.com/vEqu6beF
Дошло.
Часто говорят, что выделение двумерного массива в С/С++ плохое, потому что в памяти всё лежит по столбцам, а не по строкам, а вот в фортране всё хорошо, там всё построчно и поэтому можно быстро бегать по двумерному массиву.
Я набросал этот код и запустил его в DevC++ с MinGW:
#include <iostream>
/ run this program using the console pauser or add your own getch, system("pause") or input loop /
#define MD 4
int main(int argc, char argv) {
int a[MD][MD];
for(int i = 0; i< MD; i++)
{
for (int j = 0; j < MD; j++)
{
a[j] = i100+j;
}
}
void b = a;
for(int i = 0;i<MDMD; i++)
{
std::cout << (b+=sizeof(int)) << " " << ((int*)b) << std::endl;
}
return 0;
}
На выходе у меня
0x28fe64 0
0x28fe68 1
0x28fe6c 2
0x28fe70 3
0x28fe74 100
0x28fe78 101
0x28fe7c 102
0x28fe80 103
0x28fe84 200
0x28fe88 201
0x28fe8c 202
0x28fe90 203
0x28fe94 300
0x28fe98 301
0x28fe9c 302
0x28fea0 303
--------------------------------
Process exited after 0.2274 seconds with return value 0
Press any key to continue . . .
Т.е. всё лежит именно построчно.
Что я делаю не так?
Часто говорят, что выделение двумерного массива в С/С++ плохое, потому что в памяти всё лежит по столбцам, а не по строкам, а вот в фортране всё хорошо, там всё построчно и поэтому можно быстро бегать по двумерному массиву.
Я набросал этот код и запустил его в DevC++ с MinGW:
#include <iostream>
/ run this program using the console pauser or add your own getch, system("pause") or input loop /
#define MD 4
int main(int argc, char argv) {
int a[MD][MD];
for(int i = 0; i< MD; i++)
{
for (int j = 0; j < MD; j++)
{
a[j] = i100+j;
}
}
void b = a;
for(int i = 0;i<MDMD; i++)
{
std::cout << (b+=sizeof(int)) << " " << ((int*)b) << std::endl;
}
return 0;
}
На выходе у меня
0x28fe64 0
0x28fe68 1
0x28fe6c 2
0x28fe70 3
0x28fe74 100
0x28fe78 101
0x28fe7c 102
0x28fe80 103
0x28fe84 200
0x28fe88 201
0x28fe8c 202
0x28fe90 203
0x28fe94 300
0x28fe98 301
0x28fe9c 302
0x28fea0 303
--------------------------------
Process exited after 0.2274 seconds with return value 0
Press any key to continue . . .
Т.е. всё лежит именно построчно.
Что я делаю не так?
Парсер двоща — шлюха, экранировал отступы
Ну,список странный тогда выходит. Ведь как сначала написать научный калькулятор не умея писать даже с обратной польской нотацией?
А вот телнет сервер мне был бы очень нужен.
большое спасибо за развёрнутый ответ
Если не вредит программе и остаётся читабельной код - вполне да. Но лучше заменять exit ретурном.
> разница какая
завтра потом выростайэт макака. ТЫ ЧО ПИРИМЕННУЮ VAR1 И VAR2 ВСЕ ПОЙМУТ ПРЕДНАЗНАЧЕНИЕ. ЗАСЕМ ОТСТУПЫ КОММЕНТАРИИ ЧИТАБЕЛЬНОСТЬ???ЮЮ НИНУНЖА
Пили файловый менеджер. Ему фичи допиливать можно будет бесконечно: FTP, вьювер картинок, архиватор, mounter, встроенный терминал, API для плагинов на каком-нибудь скриптовом языке, и т.д. и т.п.
Ну смотри, давай я тебе объясню.
С++ — говно сраное, этот язык давно должен был умереть и кануть в Лету.
С — лучший язык современности, он популярен, прост, быстр. Что ещё нужно от языка?
А ты осмысли своей тупой башкой, что тебе пишут в ошибке.
install gentoo
На начальном этапе в любом случае надо вводить в привычку писать хороший код.
Двумерных массивов в сишечке нет. Какой-нибудь array[n][m] - это по сути массив размером n, в котором каждый элемент - массив размером m. Соответственно, тебе нужно просто помнить, что "измерения" лежат последовательно, начиная с самого правого. array[y][x] будет лежать построчно, а вот array[x][y] - по столбцам.
>>1018608
От научного калькулятора в первую очередь требуются математические функции. Добавить приоритеты вычислений можно при последовательном вводе, RPN не нужна. Пример - виндовый калькулятор до десятки.
> В общем, насколько приемлемо и в каких случаях приемлемо библиотечной функции прерывать выполнение программы?
Только если библиотечная функция явно предназначена для прерывания выполнения программы. Иначе неприемлемо. Возвращай ошибки, даже если API станет менее красивым. Алсо, лично я не считаю нужным обрабатывать ошибки при выделении памяти в обычном, не серверном софте, поэтому у меня обертка над маллоком с exit(), но это единственное исключение.
>>1018711
> что за хуйня
Смотри сюда, собирай информацию: >>1010153 А телепаты в отпуске, лето же.
Хуй знает, стековый калькулятор запилить как нехуй, а распарсить строку с скобочками, которые меняют приоритеты операций - так и не осилил.
Ыыы, сколько я говна в блокнотик излил, пытаясь распарсить скобочки.
https://pastebin.com/Nehizuti
>С++ — говно сраное
Понадобятся классы - прибежишь и начнешь жрать это говно, еще спасибо скажешь, что тебя им накормили.
Наааахуй эти ваши классы. Если реально надо, то эта задача требует нормального выскоуровнего языка - жаба, питон, хуйтон или что там щас модно.
А если задача требует высокой производительности, которой не достичь джавой и питоном?
JNI, экстеншены для питона. На сишечке.
Разрабатывать программы на C с меньшей эффективностью. Поверь, говнокод васи пупкина на ц++ куда медленнее, чем грамотный код специалиста по java на java.
>говнокод васи пупкина на ц++ куда медленнее, чем грамотный код специалиста по java на java.
Но быстрее говнокода на Java. А грамотный код специалиста по C++ на C++ быстрее, чем грамотный код специалиста по java на java.
Java предназначен для грамотной разработки. Тем более, найти специалиста по java куда проще чем по c++, если они вообще есть.
Джава по скорости почти не уступает крестам, в некоторых случаях даже быстрее. Про скорость разработки и говорить нечего.
> Но быстрее говнокода на Java.
С нулевой обоссу. Наглый пиздец.
Говнокод Васи Пупкина на крестах будет течь памятью и просто медленно работать потому что Пупкин ебоклак. А говнокод Сюткина течь не будет и будет работать быстрее за счет того, что у Пупкина есть только собственный говнокод, а у Сюткина десятилетиями оптимизируемый JVM.
Только, блять, не надо сюда совать бенчмарки уровня "короч вот тут я запускаю числодробилку и измеряю время старта приложения и время остановки приложения".
В общем, подумой почему на крестах пишутся всякие игори и движки на них, плюс реально специализированное говно, а весь кровавый тырпрайз и хуйлоад на JVM-языках.
>десятилетиями оптимизируемый JVM
Там десятилетия говнокода и архитектурной астронавтики. Достаточно сравнить любую программу на Qt и Swing, чтобы убедиться, что свинг - тормозное overengineered говно, как и большинство кода на джаве.
>Джава по скорости почти не уступает крестам
Как она может по скороси не уступать, если у любой коллекции там оверхеды в 5 раз по памяти из-за жирных пойнтеров и в десятки раз по скорости из-за отсутсвия value-типов и убивающего кэш пойнтер-чейза.
> Только если библиотечная функция явно предназначена для прерывания выполнения программы.
Я так понимаю, под это подходит только один exit()?
Вася и Петя пилят сервер к месседжелу (мессенджеру).
На второй день, пока Петя в джаве пишет конференции, Вася на крестах велосипедирует парсер json, так как другие реализации слишком кривые. Саше вообще класть, на Ц всё давным давно написано и отлажено.
Возможно не один, но да.
>В общем, подумой почему на крестах пишутся всякие игори и движки на них, плюс реально специализированное говно, а весь кровавый тырпрайз и хуйлоад на JVM-языках.
ентерпрайз пишут на явке (и на шарпе) потому что там есть горячая загрузка кода - ты можешь подгрузить классы
а в крестах этого нет, так как нет стандартизированного abi, приходится поэтому пользоваться старыми сишными соглашениями и городить поверх них компонентные обертки типа com
>Двумерных массивов в сишечке нет. Какой-нибудь array[n][m] - это по сути массив размером n, в котором каждый элемент - массив размером m. Соответственно, тебе нужно просто помнить, что "измерения" лежат последовательно, начиная с самого правого. array[y][x] будет лежать построчно, а вот array[x][y] - по столбцам.
В примере у меня получилось, что array[y][x] лежит построчно в виде сплошного массива array[x*y]. При этом всё время слышу о каком-то сверхправильном расположении массивов в фортране, из-за чего он чуть быстрее.
Нет, пишут на джаве и шарпе потому что там нет байтоебства. В ынтерпрайзе важна надежность, в крестах память потечет, время разработки долгое.
Это всё демагогия. array[x][y] вполне себе двумерный массив.
Когда в дело вступают скобки, проще со стека перейти на дерево. Не прямо сразу вот на AST, но примерно как-то так — тоже строишь дерево операций и потом его обрабатываешь.
В джаве память тоже течёт, но поддержка за деньги и интеграция с другими продуктами орлакли решает.
Если нет классических «у нас джава потому, что манагер срубил откат с сейла оракла», «делаем высеры под ведро», «крабую на галере для тырпрайза» — то и жабы нет, проверено.
> Вася на крестах велосипедирует парсер json, так как другие реализации слишком кривые
Что за сферический JSON в вакууме? Реальные примеры есть?
> Там десятилетия говнокода и архитектурной астронавтики.
Доказательств у петушка, конечно, не будет.
> Достаточно сравнить любую программу на Qt и Swing
Проиграл с долбоеба. Свинг имеет такое же отношение к JVM, что и грязь в соседнем лесу к планете Земля. Что свинг, что javafx это действительно говно и любой разработчик на JVM-языках тебе это скажет.
> большинство кода на джаве
Ты не подумол почему. Подумой почему все хуйлоады и инструменты на jvm-языках (сейчас пукнешь, что JVM на крестах написан - никто не отрицает, что кресты ненужны).
> В общем, подумой почему на крестах пишутся всякие игори и движки на них, плюс реально специализированное говно, а весь кровавый тырпрайз и хуйлоад на JVM-языках.
Разбери это предложение по частям и сделай соответствующие выводы для себя.
>>1019070
В голос. Ты правда думаешь, что в продакшене подгружают на горячую код? Ты ведь не думаешь, что хуйлоад это один большой сервер, который нельзя останавливать? Ты ведь не такой дебил?
>>1019086
> В джаве память тоже течёт
Это уже мантра байтоеба какая-то. Доказательств, конечно, не будет.
>все хуйлоады и инструменты на jvm-языках
Я мимокрокодил, мне интересно, о чём конкретно идёт речь? Чего за "хуйлоады" и "инструменты"? Мавен, штоле?
Проиграл с ждауна.
Если массивы это указатели, то почему в си добавили указатели, если можно было просто массивы.
Вернее Ритчи мог тайно добавить в язык указатели, чтобы сделать массивы, а в стандарт не добавлять.
С помощью указателей можно сделать массив, потому что компилятор разворачивает массив в указатель. Тогда в языке можно было бы оставить что-нибудь одно: либо массивы, либо указатели.
Убрав массивы, мы бы ничего не потеряли, т.к их можно реализовать указателями.
Убрав указатели, мы могли бы заменить их массивами, похуй, что задачи разные, все равно массив развернется в указатель, даже если указателей нет в языке.
Если бы я не понял, что ты нубик, то просрался с тебя по полной.
Напиши интерпретатор brainfuck без массивов.
Что за хуйня - почему код в ассемблерной вставке работает, а в цикле while вываливается с исключением - нет прав на чтение (типа лох расчехляй VirtualProtect).
Ах да, inb4 используй (DWORD)GetModuleHandleA(NULL) - нет, мне нужно именно вручную находить image_base, не спрашивайте почему.
Не, у меня же там адрес, а переменная - не указатель. Значит нужно кастануть к указателю, а потом получить значение, находящееся по адресу. А адрес - DWORD.
Ну а значение - WORD.
А так циклиться будет, пока 16..31 биты нулевыми не окажутся по указателю, ведь сравниваешь с 0x00005A4D.
Ето C++, там при компиляции в x86 константы - int. Да и дело даже не в том, что там найтись не может результат, а в том, что при одинаковых командах, написанных по разному, в одном случае всё работает, а в другом - доступ запрещен.
тебе и объясняют, что код не одинаковый: в асме 16-битное сравнение, а в си 32-битное.
открыл бы асм- код на выходе конпелятора да посмотрел бы давно
Погоди, а какая разница? В асме все равно через оператор ptr берется значение, находящееся под адресом, хранящемся в переменной DWORD, а затем кастуется в word. В С - нет каста. Так или иначе, и там и там берется значение по адресу DWORD, и каст к WORD именно в этом моменте ни на что не влияет. Или я не прав?
каст к word обнуляет два старших байта
чтобы можно было удобно манипулировать с куском непрерывной памяти, выделенной на стеке или в глобальной памяти посредством индексного доступа
поэтому ритчи и сделал встроенный тип данных "массив"
полезно вообще массивы рассматривать как возможность выделить кусок памяти на стеке или в глобальной области
причем следует также знать что в си нет никаких способов работы с кучей, а malloc/free всего лишь интерфейсы к соответствующим системным вызовам
Это просто фича языка. Ничего не нужно было делать для поддержки создания указателя на указатель, а вот чтобы запретить - нужно было бы при написании компилятора это запрещать.
Ант.
Да? Ну извиняйте, я просто в раздел не захожу, сижу в полутора тредах.
Вопрос треду, на сколько живой С в современных реалиях , учу этот ЯП и дико доставляет , но сейчас появляется куча "модных" ЯП не вытеснят ли они С?
Это копия, сохраненная 20 июля 2017 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.