Это копия, сохраненная 22 января в 01:27.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
Пожалуйста, пользуйтесь https://ideone.com/ или https://pastebin.com/ для вставки кода, если он длиной больше нескольких строк или содержит или ∗.
⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹
Что читать:
⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹
- Brian Kernighan, Dennis Ritchie "The C Programming Language": http://www.cypress.com/file/56651/download
- Stephen Prata "C Primer Plus, 6th Edition" (2014): относительно свежая, знает про C89/C99/C11, описывает различия, объемная (около тысячи страниц), годная, с вопросами, упражнениями и ответами. Читать после K&R или до.
- Zed A. Shaw "Learn C the Hard Way" (2015): годное пособие для гуманитариев для гуманитариев!
- Немного примеров хорошего стиля: http://www.oualline.com/books.free/style/index.html
- ООП, например: http://www.cs.rit.edu/~ats/books/ooc.pdf
- Стандарт ISO/IEC 9899:1999 (он же C99): http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf (драфт)
- Стандарт ISO/IEC 9899:2011 (он же C11): http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf (драфт)
- man/Dash/zealdocs
⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹
Чем компилировать:
⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹
- Очевидный GCC.
- clang: оче годно, батя рекомендует.
- Intel C++ Compiler: оптимизации, тысячи их.
- Visual Studio 2017 Community Edition: внезапно этим стало можно пользоваться, особенно с тулсетом clang/C2. Поддержка C11 на уровне "есть все, что тебе понадобится в реальном проекте плюс кривая библиотека". Анализатор кода в комплекте.
- Pelles C (шиндоуз онли): поучиться, вкатиться в C11 (стандарт полностью реализован, имеются в том числе threads.h и прочие stdatomic.h), но количество багов в оптимизаторе и редкие апдейты напрочь отбивают желание собирать этим что-то сколько-нибудь серьезное.
- TCC: очень маленький компилятор с багами и поддержкой C99. С ключом -run умеет компилировать код в память и запускать его, что позволяет писать скрипты прямо на сишечке.
⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹
Что еще почитать:
⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹
http://c-faq.com/
FAQ из comp.lang.c. Древний, но все еще актуален.
⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹
Samuel P. Harbison, Guy L. Steele Jr. "C: A Reference Manual, 5th Edition" (2002)
Ебаный пересказ стандартов C89 и C99 (включая стандартную библиотеку). Для не осиливающих стандарт в оригинале. Читать в качестве подготовки к собеседованиям (есть задачник с ответами) и для ознакомления с масштабами пиздеца перед написанием своего парсера/компилера.
⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹
Peter Van Der Linden "Expert C Programming. Deep C Secrets" (1994)
"Си: грязные истории". Смехуечки, немного объяснений, чем обусловлены особенности языка, всем известные подводные камни кто там ругал косяки в JS? у нас в сишечке их гораздо больше, просто они лучше спрятаны, немного байтоебли и непонятно откуда взявшаяся глава про старинные плюсы. Читать в качестве сказки на ночь (на пару вечеров хватит).
⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹
Richard M. Reese "Understanding and Using C Pointers. Core Techniques for Memory Management" (2013) - почитать, вкатиться в указатели.
⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹
Ben Klemens "21st Century C: C Tips from the New School" (2012)
⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹
Paul Deitel, Harvey Deitel "C for Programmers with an Introduction to C11" (2013)
⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹
Stephen G. Kochan "Programming in C (3rd Edition или 4th Edition, если найдется)" (2014)
⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹
MISRA Ltd. "Guidelines for the Use of the C Language in Critical Systems" (2013)
Набор рекомендаций по написанию надежного кода на C (промышленный стандарт). Читать - однозначно, следовать - вдумчиво и без фанатизма. Также можно посмотреть https://www.securecoding.cert.org/confluence/display/c/SEI+CERT+C+Coding+Standard и http://web.archive.org/web/20190213011655/homepages.inf.ed.ac.uk/dts/pm/Papers/nasa-c-style.pdf
⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹
Еще более длинный список: http://www.iso-9899.info/wiki/Books#Learning_C
⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹
Онлайн-утилиты:
⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹
- https://godbolt.org/ - Compiler Explorer позволяет посмотреть выхлоп компиляторов для введенного куска кода (больше полусотни разных версий компиляторов).
- http://cdecl.org/ - С Gibberish ↔ English помогает читать сложные сишные декларации.
Прошлый: >>2770768 (OP)
⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹
pointers edition
Так если я библиотечку для себя делаю, как мне ее скомпилировать? Или в библиотеке тоже нужен main?
Нет, для библиотеки не нужен мэйн. Ты же мне ответил, что то, что ты кинул скриншотом это и есть вся твоя программа. А, для библиотек и других сторонних ф-ций тебе нужно разобраться с хэдерами. Начни отсюда: https://otus.ru/journal/programmirovanie-po-modulyam-v-si/
Уже нет!!! В этот раз текст читать гораздо легче - звёзды не ебут так глаза, как в прошлом (удалённом) треде. Зато теперь "поинтеров" хватит на всех и на все случаи (до 500-го пста).
>gcc src/array.c
Так либа не собереться.
Тебе надо .so объекттник собирать если хочешь именно статик либу компильнуть, с флагом -shared
Но можешь потрениться на классических эльфах и компильнуть .o
В любом случае ты не те команды вызываешь.
Делай gcc -c сырецнейм.c -o объектнейм.o
или gcc -c сырецнейм.c -o либанейм.so -shared вроде так, давно либи не компилил
Ах забыл добавить, чтобы из эльфов/либ собрать экзекьютабел делай в финале
gcc [объекты через пробел] [-lлибанейм если линкуется либа] -o приложениенейм
Итак допустим у нас есть описание функции foo и мы хотим хранить ее отдельно от основного проекта.
foo.c
int foo(void){
return 42;
}
main.c
int foo(void);
int printf( const char⚹, ...);
int main(void){
int result = foo();
printf("foo: %d\n",);
return 0;
}
По хорошему нам кроме двух сырцов нужен еще хидер куда мы положим прототип функции foo и printf, но можно обойтись и без хидера.
Итак сборка проекта.
Первым делом надо откомпилить два объектника:
gcc -c foo.c -o foo.o
gcc -c main.c -o main.o
Теперь надо эти объектные файлы слинковать вместе, по отдельности мы можем запустить только main.o но в нем есть референс на функцию принцип работы которой лежит в foo.o поэтому она не будет работать.
Линкуем
gcc main.o foo.o -o myapp.exe ну или не ехе тут уже без разницы
Теперь экзекьютабл не только имеет референс на foo но и знает как она работает.
Поздравляю вы красавчик.
Итак допустим у нас есть описание функции foo и мы хотим хранить ее отдельно от основного проекта.
foo.c
int foo(void){
return 42;
}
main.c
int foo(void);
int printf( const char⚹, ...);
int main(void){
int result = foo();
printf("foo: %d\n",);
return 0;
}
По хорошему нам кроме двух сырцов нужен еще хидер куда мы положим прототип функции foo и printf, но можно обойтись и без хидера.
Итак сборка проекта.
Первым делом надо откомпилить два объектника:
gcc -c foo.c -o foo.o
gcc -c main.c -o main.o
Теперь надо эти объектные файлы слинковать вместе, по отдельности мы можем запустить только main.o но в нем есть референс на функцию принцип работы которой лежит в foo.o поэтому она не будет работать.
Линкуем
gcc main.o foo.o -o myapp.exe ну или не ехе тут уже без разницы
Теперь экзекьютабл не только имеет референс на foo но и знает как она работает.
Поздравляю вы красавчик.
>printf("foo: %d\n",);
printf("foo: %d\n",result);
Команд по сборке бывает много, рекомендую освоить утилиту make для автоматизации сборки проектов. Make ультрапростой и в нем заложены удобные принципы, он будет рекомпилить только те участки проекта, которые подверглись изменениям.
1280x720, 0:19
Продолжаю тему микрогайдов на примере функции foo
Дополним наш проект маунальными тестами.
Удобно будет все же создать хидер с прототипами наших функций.
proto.h
int foo(void); // return 42
int printf(const char⚹ format, ...); // std format output
Добавим в проект еще один сырец с мейном
test.c
#include "proto.h"
int main(void){
int res = foo();
if(res-42) return 1;
return 0;
}
Не забудьте включить хидер proto.h в main.c заместо прототипов.
У нас уже есть скомпиленный foo.o и нам для сборки тестов достаточно скомпилить test.o и собрать приложуню.
gcc -c test.c -o test.o
gcc test.o foo.o -o testsuite.exe
Тесты ничего не печатают на экран, но возвращают код операционке и это можно использовать в системах сборки. Например в make
Makefile
myapp: tests main.o foo.o proto.h
gcc main.o foo.o -o myapp
main.o: main.c
gcc -c main.c -o main.o
foo.o: foo.c
gcc -c foo.c -o foo.o
test.o: test.c
gcc -c test.c -o test.o
tests: testsuite
./testsuite
testsuite: test.o foo.o proto.h
gcc test.o foo.o -o testsuite
Итак
>myapp: tests main.o foo.o proto.h
Обратите внимание, что основной (релизный) проект собирается только после того как успешно выполниться цель tests, тоесть если все тесты успешно выполнились мейк слинкует финальный экзешник. Если экзешник тестов вернет операционке не 0 а любой другой код ошибки - мейк не станет выполнять эту цель по сборке финального экзешника и прерветься с ошибкой.
Без автозамены функциями мейка выглядеть будет так. У мейка есть свои функции и переменные обработки текста, чтобы выкапывать имена файлов/каталогов и подставлять их куда нужно.
1280x720, 0:19
Продолжаю тему микрогайдов на примере функции foo
Дополним наш проект маунальными тестами.
Удобно будет все же создать хидер с прототипами наших функций.
proto.h
int foo(void); // return 42
int printf(const char⚹ format, ...); // std format output
Добавим в проект еще один сырец с мейном
test.c
#include "proto.h"
int main(void){
int res = foo();
if(res-42) return 1;
return 0;
}
Не забудьте включить хидер proto.h в main.c заместо прототипов.
У нас уже есть скомпиленный foo.o и нам для сборки тестов достаточно скомпилить test.o и собрать приложуню.
gcc -c test.c -o test.o
gcc test.o foo.o -o testsuite.exe
Тесты ничего не печатают на экран, но возвращают код операционке и это можно использовать в системах сборки. Например в make
Makefile
myapp: tests main.o foo.o proto.h
gcc main.o foo.o -o myapp
main.o: main.c
gcc -c main.c -o main.o
foo.o: foo.c
gcc -c foo.c -o foo.o
test.o: test.c
gcc -c test.c -o test.o
tests: testsuite
./testsuite
testsuite: test.o foo.o proto.h
gcc test.o foo.o -o testsuite
Итак
>myapp: tests main.o foo.o proto.h
Обратите внимание, что основной (релизный) проект собирается только после того как успешно выполниться цель tests, тоесть если все тесты успешно выполнились мейк слинкует финальный экзешник. Если экзешник тестов вернет операционке не 0 а любой другой код ошибки - мейк не станет выполнять эту цель по сборке финального экзешника и прерветься с ошибкой.
Без автозамены функциями мейка выглядеть будет так. У мейка есть свои функции и переменные обработки текста, чтобы выкапывать имена файлов/каталогов и подставлять их куда нужно.
Хотя вероятно зависимость от хидера proto.h стоит поставить на компил из сырцов, а не на сборку.
>А то сейчас, блять, хочется только материться!!!!!
Почему? Вроде все читабельно. Макаба херит табуляцию, что критично только для мейкфайла, но думаю синтаксис мейкфайлов погуглить - минутное дело. Там все сводится к комментарию типа:
цель : зависимости
таб действия
А всё из-за того, что стандартная библа написана закройте глаза: (если не хотите, чтобы ваш мир перевернулся) на асме...
А вы думали, блять, почему программа начинает прыгать по неизведанным областям памяти, когда совершается вызов библичной ф-ции из дебагера?
А всё из-за того, что Си это язык указателей!!!!! Просто представьте себе, что:
while (1) {
;
}
это просто набор указателей на каждый, как вас учили "оператор", но на самом деле на каждый символ, т.е.:
((w) + (i) +... + (e)) + ...;
Именно поэтому, когда вы в дебагере, типа gdb нажимаете "s" (step - команда, позволяющая попасть внутрь ф-ции), то попав на какую-нибудь библиотечную ф-цию, программа начинает прыгать столько раз, что, блять, кажется будто она прыгает по пространству всей Вселенной!!! Анон, ты не поверишь, где я был (я запрыгивал в анус твоей мамки), когда совершал прыжки в дебаге. Но, об окончании прыжков в программе я могу только мечтать, потому что я никогда не доходил до конца этого марафона (то ли анус твоей мамки бесконечный или спецом бесконечно-багованный в некоторых участках), но каждый раз из-за каких то багов мой дебаг падал. Удивительно то, что, когда запускаешь прогу без дебага, то всё проходит "оллрайт"!!! Но стоит, блять, задебажить это дерьмо, и начать прыгать по библичным ф-циям, как сразу же меня накрыает бесконечно-багованный анус твоей мамки, анон.
А потому мне кажется, что от нас что-то пытаются утаить. Возможно, то, что ЮНИКС, в своё время, Керниган и Ричи написали на асме, но, при этом, создав скрипто-адрессный язык, взяли денег, как за новую ОСь + новый язык программирований...
Получается, что Кернинган и Ричи попилили бюджет асашая!
>Вроде все читабельно.
Хз, анон, возможно, что ты настроил макабу таким образом, что, каждый пост, который содержит какой-либо код, то макаба определяет ЯП, а после этого выводит тебе его синтаксис.
Но у нас, у неманямирковых жителей макабы, твой код представляется полнейшим говном, которое плохо пахнет, и при этом плохо выглядит, чтобы не позволяет прочитать то, что там написано.
Кидаешь код - кидай пастбин!!!!!!!!!!!!!!!!!!!!!!!!11111!!!!!!!!!!!!! Блять, это же очевидно, как креститься в церкви!!!!
Господи что за zog тута? Все написано на си и даже библиотечные функции. Другое дело что в стдбибле куча оберток над обертками и твой принтф разворачивается множество раз на левел ниже пока не начнет вручную прыгать поинтерами по потоку и вызывать сискол и вот только в месте сискол write происходит чистый асм и то только потому что реализация write закомпилена в stdlibc которая по дефолту линкуется gcc
>>2835246
Тебе зачем подсветка синтаксиса в тривиальном примере функции всегда возвращающей число 42? Боишься ошибиться?
Но раз так просишь как нибудь залью статью на пастбин и линкану сюда.
Сам я юзаю вим + мэйк. Вим голый без плагинов, на мейке завязана не только сборка, но и например создание нового проекта. В голом виме кстати есть файлбраузер и поддерка мультиоконности для тех кто не знал.
Но г-ди, какой же это охуительный язык. Нравится то, что компактный и мало конструкций. Дает невероятное чувство свободы.
И учебник K&R - топ. Почти в каждой главе, помимо базы, дается какой-нибудь пример, а также пару заданий, где приходится поломать мозг.
Кодирую на линуксе (да, это wsl. 2 системой есть дебиан на всякий, но мне удобнее в винде, на линуксе рендер щрифтов ебанутый, какой только дистр я не пробовал).
Так что принимайте в семью :)
>>2838730
vscode + cmake
Добавлю, что решил, что идеальная связка для меня - это питон + С. Вызываются функции из С либы очень легко, я через ctypes это делал, там буквально пара строчек. Так что числодробилку можно спокойно на С писать и интегрировать в проект.
А залей сюда тривиальный пример вызова числодробильной функции foo из какой нибудь тривиальной libfoo.so при помощи пайтона. Как раз размышлял над тем какой мордошлепный язык взять, а то окошки на пьюр си писать геморно и профитак как такового все равно не будет. Ждем скриншотик :3
array это у тебя описание типа, а не сам объект. Чтобы вернуть указатель на объект типа array из функции, тебе надо создать объект сначала, только не в коем случае не на стеке, как ты обычные переменные объявляешь, иначе после выхода из функции все переменные выгрузятся, и ты получишь указатель с мусором, который нельзя использовать. В твоей ситуации, что можно сделать, убрать звёздочку после array и вернуть сам объект, а не его адрес. Т.е сначала объявляешь переменную array простую и просто ее возвращаешь без всяких &.
'''
>Создаёшь переменную типа array
array b:
>твоя инициализация переменной
>в конце возвращаешь ее копию
return b;
'''
> Чтобы вернуть указатель на объект типа array из функции, тебе надо создать объект сначала, только не в коем случае не на стеке, как ты обычные переменные объявляешь
Кривовато немного выразился. Если тебе надо возвращать именно адрес переменной, которая создаётся внутри этой же функции, то пользуйся маллоком обязательно, либо static переменными, если переменная у тебя может быть только одна на всю программу. Если надо обязательно на стеке ее создать, то можно выкрутиться так.
'''
>перед вызовом твоей функции
>Создаешь объект на стеке
array b;
> вызываешь функцию которая уже ничего не возвращает, но в качестве аргумента принимает указатель на твой объект
void (array *p_array, size_t foo, size_t bar)
> Здесь заполняешь структуру, как ты и делал
p_array->foo = ...
p_array->bar = ...
> Далее ничего не делаешь, структура b у тебя уже поменялась
'''
Был некогда отличный, идеальной softice, но масдайки убили его. Есть ollydbg, но он для 32 битных прог. Есть x96dbg, попытка оживить ollydbg, не знаю удачная ли, надо пробовать.
А, они все гуишные, забыл добавить. без gui думаю сложно найти будет, тем более под виндовс.
Спасибо.
Есть x64dbg. Опенсурс, под винду, но с гуем. Под винду без гуя ничего и нету скорее всего.
Ну в винапи достаточно богатый набор функций для консоли, тот же фар очень красиво и интерактивно выглядит, он полностью на этом апи построен, HIEW как пример ещё, hteditor - все они консольные, просто так сложилось что окна с кнопками более распространены в винде.
Как переписать, чтобы не было так всрато?
Перепиши на питон.
фу бля что за шрифт, уноси это нахуй отсюда.
На do..while замени, (перенеся инкремент в while в постфиксной форме), чтобы не повторять 3 строчки в конце. Естественно, дополнив: if(it == ' ' || it == '\0').
Кодстайл залупный
Вот допустим - у меня структура.
Давайте для простоты - бизнес кейс. Работник. Отдел.
Работник - может иметь у себя ссылку на отдел.
Отдел - может иметь в себе ссылку на массив работников.
Такая-то один-ко многим связь. Тут не суть.
Суть в другом. А как мне в рамках си это описать?
Мне компилятор на вот такую запись:
typedef struct emp {
departament* dep;
} emp;
struct departament{
emp emps[1024];
} departament;
говорит что нельзя.
Когда гуглю про декларацию текстур - там везде какая-то простая фигня. А вот такого - нету чет.
struct emp {
struct departament* dep;
};
struct departament{
struct emp emps[1024];
};
Так попробуй.
а неча по гайдам с ютюба язык учить
нахерачил типдефы сам не знаешь нахуя и зачем
книжку кернигана почитай лучше
А там про это есть?
Я просто читал ее еще во времена вуза и нифига не помню на самом деле.
Я си просто решил "повспоминать" в свободное от работы время. И чет вот такие моменты - меня заставляют ловить тупень. А как гуглить - даже не знаю.
int ((foo)(const void *))[3]
ето просто поинтер на функцию же а не муть
муть вота
int a = printf("huypizda"), for(int i =0; i<3; i++) puts("chemu ravna a?"), 10;
У нас первый курс был си. Ну. Т.е. да, там говорили, что это СиПлюсПлюс. Но какой это СиПлюсПлюс, если мы все делали через printf, и писали приложухи в Borland C++ через DosBox(потому что нужно было graphics.h а оно не хотело на семерке работать никак)?
На втором - с ООП уже да, были плюсы. Не хочу вспоминать как я с них горел. Вот типа тебе говорят: cout<<"Hello world"<<endl; И вот что это мать его за запись? Что она делает? ПОЧЕМУ ЭТО РАБОТАЕТ? Хуй, пиши давай лабы и не выебывайся.
на вот отпарси моего корявого коня в вакууме
char⚹ str = "Some string";
size_t len = strlen(str);
for(int i=0, int j=len; i<j; i++,j--)
if( str ^ str[j] ) {puts("Строка не палиндром"); break;}
>cout<<"Hello world"<<endl;
мне кстати только этой механикой работы с потоками плюсы и нарвились
остальная оопэшная хуйня кал ебучий, вот типа сишник да? но ты постоянно кодишь на каких то хайлевел абстракциях не задумываясь как там под капотом все это крутится, прям жаба какая то
еще в сишке прям не хватает неймспейсинга, чтобы свои велосипеды писать и не ебаться с отключением линковки стл
Мне в си много чего не хватает. Но я не буду про это ныть тут.
Хотя вру. Буду.
Не хватает удобной модульности.
Не хватает возможности в многопроходную компиляцию. Чтобы можно было как во всех современных языках:
void foo(){ bar(); }
void bar(){ // чет делать}
Не хватает человеческих строк.
Не хватает лямбд. Ну серьезно.
Не хватает отсутсвтвие в стандартной либе кучи полезного, типа JSON'а, работы с сетью и т.д.
Не хватает нормальных enum'ов, чтобы ты мог только те что должны использоваться использовать.
Не хватает асинхронности в стандарте.
Ладно. Я так много могу продолжать. Устал.
Просто мне си - нравится как-бы. Но вот эта вот философия с - напиши себе сам меня, как деда - убивает. Я уже написался разного.
>Не хватает удобной модульности.
это есть
>Не хватает возможности в многопроходную компиляцию.
хуйня какая то зумерская. сначал снимаем свитер потом срем
>Не хватает человеческих строк.
хуйня какая то зумерская
>Не хватает лямбд.
хуйня какая то зумерская
>JSON'а, работы с сетью
биндер в роде не в стл но то есть как и стл сокеты
>ты мог только те что должны использоваться использовать
сам то понял?
>Не хватает асинхронности в стандарте.
мультипроцессинг по дефолту асинхронный же или чо те не хватает
>Просто мне си - нравится как-бы.
но ты очень хочешь питон, да?
А какую ты хочешь написать? K&R по-моему дают достаточно практических примеров, ккак писать как раз такие утилиты. Охуенная книга.
Можешь порешать задачки на всяких leetcode, чтобы привыкнуть к языку.
Поддерживаю оратора там упражнений до жопы крутых я даже помню некоторые до сих пор, с непривычки от некоторых срака горела по нубству но потом нормально
Ну например свой генератор пакетов или альтернативу cat/grep.
В варианте пик1 всё работает.
В варианте пик2, т.е., когда мы не знаем точной длины массива структур и добавляем realloc(), то программа падает с ошибкой: malloc(): corrupted top size
И ещё непонятно, почему компилятор ругается пик3, когда я ему передаю указатель на массив структур пик4.
Аноны, я разобрался с этим
>В варианте пик2, т.е., когда мы не знаем точной длины массива структур и добавляем realloc(), то программа падает с ошибкой: malloc(): corrupted top size
надо, оказывается, в realloc() указывать ещё и размер структуры. Я думал, что, если ты даёшь realloc() уже саму динамическую переменную, то м.б. он уже должен сам понять, какого размера должна быть одна "ячейка" памяти, поэтому ему нужно просто указать общее кол-во этих "ячеек" памяти вторым аргументом.
Но я чёт всё также не понимаю, почему я не могу обращаться к полям структуры, указатель на которую я передаю в ф-цию, через "стрелочку".
>И ещё непонятно, почему компилятор ругается пик3, когда я ему передаю указатель на массив структур пик4.
ЧЯДНТ?
Получается, что
(⚹p).index == p->index, следовательно, p.index == (⚹(p+i)).index == (p+i)->index, а, эта конструкция p->index тогда ровна (⚹(⚹(p+i))).index.
Она ((⚹(⚹(p+i))).index), наверное, сработает в каком-нибудь массиве указателей на массив структур.
Бляяятьь!!! Макаба совсем охерела - теперь не только указатели жрёт, но ещё и квадратные скобки!!!!!
Ну как же так. Даже в /math/ латех завезли
Потому что вот так вот:
void (хget_data) (int n, const char хstr);
хранят указатели на вызовы, с обязательным перечислением аргументов, а указатель на данные просто: void хdata;
без скобичек
Так у меня массив структур и передаю я указатель на этот массив структур, и тут не так всё просто, как ты описываешь:
>если получил структуру по адресу - то стрелочка, если получил локал копию - то точка.
Мне тоже так казалось изначально, а по факту получается, что нельзя перебарщивать со скобками и звёздочками перед ними.
Спасибо, анонче! Я с этим уже разобрался, т.е. лучше стал пынямать что такое вообще точка и "стрелочка" в этих ваших структурах. Сейчас у меня другая проблема - я теперь прыгаю в ф-цию, которая подбирает мне нужный индекс через другую ф-цию, которая разделяет иксы на меньше нуля и больше нуля, и соответственно, подставляет массивы структур с положительными и "отрицательными" индексами. Всё робит хорошо, т.е. в итоге я получаю необходимый результат, и он выводится на экран, но беда в том, что когда я запуская свою прогу в валгринде, то он просто ахеревает от этой моей программы - сначала слегка подвисает, потом говорит, что моя програ достигла лимита в десять миллионов ошибок лол, после чего улетает в бесконечность, пукнув на последок о том, что точный расчёт общего кол-ва ошибок невозможен.
Я сам не сишник. Но сегодня от нехуй делать - полез на работе по репкам коллег из других отделов.
Собственно. Че я увидел и нифига не понял.
1. Почему-то все переменные в начале функции объявляли.
void foo(CONST_PTR_CONTEXT ctx){
int a,b,c;
float factor;
...
}
Зачем так делать?
2. У структур какое-то двоеточие было, типа:
struct {
int day:2;
int month:2;
int year:2
}
Че это вообще такое?
3. Ни одного malloc на весь здоровенный проект. Это как так? В вузе учили, что если там нужно какой-то связный список, то надо же выделить под него память. А там - ни одного не было, я специально grep'ом поискал.
4. Стиль объявления функций в виде:
int device_set_gpio_state
(
int number, // gpio number
int state // gpio state
)
Зачем так писать?
5. Серия глобальных переменных. В вузе учили, что так делать нехорошо.
6. Какая-то магия с тем, что никаких тредов, но судя по комментариям там как-то парралельно работа ведется. Это я вообще не понял. Там что-то было про какие-то прерывания чи еще что-то но в душе не представляю, что там происходит, типа вот вроде синхронный код, а написано, что между этим делом откуда-то могли прийти команды остановки и надо почистить сектора флешки.
В общем. Че курить чтобы понимать это все?
Я сам не сишник. Но сегодня от нехуй делать - полез на работе по репкам коллег из других отделов.
Собственно. Че я увидел и нифига не понял.
1. Почему-то все переменные в начале функции объявляли.
void foo(CONST_PTR_CONTEXT ctx){
int a,b,c;
float factor;
...
}
Зачем так делать?
2. У структур какое-то двоеточие было, типа:
struct {
int day:2;
int month:2;
int year:2
}
Че это вообще такое?
3. Ни одного malloc на весь здоровенный проект. Это как так? В вузе учили, что если там нужно какой-то связный список, то надо же выделить под него память. А там - ни одного не было, я специально grep'ом поискал.
4. Стиль объявления функций в виде:
int device_set_gpio_state
(
int number, // gpio number
int state // gpio state
)
Зачем так писать?
5. Серия глобальных переменных. В вузе учили, что так делать нехорошо.
6. Какая-то магия с тем, что никаких тредов, но судя по комментариям там как-то парралельно работа ведется. Это я вообще не понял. Там что-то было про какие-то прерывания чи еще что-то но в душе не представляю, что там происходит, типа вот вроде синхронный код, а написано, что между этим делом откуда-то могли прийти команды остановки и надо почистить сектора флешки.
В общем. Че курить чтобы понимать это все?
не знаю анонче, кодстайл такой хули ты нас спрашиваешь спроси данов которые это писали вы же там рядом
ну я про функции
старые стандарты все равно другую запись имеют, хз зачем они именно так пишут
Я боюсь спросить.
Во-первых, я не должен иметь доступ к этому коду, потому что он СЕКРЕТНЫЙ.
Во-вторых, боюсь выглядеть самозванцем, я то на java пишу. И тут к дедам с 20+ годами опыта пойду спрашивать, на меня посмотрят как на говно, начнут говорить, что вот, понабрали, они там в эти годы в космос запускали штуки, а я вот такое не знаю. В общем да.
Так интересно же. Особенно 6й момент. Как можно в однопоточной программе что-то сделать пока выполняется какая-то функция, не завершив ее.
Насрать в кучу
1) Стандарт ANSI/C89
2) Битовые поля, возможно там рядом где-то ещё union есть
3) Судя по коду, проект для контроллера, там нежелательно юзать динамическое выделение памяти из-за риска её фрагментации
4) Просто кодстайл такой
5) Глобальные переменные объявлять нормально, но осторожно. В эмбедед частая практика
6) Пушо ядро одно, тут либо вытесняющая многозадачность, либо никак
В твоем случае для начала учебник Праты по Си. Дальше можно Кармин Новиелло "Освоение stm32". Но вторая книжка только если хочется понимать что именно в том проекте происходит. Ну и я просто предположил, что там контроллер.
Асинхронно, в ОС тоже есть сигналы и прерывания, часто они вызываются в любой рандомный момент времени.
Ну. Да. Там контроллер. Ты угадал.
Спасибо за совет. Почитаю. А то каким-то неполноценным себя почувствовал от того что половниу времени - приходилось просто угадывать.
Вместо Праты можно Кернигана с Ричи. Он компактнее и лаконичнее.
Ты неправильно делаешь. Нельзя передавать локальные данные ссылкой на стек выше.
1. Либо объяви структуру на стеке выше и передай в функцию ссылкой для инициализации:
struct array arr;
init_array(&arr, size_t c, size_t n);
2. либо убирай ссылку и возвращай копию:
array new_array(size_t c, size_t n){
return (array){ ...};
}
еще лучше добавь статик инлайн и вынеси в хидер, либо вообще через
#define new_array(c, n) {...}
struct array = new_array(c, n);
Но сейчас так не модно, модно по плюсовому писать инлайн функции.
3. Выделить всю структуру в памяти (вместе с данными), и через указатели разделить структуру и данные, но это уже неараствый хак, да и все очищать придется.
>Нельзя передавать локальные данные ссылкой на стек выше
да ваще можно если принять ручное управление стеком через асмавставки, но это сейчас то же немодно и лютый хак
без асмахаков напрашивается только статик аррэй с пробросом данных на левел выше
в остальном сыглы
>struct array arr;
>init_array(&arr, size_t c, size_t n);
Ну я, в принципе, так и делаю. Объявляю массив в мэйне и в ф-ции передаю указатель на него. В ф-циях выделяю под него память и заполняю его данными, и всё через указатели.
>2. либо убирай ссылку и возвращай копию:
Это не подходит. Хочу научиться именно через указатели.
>3. Выделить всю структуру в памяти (вместе с данными), и через указатели разделить структуру и данные, но это уже неараствый хак, да и все очищать придется.
А тут я так понимаю, мне нужно знать заранее размер массива и, соответственно, данные, которые хранятся в его "ячейках"?
Такой хак будет работать только на интеле, а на другой архитектуре (типа e2k и стековых машинах) код будет не рабочий.
>>2842989
> А тут я так понимаю, мне нужно знать заранее размер массива и, соответственно, данные, которые хранятся в его "ячейках"?
Нет я имею в виду
void xd = malloc(sizeof(array) + capacity x s);
Как разделить это сходу не напишу, но если нет необходимости хранить структуру в памяти то не надо так делать, тем более я не уверен можно ли это очищать кусочками или надо сохранить где то указатель d
А хотя нет, на e2k будет работать, там для манипуляции со стеком есть команды getsp и setsp (stack pointer) и в регистр через который возвращается значение из функции вполне наверное можно затолкать указатель из стека ниже.
значение из стека ниже можно затолкать и обычным модификатором static
нахуй так изъебываться то
>Ну я, в принципе, так и делаю. Объявляю массив в мэйне и в ф-ции передаю указатель на него. В ф-циях выделяю под него память и заполняю его данными, и всё через указатели.
так разве ты не выделяешь память под массив в мейне? получается два раза выделаешь
прокинь поинтер и ковыряй память уровнем ниже через поинтер
потренируйся на "кошках", нахуй ты сразу в какую то структурную кашу полез если еще не шаришь как чо делается то?
Всмысле через
static inline arrayx new_array(...){ return &{...} }
? Ну это то может просто компилятор вызов убирает и получается ссылка на локальные данные. А так оно вроде вместо поинтера возвращает 0.
И при компиляции матерное сообщение выдает.
нафига чот возвращать?
типа в мейне
static array[];
foo(array);
и ковыряешь внутри foo проброшенный наверх массив
в чем я не прав?
Так не работает.
Ты передаешь в функцию нулевой указатель, как ты по нему что то запишешь?
Надо все равно передавать ссылку на указатель foo(&arr) что бы по этой ссылке внутри функции тебе записали указатель в нужное место.
Вот поэтому все это путает и не надо злоупотреблять указателями и их передачей туда сюда неявными методами.
Тем более что указатель объявлен как array[]
А foo может принимать
void foo(void*ptr);
И записывать в указатель что угодно и компилятор это сожрет.
>⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹⚹
У жопаскриптеров шапка лучше выглядит. Как Си скатилися в такое говно?
>так разве ты не выделяешь память под массив в мейне? получается два раза выделаешь
Да, тот вариант проги, который я закинул в тред, выделяет в мейне. Сейчас же я переписал прогу, и там всё в ф-циях происходит.
576x1024, 0:16
иноагент из узбекистана по кличке Абу подрывает имидж кодерской имиджборды
На какой элемент массива, шизик? У тебя поинтер не инициализирован и никуда не указывает.
И на стеке ничего не выделяет так как ты не написал сколько выделить.
Ну и выглядеть это будет максимально всрато:
struct array arr[1];
foo(arr);
Самый богоугодный вариант это:
typedef struct array arr_t;
static inline arr_t new_array(int size, int capacity) {
arr_t out = {
.size = size,
.index = 0,
.capacity = capacity,
.data = malloc(size × capacity)
};
return out;
}
static inline void del_array(arr_t ×in) {
in->size = 0,
in->index = 0,
in->capacity = 0,
free(in->data), in->data= NULL;
};
int main() {
arr_t myArray = new_array(3, sizeof(arr_t));
// •••
del_array(&myArray);
return 0;
}
На какой элемент массива, шизик? У тебя поинтер не инициализирован и никуда не указывает.
И на стеке ничего не выделяет так как ты не написал сколько выделить.
Ну и выглядеть это будет максимально всрато:
struct array arr[1];
foo(arr);
Самый богоугодный вариант это:
typedef struct array arr_t;
static inline arr_t new_array(int size, int capacity) {
arr_t out = {
.size = size,
.index = 0,
.capacity = capacity,
.data = malloc(size × capacity)
};
return out;
}
static inline void del_array(arr_t ×in) {
in->size = 0,
in->index = 0,
in->capacity = 0,
free(in->data), in->data= NULL;
};
int main() {
arr_t myArray = new_array(3, sizeof(arr_t));
// •••
del_array(&myArray);
return 0;
}
чот ты тут изъебываешься ради нихуя, как не прокидывал наверх так и не прокидываешь
крч, хуеплет, нахуй иди ок да?
научишься на стек прокидывать аррэй - пиши
>linear11
ну судя по этой инфе тут два байта каких то флагов
запиши флаги в каждый бит вручную
Что значит конвертировать?
#define MASK_PMBUS_M 0x07FF
#define MASK_PMBUS_N 0xF800
#define get_linear11_hi(i) ((i & MASK_PBUS_N) >> 11
#define get_linear11_lo(i) ((i & MASK_PBUS_M)
#define set_linear11(hi, lo) (\
((unsigned short)hi << 11) | \
((unsigned short)lo & MASK_PBUS_M))
Как то так.
Но вообще когда работаешь с битами используй тип uint лучше.
Как установить биты я знаю, но сначала надо преобразовать число в показатель и мантиссу, основная проблема в этом.
typedef unsigned short u16;
typedef unsigned char u8;
typedef struct
{
u16 base : 11;
u8 mantissa : 5;
} linear11_t;
void float_to_linear11(float in, linear11_val_t* l11)
{
const s16 Ymax = 1023;
s8 sNval = 0;
s16 sBase;
sBase = (s16)in;
if(sBase > Ymax)
{
while(sBase > Ymax)
{
sBase = sBase >> 1;
sNval++;
}
}
l11->linear.mantissa = sNval;
l11->linear.base = sBase;
}
Вот, как-то так пока сделал, теперь бы ещё придумать, что делать с дробными числами.
typedef unsigned short u16;
typedef unsigned char u8;
typedef struct
{
u16 base : 11;
u8 mantissa : 5;
} linear11_t;
void float_to_linear11(float in, linear11_val_t* l11)
{
const s16 Ymax = 1023;
s8 sNval = 0;
s16 sBase;
sBase = (s16)in;
if(sBase > Ymax)
{
while(sBase > Ymax)
{
sBase = sBase >> 1;
sNval++;
}
}
l11->linear.mantissa = sNval;
l11->linear.base = sBase;
}
Вот, как-то так пока сделал, теперь бы ещё придумать, что делать с дробными числами.
Так а что значит преобразовать int?
Тебе надо целое число в вещественное преобразовать и взять мантиссу или что?
Хвалю трехтомник Столярова.
Критикую трехтомник Столярова.
Ещё не читал трёхтомник Столярова.
Чел, он хорош, но два единственных и огромных минуса в том, что многие проги даны просто как отдельные ф-ции, плюс ко всему у него совсем нет упражнений (то что иногда встречается то, что это для раздумий читателя, это нещитово). Короче, эту книгу надо совмещать с чем-то ещё. Если ты совсем нуб, то не советую.
>У всех регионаж Росиии йододеицит. Не удително что ты такой.
Как там борьба за адресацию каждой защёлки? Продвигается? Вы (свора дегенеративных петуччил - Защелкане) побеждаете?
Я сгорел с того, что он огромное время уделяет паскалю, а потом дропает его, говоря "все хуйня давай по новой", и даёт С. Нахуя паскаль-то?
Идея в том, что таким образом ты вкатывашься в основы кодинга. Если у тебя уже есть опыт и ты чётко знаешь что такое указатели, рекурсия, ф-ции и т.д., то этот том можешь смело пропустить. Второй том лучше начать с Ван Гуйа, совмещая его с тем, что написано у Столярова про асм.
Прочитал все 3 тома. Только часть с паскалем скипнул.
В целом, разделы про Си и асм очень хорошие, раздел про устройство UNIX тоже неплохой. А вот с API линукса уже надо быть осторожнее, особенно про параллелизм лучше у кого-то другого почитать, типа Керриска или Лава. Столяров даже судя по тексту книги не очень разбирается (и не хочет разбираться) в теме потоков.
Ну и С++ точно не стоит учить у Столярова кмк. У него хороший подход, что он пытается дать только базовую часть языка, но при этом он жестко отсекает всю STL, что мне кажется неправильным. Да, STL не является частью языка, но при обучении языку все-таки необходимо хотя бы немного времени уделить ему, чтобы после прочтения хотя бы минимальная база была.
https://www.labirint.ru/reviews/goods/215409/
Вообще, для вката в Си советую эту книгу, плюс, если ту же тему прочитывать у Столярова, естественно не забывая решать задачки, то, в принципе, Си можно освоить на достаточно хорошем уровне.
Тоже Ван Гуйа на английском купил. Кратко пробежался (выборочно) по части асм в первом томе и показалось, что тема не полностью раскрыта. Возможно в других томах она раскрывается подробнее, но все равно решил купить отдельный учебник.
Не совсем по асм, но крайне зашел пик 1.
Кто-нибудь в пик 2 играет?)
>что тема не полностью раскрыта
Так это для начинающих книга, но она самое то, чтобы вкатиться в асм. Дальше уже можно обмазываться Крисом Касперски.
На входе у меня float или int, на выходе linear11 - 16 битное с плавающей точкой, если упрощённо. 5-битная знаковая мантисса и база 11-битная база, тоже со знаком. В общем странный формат, я с ним не сталкивался раньше. Пока сделал грязный хак, который работает только с целыми положительными, но вообще хочу найти что-то нормальное.
Находил один алгоритм на стэковерфлоу, но он ещё хуже работал, до 1023 только работал.
Читал в то время не только Столярова, но с периодическими перерывами прочитал примерно за 4 месяца.
Ну и читал я его после Праты и небольшого опыта в Си, поэтому при прочтении уже была в голове какая-то база.
А где можно посмотреть? У него свой гит есть?
Ну да, проблема столярика в том, что он по сути всю жизнь только преподавал и у него нет норм коммерческого опыта. Отсюда и его ебанутые заскоки в некоторых областях.
>А где можно посмотреть?
https://github.com/a-croco-stolyarov/thalassa
http://thalassa.croco.net/
>поэтому при прочтении уже была в голове какая-то база.
Вот это, кстати, роляет, когда читаешь его книги, при этом черпаешь интересные нюансы, без слома мозга, если пытаешься осилить его книги, читая без подготовки.
> проблема столярика в том, что он по сути всю жизнь только преподавал и у него нет норм коммерческого опыта. Отсюда и его ебанутые заскоки в некоторых областях
> @
> Слышь, двач, посоветуй, что почитать про Си. Нет, мне не нужно писать программы, не нужен реальный опыт, мне надо книжек почитать
> @
Ебало)))
Уже передергивания пошли, для изучения языка с нуля он нормально подходит.
И чего тебя так разорвало?
не читал, но критикую
У языка огромный потенциал, кмк.
патенцивал стать очередной жабахуетой с бесконечным набором блекбоксов и роадмапами освоения zig.hail.core в 7 лет и ЕЕ спецификаций еще длинною в 15.
последователь судьбы руби он рейлс кмк
хайп пройдет и все жидко пукнут как всегда это бывает
>патенцивал
>не хайп
ладно ты утомил, пойду своими делами займусь, не хватало еще срачь раздувать в копилку форса очередного говна
Я вообще мимокрок, лол) Просто забавно видеть слова "зиг" и "хайп" вместе.
Хайпится как раз раст сейчас.
да и он то же
Раст мне не нравится, слишком анальные правила борров чекера, а вот зиг очень даже. По сути тот же самый С, но с плюшками.
Олимпиаднику всё равно какой язык, для него язык как шлюхе наряд, любой модный нравится.
А вот если ты реальный программист пишущий реальные программы, то расты с зигами и прочей шушерой будет вызывать только отвращение, потому что интеграция с реальными апи ос отсутствует, а программа это в первую очередь апи ос и дальнейшие надстройки в виде библиотек, иначе ничего не напишешь кроме олимпиадного хеллоуворлда в вакууме.
Хуй знает что ты высрал. Разве не является пик1 интеграцией с апи ОС? Разве не является компилятор зига, компилящий сам себя, реальной программой, способной при этом компилировать крос-платформенно с линукса на винду (пик2) и выдавать мне няшный 22 КБайтный файл?
>Разве не является пик1
Является, хеллоуворлдом, олимпиадным говном без задач. Как раз про это и сказал же.
>>2847574
Чел, и раст и зиг это хорошие системные языки, если твой проект начинается с нуля, и, если этот твой проект какой-нибудь стартап (все высокопроизводительные блокчейны пишутся на расте), то дрочи раст/зиг. Но это маленький процент от всего айти мира, поэтому чаще всего высокопроизводительные штуки пишутся на Си или плюсах, т.к., чаще всего эти высокопроизводительные штуки есть продолжение либо производная от того, что уже хорошо себя зарекомендовало, и используется значительное время. Поэтому, если ты стартапер, то изучай раст/зиг, если ты просто хочешь стабильную работу, то изучай Си и плюсы.
Чому такие простые вещи в этом треде приходится объяснять каждый месяц?
При чем тут это? Чел назвал зиг шушерой, потому что отсутствует интеграция с системным апи, но по факту он может вызвать и слинковаться с любой С-совместимой либой, а также компилить С-совместимые либы. Я сгорел от того, что он высрал что-то, обосравшись с подливой.
>слинковаться с любой С-совместимой либой, а также компилить С-совместимые либы
Ну и кому это надо, какому-нибудь особому прошивщику микроконтрроллеров? Но там нет ос и нет апи.
На ос без крестов как минимум делать нечего, потому что без объектов ты напишешь только хелолоруворд, олимпиадное говно без задач.
Да, с долбоебов, которые утверждают, что без объектов нельзя написать ничего, кроме олимпиадных задач, лол. Ну по его логике С тоже олимпиадный язык получается, так как в нем нет объектов.
Чтобы не быть лицемером, пусть выкидывает тогда свои гаджеты и пека, так как ядра в них написаны на С, в котором нет объектов АХАХАХ БЛЯТЬ КАКАЯ ЖЕ ЭТО ХУЙНЯ. А на ассемблере кстати тоже нет объектов. Как же тогда была написана первая ОС? Непонятно. Мы пользуемся олимпиадным софтом, господа.
А почему кстати он так не любит олимпиадников? Мозгов не хватает на алгоритмы, видать.
Freertos и другие чибиосы на микроконтроллерах тебе шутка чтоли? И апи там есть и драйверы и фрэймворки. Да и под винду вполне себе пишу клиенты на си-labwindows, с потоками, очередями и вот этим всем.
Короче этот не шарит, впрочем все уже и так это поняли.
Олимпиадник, спок.
кто? крестовик? вам обоим по пикрилу
Двачую, охуенный язык. Мало того, его компилер еще и является компилером с/с++. Ну а комптайм вкусный еще и тем, что и сам код, и комптайм, и билдскрипты на одном языке, а не на портянке с макросами/шаблонами и мейкфайлами написанными инопланетянами.
Кто от него может бомбить итт? Только пердежи которые отстаивают UB через UB да только винапи знают, застряли в развитии в 90х.
Пишу типа JIT для своего скриптового языка. Сгенерить нативный код в памяти из скрипта, потом запустить на выполнение.
Почему в функции x64_call_show_hello_world при вызове CALL RAX (код 0xFF 0xD0) программа наебывается и падает? В 32-разрядной версии команда CALL EAX отрабатывает успешно, а на 64 битах не хочет.
Очевидно, в отладчике поставить брейкпоинт перед вызовом сгенерированного кода, проверить, что он правилен, затем пошагово выполнять инструкции, чтобы записать, в какой момент выдаётся ошибка, и какова она. Потом проверить, какие ещё методы защиты от эксплоитов есть в твоей системе, как должны оформляться вызовы функций и возвращение из них на стеке, если программа на самом деле завершается при попытке вернуться.
Код проверял пошагово, генерится все правильно (байты в смысле), регистр RAX содержит адрес функции, падает в указанном месте (когда доходит до байтов FF D0). Функция show_hello_world не имеет аргументов, поэтому никакие конвенции вызовов типа PASCAL/CDECL/STDCALL не нужны (и вообще в 64-битном коде есть единственное соглашение с регистрами). Думал, может проблема в WinAPI (там вызывается MessageBox), но если внутри show_hello_world оставить единственный оператор return 123, то все равно падает. На этой же системе (Windows 7) эта же программа в 32-разрядном режиме работает без ошибок - помещаю в EAX адрес функции show_hello_world и вызываю ее с помощью CALL EAX. А на 64 битах такой же алгоритм (адрес функции в RAX и вызов CALL RAX) приводит к краху. Про эксплоиты не понимаю ничего.
> ну в винде под консоль чота делать непрофитно, там система построения процессов завязана на принцип - все процессы это окно, тоесть надо изъебываться чтобы отрисовывать вывод в консоль
Чепуха какая-то. Приложение, у которого в заголовке стоит WINDOWS_GUI, может спокойно заниматься своими делами и не создавать никаких окон. Наоборот, приложение с типом WINDOWS_CUI получит окно консоли (или будет привязано к родительскому) вне зависимости от того, будет ли оно вообще с ней что-то делать.
Проблемы с консолью связаны с тем, что она изначально была построена вокруг костыльной метафоры буфера, так или иначе отображавшего видеопамять текстового режима программ под DOS, каковая память из-под них выдёргивалась в нужные моменты, и для совместимости с которыми всё это налепили, а потом бросили, поскольку получили себе весь рынок. Два десятка лет оно тухло. Отсюда и кодировка DOS, и невозможность нормальной поддержки UTF-8, и невозможность нормальной работы с потоками ввода-вывода, и всевозможные решения по обходу консоли под Windows в кроссплатформенных средах. Только недавно им пришлось ради удержания разработчиков на винде делать с нуля Windows Terminal и новое API (поскольку старое починить невозможно).
Ну так с чем падает-то? Всю интеловскую документацию по архитектуре посмотрел, нигде не нашёл описанного тобой кода ошибки "NAJEBNULAS_I_UPALA". В системном журнале можешь поглядеть, почему процесс внезапно завершился.
Про эксплоиты речь зашла потому, что надо знать, какие ещё способы защиты могут мешать на системе x64 прыгать на произвольный адрес между произвольными страницами памяти.
Машинные коды твои я пока даже не разбирал.
> Только недавно им пришлось ради удержания разработчиков на винде делать с нуля Windows Terminal и новое API
Так вот зачем они решили сделать консольку с закосом под линух
>делать с нуля Windows Terminal и новое API
Тоесть в 11 шинде ТРИ блядских терминала?
Нет, там два вида консоли, старая и новая, и два командных интерпретатора, товарищ Комманд Ком и Помершелл. Плюс сбоку линуксовые в своей подсистеме.
Классная шутка.
Windows Terminal это ничто, просто оболочка для терминалов, в одном окошке со вкладками.
А вот тот же PowerShell напердоленный OhMySh в легкую дает на ротан zsh от которого взяли идею. Пердосрали слили даже в конкуренции консолей, кек.
Пути уже прописал вротдаватель?
И что тут такого ужасного?
Обычно под "не использовать goto" подразумевается реализация алгоритмов таким образом, что бы этот уродливый инструмент не требовался. Например использование функций и конструкции switch.
Мало кто знает, но в javascript тоже есть goto (По крайней мере был в стандарте ES5). И слава богу как то без него обходились, потому что функциональность языка позволяла реализовать все необходимое и даже больше. Ну или просто не знали про него, что тоже неплохо.
Понимаю, что в идеале надо так алгоритм планировать, чтобы таких ситуаций не возникало. Но просто интересно, что делать именно в контексте данной ситуации. Мне приходит только решение расставлять флаги и по ним делать break из каждого вложенного цикла, с каждым флагом продвигаясь наверх.
Такой юзкейс описан ещё в K&R был. Не вижу ниче страшного так делать, если в итоге и читат и понимать проще
> А вот тот же PowerShell
Это ниразу не аналог zsh и bash, это аналог Console.app с AppleScript из макоси.
Макось состоит из двух половинок - одна уходит корнями во всякие AmigaOS NextStep BeOS, другая это классический юникс с позикс окружением.
Это как если бы в винде в корневой папке было бы
/bin
/lib
/home
/var
/usr -> /var/usr
/etc -> /var/etc
/tmp ->/var/tmp
/ProgramData
/ProgramFiles
/Users -> /home
/Windows
А так же было бы две категории программ: испоьзующие winapi и каталоги относящиеся к виндоус-окружение и использующие unix/posix, при этом прастранства друг друга видят но воспринимают просто как папки с файлами. Из баша нельзя получить или вызвать что то из NSApi (аналог winapi), поэтому был разработан консолеапп с аплскриптом.
В консолеапп можно строчить команды операционной системе (той части которая не юних) в эплскрипте можно написать из них сценарий и скомпилировать для запуска в качестве программы.
Сейчас не знаю насколько оно живо на данный момент, но в любом случае это не аналог sh. Оно сложней и испоььзует только функции заложенные в не-позикс операционку. Тогда как баш это сам себе операционная система.
Но он прав: bash - это клей для системных тулзов и демонов в линухах. OS это не только ядро
Чето вы не в ударе
оберни циклы в функцию и делай ретурн
Выдели в функцию и return
Принудительно выставить счётчики циклов так, чтобы сработало условие выхода.
Так сходу не скажу, но я не вообще не вижу путей выхода из функции search(), просто бесконечная рекурсия т.к. нету условия выхода.
Мне вот что непонятно: мы нашли первое подмножество и вызвали себя ещё раз теперь уже с соблюдением условия if (k == n + 1), соответственно можем выводить это подмножество на экран (пикрилл 1). Выводим его, потом возвращаемся "под" вызывавшую инструкцию, после чего уменьшаем размер следующего подмножества, и готовы вызвать себя ещё раз (пикрилл 2). Вызвали себя с соблюдением условия, поэтому готовы вывести на экран очередное подмножество (пикрилл 3). И, по идее, после вывода на экран должны вернуться "под" вызывавшую ф-цию (на пикрилле 3 есть уточнения откуда вызвали и куда должны вернуться). Но мы почему-то сразу возвращаемся в ф-цию, которая вызвала вызывавшую ф-цию, т.е. мы как бы перескочили через ретёрн. Почему так?
Лови ещё код, там всё норм робит - нет никаких бесконечных ф-ций.
https://pastebin.com/Ht8Vmyyt
А что тут такого? Первая ф-ция набирает первое, самое большое подмножество, а дальше уже следуют из него исключения, когда ф-ция прыгает обратно из состояния k == n + 1. Т.е. когда ф-ция возвращает управление, то подмножество уменьшается на единицу, и следует очередной вызов ф-ции с к k + 1.
Но у меня почему-то в некоторых программах управление возвращается на это скобку, после чего уже идёт возврат в предыдущую ф-цию. Поэтому я и бугурчу, не понимая как так получается.
Пиздец, ГНУтый софт как всегда дизайном поражает умы неискушенных. На такое реально страшно смотреть, лучше обычным консольным GDB пользоваться.
>лучше обычным консольным GDB пользоваться
Не, это пердол ещё тот! ddd построен на gdb, т.е. в консоле ddd можно управлять командами gdb, только тут фичи в том, что можно окошки с переменными, аргументами, либо участки памяти с энтым кол-вом ячеек (от байта до 64 байт) выставить в панеле, и наблюдать за тем как они меняются, в процессе дебага. А в дефолтном gdb, чтобы проверить переменную/аргумент/участок памяти приходиться каждый раз исполнять команду с адресами/именами переменных, что заёбывает пиздос!!!!! Особенно, когда не особо шаришь, что делаешь и что вообще перед тобой происходит.
пускай накатывают чо хотят и смотрят как протоны на окисленных кремниевых пластинках в жопы ябуца, но не так как они планировали
чем бы дитя не тешилось...
Хз, я об этом первый раз слышу.
Проверил, в gdb выходит из функции как обычно, приземляется на следующую строчку после search().
Я уже разобрался! Дизассембл помог! Когда мы подходим к ф-ции (пикрилл 1), то мы уже находимся в "третьей" ф-ции сёрч, следовательно, после выполнения инструкции "очередной вызов самих себя", в "третьей" ф-ции сёрч больше нечего выполнять, поэтому она готовится к возврату. На пикрилле 2 видно, что, когда мы выходим из вызываемой ф-ции (то есть последняя инструкция в "третьей" ф-ции сёрч), то у вызвавшей ф-ции адрес выполнения следующей инструкции совпадает с подготовкой к ретёрну, т.е. она готовится отдать управление "второй" ф-ции сёрч. Пикрилл 3 показывает состояние стека, когда мы вернулись из "четвёртой" ф-ции; заодно он показывает, что следующая инструкция у "третьей" ф-ции сёрч это поготовка к ретёрну.
В общем, итог таков, что мы на самом деле не перескакиваем через "ретёрны", а gdb достаточно умён, чтобы понимать, если ф-ция, в которую мы прыгаем, находится в состоянии, в котором она должна вернуть управление следующей инструкцией, то и нечего в неё возвращаться, а можно сразу хуйнуть в ф-цию, которая вызывала "готовую к ретёрну" ф-цию.
Никогда не играл в доту. А вообще я уже нагуглил, как эта специальность называется, и что начинать лучше не с сей, и дурацкими вопросами заёбывать надо не сишников, а более профильных товарищей.
Энивей, моя сфера деятельности несколько примыкает к эмбеддед-разработке, так что нужный инструментарий есть, всем чмаки в этом чати, пойду я отсюда, извините за беспокойство.
Только подумал скинуть тебе все, что я нашел за некоторое время, но решил не кидать. Пошёл нахуй, лодырь.
> Visual Studio 2017
Мужик, ты шесть лет провёл в анабиозе и сбежал на двач от санитаров?
Зачем тебе эта книга? Есть же
>Stephen Prata "C Primer Plus, 6th Edition" (2014): относительно свежая, знает про C89/C99/C11, описывает различия, объемная (около тысячи страниц), годная, с вопросами, упражнениями и ответами. Читать после K&R или до.
Совершенно замечательная книга, если ты только вкатываешься. Если уже вкатился в базовый уровень, то тогда лучше что-то более сложное изучать, типа всякие алгоритмы на Си, олимпиадки. Есть много различных книг по олимпиадкам, но нет на Си, поэтому тупо переводить тот код, который представлен в этих книгах (по алгоритмам и олимпиадкам) на других языках, на язык Си это афигенная практика, если ты уже изучил базовый уровень.
вот я скачал его с официально сайта и поставил
вот я ручками создал файл main.ll с содержанием:
define i32 @main() {
ret i32 666
}
пишут, что компилятор вроде как встроен в clang.exe т.е. в виндовой сборке нет llc.exe
но так оно ругается
наверное мне нужно еще цель указать в файле main, что сборка шлангом, а не MS ?
Обстоятельно пишет, для вката самое то. Да и потом удобно использовать его книгу как справочник, как раз недавно помогла вспомнить про битовые поля.
Пожалуй, пизже, я бы даже пользовался стандартом, если есть его офлайн версия. Буду благодарен, если подскажешь где искать подобное. Хотя бы пдфку было вообще отлично и желательно С11.
Вот это я в глаза ебусь, спасибо.
Чёт не улавливаю сути - когда глобальная переменная это хорошо, а когда глобальная переменная это плохо?
Чето ты по-моему сам на свой вопрос ответил
глобалки это выгодно если:
надо разгрузить стек
надо делать ретурн из макроса
в остальном выгоднее локалки
Понял, анон! Спасибо!
Объясните дебилу что значит "разгрузить стек". Куча и стек в одну сторону растут, если ты из стека в кучу переложишь не одна хуйня будет? Или это какие-то компьютационные выгоды имеет
стек не вечный а на винде еще и выравнивание ебанутое в 32 бита вот и думай
глобалки не в куче лежат если что
При чтении советов надо всегда понимать, на каком уровне они даются. Тут объясняется начинающим, что такое хорошо и что такое плохо. Онтогенез здесь повторяет филогенез: когда-то, при появлении высокоуровневых языков, людям, привыкшим к более простым решениям, и программирующим по наитию новичкам тоже приходилось объяснять, что не стоит валить в начале программы все переменные (по примеру тех языков, в которых альтернатив не было), а потом в нужный момент глубоко внутри вызовов глобальный коэффициентик убавлять или прибавлять, и что функция не просто метка для GOTO, а логическая единица, и чем больше она напоминает чёрный ящик, при работе не открывающий и не закрывающий файлы и не переключающий краны на трубах с серной кислотой, чтобы налить чуть-чуть себе в бидончик, тем удобнее ей пользоваться и судить о работе программы.
Если у тебя модуль-объект-что-угодно является чёрным ящиком и внутренними функциями меняет своё состояние, то всё в порядке. Понятно, что на предложение в сложной многопоточной системе с кучей уровней абстракции для удобства завести переменную, чтобы хранить число подключений к базе данных, тебе сразу объяснят, что код окажется в библиотеке или каком-нибудь COM-объекте, и выполняться будет сферически в вакууме.
Типа когда пишешь { она автоматически на tab выравнивается. Я просто привык писать так как понятно лишь себе. Я недавно перешел на вим
убери в vimrc сточку set autoindent это автоиндент выравнивает по предыдущему отступу новые строки
Ах вот как это называется. Я просто думал может быть уже готовое есть на каком-нибудь ресурсе где можно писать свои exercises.
На литкоде можно писать свои упражнения, например?
здоровья тебе, анон
На кодварс вроде должно быть можно
линух, gcc
насчет номера строки - такое не знаю, наверн только компилер умеет построчно
но вот вывести например имя функции в которой крашнулось можно макросами, а вообще ты наверное про стандартные потоки говоришь? поток ошибок stderr туда пишешь текст чо случилося и ретурнишь не ноль, в консоль автоматом выпадет вывод потока ошибок
>>2866837
Внезапно, номер строки можно вывести с помощью макроса __LINE__.
https://gcc.gnu.org/onlinedocs/cpp/Standard-Predefined-Macros.html
ну я подозревал что это лоу левел проброс макровставкой по аналогии с __func__ или var но пощупать так и не довелось, не было повода, поэтому я и сказал честно что не знаю
Лучей добра тебе анончик. Уже пару дней не мог вспомнить про этот макрос, думал это как-то ещё реализовано и не получалось загуглить.
Да ничего такого, просто тренируюсь работать с сокетами и когда реализовывал обработку ошибок вспомнил об этой фиче. Поичем до этого вообще встречал это на микроконтроллерах, то ли в коде FreeRTOS, то ли у LwIP.
Я такое вообще применял только пару раз, и только на мк, когда отладку применить вообще никак нельзя было. Один раз мультипроцессорная система стм+модем sim800 с EAT, обмен и синхронизацию через два терминала пасти. Второй раз нужно было портировать стм проект на нонейм китайский проц с высиранием отладки через усарт. Тот ещё гемор, но фича нужная, выручает, когда нет других вариантов.
А все нашел. Как оно так работает? Оно прекомпилирует лайв? На макоси у меня вроде не было такого фукнционала. Пикрил на убунте.
И еще в этом примере, с этими дейфайнами в примерах всегда имя дефайна в формате имени файла, но вроде можно любое использовать и работает, например
#ifndef _2ch
#define _2ch
строковые литералы неизменяемы
>>2867677
>>2867680
почти все иде умеют блобить варнинги и ерроры просто перещелкивая паттерны и референсы
>>2867713
инклюд делает контрол це контрол вэ, сделай это сам и увидишь
>>2867775
это так, впрочем долго объяснять почему не стоит дефайнить хуйнюнейм и неймить вары в абцдиэфджи
https://pastebin.com/7j5GaDtF
там были значительные отличия между цисками и рисками по сдвигам в знаковых
А, типа, надо сравнивать бит с битом, а у меня получается, что я сравниваю два числа?
не, побитово сравнивать не получится, можно только числами (битовым набором минимальной адресной ячейки тобишь байтом)
просто ксоришь два числа и в элсе делаешь то что надо если они равны, а в мейн ветке ифа соответсвенно все остальное
это похоже на битовую маску
миллиард наносекунд назад написал себе макросы для побитовой ебли и больше не парюсь с этим, могу поделиться
https://github.com/gitPeregrin/bits
там в ридми примеры есть, думаю разберешься, хотя я конечно криво написал их
Спасибо!
Старая народная поговорка.
> Есть два вида людей, кто делает и кто учит.
Та же поговорка под реалии 2023
> Есть два вида людей, кто делает и кто запрещает.
Лучше не тревожить этого дебича! У него фетиш на почтенных стариков и нескрипто-макакные языки программирования. Сейчас, если этот дебич возбудится, то мы будем не в силах остановить его эякуляцию, которая выражается в огромных постах, посвящённых почтенным старцам и языку программирования Си.
О, вот и осеннее обострение как по графику.
быстрее на децималах, а не эффективнее
Когда будет тред с хотябы сотней перекатов, тогда подумаю. А пока какая-то нонейм хуйня.
Утечки памяти пофиксил, проблемы с налпионтером пофиксил? Что юзаешь вместо божественного cargo?
Чем тебя Python не устраивает?
Что нигерскоеиговно ты высрал? Ни о чем подобном не слышал.
писать кож гадо уметь да, это тебе не смузи попивать
Но раст тормоз по сравнению с си и памяти нужно на порядки больше, как я понял для выведения типов.
Насчет управления памятью, в си - гсс и тсс, есть боундс чекер и cleanup attr, если с autofree макро
char *buf autofree = malloc (10);
Не нужно free (buf), он освободится при выходе из видимости.
buf[20] = 1 словит боундс чекер, такой он умный, даже с маллок.
"фикс" для нулпоинтера, это через union type, в кристале например, компилятор тебе скажет, что ты забыл: if (buf != NULL) ..., но делается через выведение типов и тормознуто. В зиг как-то по другому.
Тсс, компилер для си, очен быстрый и у него даже есть: tcc -run your-prog.c. Когда этот этап быстр, то тест драйвен девелопмент быстрее.
>char *buf autofree = malloc (10);
>Не нужно free (buf), он освободится при выходе из видимости.
Не работает нихуя, пиздабол
https://godbolt.org/z/q4cM3GfWc
функция-прослойка вызывающаяся после завершения мейна и перед передачей управления ос
Звучит слишком удобно чтобы я тащил это говно в мой любимый, божественный, девственно-чистый силанг.
Да кому ты нужен
Там указатель на указатель
void free_memory(char ptr) { free (*ptr); };
>>2877850
Но тем не менее, есть вот такая фича. Но в остальном я писал, что выведение типов не дается просто так. Т.е. если тебе нужно частно ждать пока скомпилится, то это время можно потратить на что-то еще.
Насчет раст, может я соврал, посмотрел видео про тесты, вроде бы быстро.
Уже давно есть, Zig называется.
Раст не намного тормознее сишки. Типы по бОльшей части выводятся при компайл тайме, по типу шаблонов в плюсах.
>Пайтон не намного тормознее сишки. Типы по бОльшей части выводятся при компайл тайме, по типу шаблонов в плюсах.
Сыглы. Для того, чтобы сравнивать компилируемый и интерпретируемый языки, надо быть гением.
все это частные случаи трансляции, но такое макакам не понять
Не.
>>2878344
Почему нет? Есть jit. awk, это такой интерп. яп, он сравним с си, в его задачах. Но авк как инструмент будет не удобен, елси нужно будет компилить. Си, так-как быстро компилится, ближе к этим яп чем к раст. В си нет таких проверок типов как в раст. Есть яп где проверка типов отдельно.
Так что если яп отличаются, это не тем, компилятся он или нет, но как быстро это происходит. И мой вопрос по раст, был про время компиляции. Когда кто-то говорит: валите с си в раст, там крутое выведение и проверка типов. Так раст, это другая штука, ты каждый раз тратишь время на проверку типов и нет опции это отключить. Совсем другой инструмент. Хотя раст компилятор не такой уж и тормоз, вроде бы, но гораздо тормознутее tcc.
Так у меня и не сложилось мнение по растам и проч. Было бы круто, если бы яп мог выполнятся или быстро компилиться, у него был бы репл, как в интер. яп. Но если хочется, то медленно с кучей проверок типов и т.д.
Не надо экономить строки, анон. Компактность кода достигается за счет грамотной архитектуры вместо монолитных процедур. А вот это вот несколько стейтментов в одну строку нахуй надо. Уноси.
Картинка не прицепилась. splint, линтер для си, детектит нуллпоинтер.
Компайл тайм - небольшая плата за безопасность. А скорости раста и си очень даже сравнимы: https://benchmarksgame-team.pages.debian.net/benchmarksgame/fastest/rust-clang.html
>https://benchmarksgame-team.pages.debian.net/benchmarksgame/fastest/rust-clang.html
странный какой то бенч, не вижу параметров железки на которой гоняли тесты
И зачем ждать жоп время компиляции каждый раз если splint находит эти ошибки и его можно зпустить 1 раз? Ну, может он не все находит, я не знаю. Но такое разделение - быстрый компилятор и чекер отдельно, позволяет писать скрипты на си, tcc -run, что на раст из-за тормознутости компилятора не получится.
>>2878704
Зачем это помнить если есть линтер? Забуду запутстиь лентер? Так что угодно можно забыть. Запускать же линтер каждый раз, принуждением, это добавляет время для сборки, это мое время.
>Зачем это помнить если есть линтер? Забуду запутстиь лентер? Так что угодно можно забыть. Запускать же линтер каждый раз, принуждением, это добавляет время для сборки, это мое время.
ты сам то понял чо ты высрал? таблетки прими подробнее подкатом
>Зачем это помнить
помнить что? как писать код?
>Забуду запутстиь лентер?
главное таблетки не забудь
>Так что угодно можно забыть.
системы сборки
>Запускать же линтер каждый раз, принуждением, это добавляет время для сборки, это мое время.
а читать стену текста не твое время ясно понятно
Как насчет разобраться о чем идет речь. Т.е. упрек в том, что я си не знаю и все ошибки, по твоему, от не знания? Ну это глупо.
Не нужно запускать линтер каждый раз.
про какие ошибки идет речь то? в линтере ворнинг по поводу того что ты не юзаешь реутрнинг валуес от сисколов, не знаешь выхлоп своих действий а потому потенциально делаешь влепую и возможен нулпоинтер
но ты бы мог проконтролировать выхлопы врапперами как это обычно и делают, ну или хотя бы ифами
так что я вообще тебя не понимаю, чо ты несешь, при чем тут что то забыть или не знание языка если это вообще про саму суть коденга
>Не нужно запускать линтер каждый раз.
не могу согласиться с этим утверждением и вот почему
ребил происходит если были правки, а так выходит из твоих слов что ты не каждую правку нуждаешься в ревью от линтера, то есть ты уверен что в эту правку ты не накосячил с кодстайлом или чем то иным, ну может только отчасти соглашусь если это частный пример когда тебе высрало ероры ворнинги в компиле и ты их поправил, но почему в эту правку не юзать линтер все еще неясно
вообще я считаю по дефолту каждую правку юзать линтер это нормально
ты вроде паришься по поводу скорости компила, но как я вроде бы тебе ранее уже говорил это проблема архитектуры твоего проекта а не компилера или языка
>>2879085
Речь про ошибки безопасности которые связаны с управлением памятью. Забыть иф или что-то еще можно по разным причинам.
Речь про такие яп где линтер, или выведение типов и проверка, занимает ощутимое время. В си возможно прототипировать, быстро скомпилить и в конце запустить линтер и пофиксить. В тех яп нельзя отключить проверку.
Поэтому, качественно, это другие яп, не являются заменой си. Время компиляции не позволяет такое использование как: tcc -run. Может быть это где-то не важно и может быть компилятся они не так медленно, но тем не менее.
Зависит от структуры программы, но скопилируй 10 раз hello world на раст и на си, сравни время.
Кроме tcc -run, это влияет так-же на то, как ты пишешь тесты.
>Зависит от структуры программы, но скопилируй 10 раз hello world на раст и на си, сравни время.
Вангую, раст будет мб раза в 2 медленнее (типа 50мс против 100мс). Проверь сам и поделись результатами.
Пока ты будешь бороться с нулл-эксепшенами, мемори ликами и всякими другими странностями Си а уж в нем дохуища подводных камнейпри помощи сомнительных прог, и искать какую бы дедовскую библиотеку для векторов юзать, я уже 100 раз напишу прогу без ошибок по памяти, с тестами всей хуйней, любой степени сложности (треды, асинки идт) и буду сидеть на диване и попивать пивко, читая двач. Вот где время реально экономится.
А вот еще, чтобы раст тебе код проверил, ничего запускать не надо, иде тебе сама подчеркнет где ты объебался. Так что аргумент типа бульк среньк медленно компилится аж в 2 раза медленнее можно засунуть себе в зад.
Где медленно компилится - так это в тайпскрипте ебаном, а ведь это интерпретируемый язык, лол. Я когда фронт пилил, просто заебывался ждать, пока он проект перекомпилит и тесты прогонит, реально до 10с доходило.
Зачем мне что-то отвечать душевнобольному, который у себя в черепной коробке что-то надумал, и вместо какого-либо мало-мальски конструктивного ответа высирает только оскорбления? Мог бы тебя нахуй послать, но я же цивилизованный человек, а не животное.
Да ладно, мне похуй в принципе, пусть лает. Я не то чтобы много, но достаточно проектов на расте, включая пару веб-серверов https://crates.io/crates/axum охуеннен кстати, а после того, как я чутка подразобрался в его кишках - так вообще познал дзен раста так сказать, чтобы речь вести тут. В принципе новые проектики, если возможно, стараюсь на расте писать, очень уж язык нравится системой типов и гарантиями безопасности.
Кстати, непонятно, чё это он так питон не любит? Охуенный язык так-то.
возьми таймаут на недельку, пока тут растоклоун срет нормального общения не будет
Хз, я натурал, а первым оскорблять кто-то из ваших начал. А может вам сперва стоит искоренить аггресивных геев-сишников из своего треда?
Согласись уже, что растоуебок тебя заовнил, так как ни одного контраргумента от тебя не было да и иди отдохни уже
лишь в твоих фантазиях
в очередной раз необучаемая макака вбросила говна, в очередной раз на нее поссали, теперь она тут нутье разводит
ничего не меняется
мимо жабобоярин
он и был как плюсы, но макака никак не угомонится и забрасывает тред бесполезным форсом
по сабжу смысла сравнивать нет, си это макросы для ассемблера, если будет что то лучше в треде дадут знать
>а Раст уже стал аналогом плюсов по сложности и раздутости?
Не, если послушать растопетуха, то растопараша - это нераздутый простой язык, где по мановению руки решены все проблемы с мемори багами, некая достигнутая недостижимая серебрянная пуля.
>это нераздутый простой язык
Ну пускай докажет это! Пикрил 1 это пример того, как, примерно, выглядит vector из плюсов, и операции над ним pushback и popback, на языке Си, который решает рекурсивно задачку о порождении подмножеств. Собственно, пикрилл 2 это тот же пример, который написан на плюсах. Теперь, если растоман хочет доказать нам, что раст это ультракрутяк, то пускай напишет тот же пример на нём.
У растопетуха ряя ансейф от этого случится и конпелятор будет сыпать красным до тех пор пока жопа не сколапсирует.
- У нужного языка есть IDE, у самого нужного их несколько.
- У ненужного языка есть блокнотик и "пук-среньк-нинужно".
не знал что растопетухи в блокнотик пишут, чо реально нет идешки?
Фича раст, это борроу чекинг, у тебя его нет. Но для си есть чекер отдельно, пример пик,
1. нужно игогда подстказать линтеру комментариями @null@ - значит функция может вернуть null, и т.д., но не так много анатаций, как видно
2. если уберать assert -> чекер выдаст ошибку
3. забуду free, тоже
4. нет проверки if (numline->line) -> выдаст ошибку
5. если вместо free (numline->buf), написать free (buf) -> линтер тоже выдаст ошибку, так-как передал управление объектом на который ссылается buf в mainline->buf. Ну вот это что-то вроде борроу чекинга, как я понял.
malloc перед getline, потому что чекер/splint не знает или я не знаю, как указать что getline выделяет память.
Но я так понял мало кто юзает линтер. Не знаю насколько это близко к раст чекеру.
представляю как ты тикеты закрываешь если на задачу навелосипедить вектор высрал это
зато в 100 раз быстрее да?
>Ну пускай докажет это!
Лол, какие-то детские выебоны. Типа а давай спорим на щелбан шо ты не дурак! Никто с нуля эти вектора не пишет, есть готовые библиотеки линейной алгебры. Есть миллион способов сделать это в rust, там есть небезопасный режим, в котором можно резервировать и освобождать память как вздумается. Там есть методы shrink_to(), shrink_to_fit() для массивов, есть метод truncate(), есть макросы, есть хитрожопые типы... Короче если нужна библиотека линейной алгебры, можешь посмотреть --> https://nalgebra.org/
мимо-проходил-раст-программер
Ха! Слился? Вот я дед для каждой своей олимпиадной программы пишу реализацию вектора с нуля! И смузи не пробовал никогда! Ууу эти хипстеры, пиздуйте нахуй из треда!
>никто велосипеды не пишет
Правильно, поэтому в маленький проект тянется огромная либа с кучей зависимойстей как в npm.
goto что-ли? Ну это же пример бороу чекинга, написал что будет если в конце заменить free (numline->buf) на free (buf).
Тред какая-то диверсия, уровень культуры, внимания к тому что пишут, ниже некуда,
>Тред какая-то диверсия, уровень культуры, внимания к тому что пишут, ниже некуда,
Растопитухи понабежали ажтрисет, второй день валерьянку пью
ничего нового
папущины
>есть готовые библиотеки линейной алгебры
Прошу написать структуру (вектор в плюсах), которая очень похожа на обычный динамический массив, но со своими некоторыми "приколами", а этот растопетуччило говорит про линейную алгебру!! Представили ебало этого погромизда, который пытается в системное программирование, не умея гуглить, и даже не имея любопытства, чтобы начать гуглить?
А ответ прост - раст это такое же перегруженное говнище, как и плюсы, которое ни в коем случае нельзя юзать для системных фишек!!! Но можно и удобно юзать, если надо сделать красивое манипулирование красивыми кнопочками! Растопетуччилло, чем отличается выделенная часть на пикрилле от того, что я привёл на плюсах?
полагаю он подумал что векторы из матеши надо написать, однако все равно мы не дождались никаих потугов от перекладываля джейсончиков
В чем проблема вектор-то написать? Один только вопрос: зачем? Ты так выебываешься, будто это невьебенно сакральное знание, я ору.
Лови кость: https://pastebin.com/NdYvffGD
Кста, накидал эту хуйню за полчасика после ужина. Уже смакую как этот клоун будет петушиться.
>вектор
>почасика
>В чем проблема вектор-то написать? Один только вопрос: зачем? Ты так выебываешься, будто это невьебенно сакральное знание, я ору.
Ну, короче, что и требовалось доказать, куча какой-то ооп параши и свистоперделок.
Пиздец!! И эта простыня решает такую простую задачку, как нахождение подмножеств? Чел, во-первых, ты сравни объём кода, во-вторых, он ещё и по скорости проигрывает, просто потому что я тебе доказал предыдущим постом, что раст это перегруженное говнище. И теперь, включи голову и подумай за что ты топишь:
1) За то что увеличивает объём кода
2) За то что понижает скорость.
А теперь взвесь эти два аргумента, и съеби с треда, поняв, что у тебя тупо нет никаких аргументов против Си.
А в этой растопараше есть понятие null pointer constant? Если произойдёт какая-то ошибка, что вернёт std::alloc::alloc?
На низком уровне с рав пойнтерами только в ансейфе можно работать, потому что у компилятора нет способов убедиться, что у тебя в них лежит. Это даже имбейилк ясно. Обычно, если нужна работа с указателяии, пишут в ансейфе, обкладывают тестами и выставляют наружу сейф интерфейс.
>1) За то что увеличивает объём кода
В чем проблема? По-моему довольно читаемо. Там треть кода мейн + коменты + 2 геттера + пару хелперов.
Мы объемами кода меряемся? Мб письки еще измерим?
>2) За то что понижает скорость
На какой строке понижается скорость, можешь пояснить?
>>2881487
Да, std::alloc::null
В случае ошибки алллокауии вернется как раз null
Про "ряя ансейф" это была ирония, я думаю, все помнят историю с Коляном.
>если нужна работа с указателяии, пишут в ансейфе
Ансейф параша это про разименовывание raw указателя и вызов ансейф говна.
>>2881522
>довольно читаемо
Гораздо менее читаемо, чем листинг сипараши выше.
>2 геттера + пару хелперов
Нахуя это все было делать вообще?
Геттеры - чтобы юзер не мог сам шариться по структуре и менять приватные поля. Остальные приватные - ну мне так удобнее.
>юзер не мог сам шариться по структуре и менять приватные поля. Остальные приватные - ну мне так удобнее.
Ладно, что ты в нашем треде забыл любитель приватных полей?
>Про "ряя ансейф" это была ирония, я думаю, все помнят историю с Коляном.
Бля, постоянно эта хуйня на языке вертится, но откуда пошло и что за Колян - не знаю)
Почему-то не удивлён.
Не могу найти, но есть же такое?
*online
Что они имеют ввиду под AI tutor? Я не нашел никакого AI tutor у них.
Его скорее всего настроить для начала надо, типо как через stty это деланшь, только набором библиотечных функций. Т.е. у тебя там не только read() будет вызываться, но и ещё какой-нибудь ioctl() с нужными параметрами для ком порта.
Обычное дело для работы с периферией. Скорее всего для работы с ком портом уже давно есть удобные либы, у меня так недавно с GPIO было, достаточно заинклудить gpiod.h и там уже все готовое для инициализации и работы есть. С uart вообще проблем быть не должно, потому что он слишком древний.
Вот, братан, я погуглил для тебя, может подойдёт:
https://stackoverflow.com/questions/6947413/how-to-open-read-and-write-from-serial-port-in-c
Ахуеть, то есть мы буквально открываем дейвайс на линуксе и пишем в него какие-то байты? Выглядит интересно. А на винде это как программируется, там ведь не всё файл, как в линуксе.
мимо
>мы буквально
буквально файл
что кстати очень удобно, можно $ ls -a /dev прочекать все устройства вотличие от
обмен инфой между процессами посредством сокетов так же буквально пишем в файл и читаем из него же
а вот про винду не знаю, анончики подскажу, я лет 15 уже на винде не был
Я, мб, дегенерат, но откуда эта функция взялась? Никак не могу нагуглить.
Возможно какая-то user defined, которую он не выложил.
Ты, наверное, из тех кто и розовый цвет пидорским считает, верно?
Скорее всего это макрос какой-то для логирования.
Возможно, даже как-то не обратил внимания на подсветку синтаксиса, а вот гцц явно выделяется.
prog1.c
#include<stdio.h>
int main(int a, charaa)
{
int a[20];
return 0;
}
prog2.c
#include<stdio.h>
int main(int a, charaa)
{
int n;
scanf("%d",&n);
int a[n];
return 0;
}
Трюк с массивом, как во второй программе, проделаваю часто, но лишь сейчас возник вопрос: если в первой программе компилятор знает, сколько выделять место в стеке, то во второй как?
У меня была мысль, что если компилятор видит объявление массива и в квадратных скобках не константа, а переменная, то заменяет всё на строчку с malloc, но и к этому у меня несколько вопросов.
мой компилятор не пропустит второй вариант по причине нон статик вар ин статик аррэй
твой видимо волшебный
gcc спокойно пропустил. clang возмущался.
Ка бэ, не особо то и глупый вопрос!
Пикрилл 1 это дизассембл первой программы. Тут компилятор даже не ввёл массив, потому что он не задействован в проге. Если в твою прогу добавить цикл заполнения массива единицей, то он выглядит как пикрил 2, т.е. тут уже массив задействован.
Приколы начинаются, когда дизассемблишь вторую программу! Тут какие-то "финты ушами", после того как scanf вернула управление (пикрил 3-4). Обрати внимание, сколько регистров задействовано! Компилятор gcc.
Продолжение!
Пикрил 1 это, если использовать malloc после scanf. Пикрил 2 это реализация malloc на асме для линукса, чтобы сравнить объём кода, твоей проги 2 и проги, которая использует malloc. И мне кажется, что код с malloc гораздо компактнее и яснее.
>то во второй как?
Во время исполнения выделяет на стеке.
>то заменяет всё на строчку с malloc
>malloc
Нет, см дизасм с комментами.
https://pastebin.com/P2WFRUYU
Это получается, что, если во второй проге в сканф загнать значение большее значения стека (допустим, что стек 8 мегабайт), то прога упадёт?
У тебя средний стек, не волнуйся, а пиздаболам с двача не верь, у кого там по 8МБ.
чо несет
>-Что за дизасемблер на пике?
>-Дизассембл программ на Си. Кринж это когда спрашивают, что такое дизассембл
>-Ты ёбнутый?
>-Не рвись.
Нет сырья и кадров.
576x1024, 0:16
проебали все полимеры
Дизассемблер, представленный в пикрилах этого >>2888345 и этого >>2888356 постов, это gui утилита на базе radare2. Если ты спрашиваешь о том, что вообще такое дизассембл, то советую загуглить. Если ты спрашиваешь про то, что конкретно я дизассемблил, то:
1) пикрил 1 (данного поста) это пикрил 1 этого поста >>2888345
2) пикрил 2 (данного поста) это пикрил 2 этого поста >>2888345
3) пикрил 3 (данного поста) это пикрилы 3-4 этого поста >>2888345
4) пикрил 4 (данного поста) это пикрил 1 уже вот этого поста >>2888356
2-й пикрил вот этого поста >>2888356 не имеет дизассембла, ибо код, представленный на данном пикриле (2-й вот этого поста >>2888356) уже сам написан на ассемблере, а это значит, что данную программу не имеет смысла дизассемблить.
зумеры...
Ну, он даёт направление, а дальше сам. Например, асм по его книге выучить невозможно, потому что у него банально не показано то, как выводить на экран результат программы. В общем, если его книги совмещать с другими, но при этом придерживаться того порядка, в котором подаётся материал в его книгах, то с "нулика" подняться можно.
> буквально файл
Люди, которые бездумно повторяют восхваления этого «концептуального прорыва», забывают уточнить контекст. В шестидесятые-семидесятые годы какие, собственно, устройства подключались к большим и малым ЭВМ? Устройства хранения данных, каналы связи, терминалы. А какая была альтернатива? «Загрузите по адресу ABCD код команды, дождитесь установки статусного регистра устройства, получите статус операции по другому адресу, в течение 500 мкс отправьте данные для записи, если не успеете — состояние буфера не определено, сбрасывайте и читайте заново и так далее». Ну, или библиотека, в которой кто-то делает это всё за вас, и остаётся только функции вызывать в нужном порядке (который тоже требует понимания внутренностей). На этом фоне «ну типа пиши данные как в файл» было волшебной абстракцией.
Занятно, что персональные компьютеры проходили те же ступени эволюции, и в какой-то момент пользователи, желающие использовать крутейшую вещь — НЖМД, должны были сами в контроллере настраивать и цилиндры-головки-сектора, и задержки доступа (в буквальном смысле сколько нужно крутить мотор, чтобы при начале чтения или записи метка начала нужного сектора оказалась у головки, и сколько ждать после этого) в зависимости, например, от быстродействия чипов памяти, стоящих в компьютере, а потом объяснять то же самое программам, желающим общаться с диском. Потом это всё быстренько обернули в более удобные форматы, как аппаратные, так и программные. Подробности в видосиках про старые диски у https://www.youtube.com/watch?v=8LbFKV_pPAE
к чему этот длиннопост? хочешь сказать сейчас как то иначе делается с удаленной периферией? не дури нам голову, все так же как в 70х
> длиннопост
С пейджера читаешь? Что-то мне подсказывает, что длинных постов ты и не видал.
Представить программам таким образом устройства, которые логично было представлять в виде потока символов, было шагом вперёд. Устройства, имеющие сложное состояние, настраиваемое кучей способов, в файловую абстракцию не запихиваются. Для сети, например, взяли концепцию сокетов, а не какое-нибудь /dev/internet/tcp/192/168/5/5/666. Впрочем, были и другие абстракции вроде
https://en.wikipedia.org/wiki/X/Open_Transport_Interface
> С пейджера читаешь? Что-то мне подсказывает, что длинных постов ты и не видал.
Ты просто растекся мыслью без повода, а вывода никакого не привёл. Спрашивается, нахуя?
>Устройства, имеющие сложное состояние, настраиваемое кучей способов, в файловую абстракцию не запихиваются.
какой же поток хуйни от хабродебила я ебал это комментить
Тебе с такими вопросами прямиком в пориджную.
Диды либы не ищут, диды для каждого проекта сами реализуют примитивы типа векторов с нуля и гордятся этим.
рубрика ответов чата-гпт
Для правильного поиска библиотек для языка C вы можете использовать следующие подходы:
1. Используйте пакетные менеджеры:
- Обратитесь к документации вашего дистрибутива Linux, чтобы определить, какой пакетный менеджер у вас установлен.
- Используйте команды поиска пакетов в вашем пакетном менеджере, такие как apt search, yum search, pacman -Ss, zypper search, в зависимости от вашего дистрибутива Linux.
- Введите ключевые слова, связанные с библиотекой C, которую вы ищете, и просмотрите результаты поиска для получения списка пакетов, содержащих эти библиотеки.
2. Посещайте сайты репозиториев:
- Многие дистрибутивы Linux имеют официальные репозитории, где вы можете искать и устанавливать библиотеки.
- Обратитесь к веб-сайтам вашего дистрибутива Linux и найдите раздел, посвященный репозиториям, чтобы получить доступ к списку библиотек и инструкциям по их установке.
3. Используйте онлайн-ресурсы:
- Существуют онлайн-ресурсы, такие как www.cplusplus.com, www.github.com и www.nongnu.org, где вы можете найти различные библиотеки для языка C.
- Используйте поисковые системы, чтобы выполнить поиск по ключевым словам, связанным с тем, что вы ищете. Например, "C libraries for networking", "C libraries for graphics", и т.д.
4. Коммуникация с сообществом:
- Обратитесь к сообществам программистов на языке C, форумам и IRC-каналам, где вы можете помощь в поиске конкретных библиотек или рекомендаций относительно задачи, которую вы пытаетесь решить.
- Задайте свой вопрос в соответствующих группах в социальных сетях или на специализированных платформах, таких как Stack Overflow, где сообщество может предложить вам конкретные рекомендации по библиотекам, основываясь на вашей задаче или потребностях.
Общий совет: перед установкой или использованием библиотеки, проведите некоторое исследование, чтобы убедиться в ее актуальности, надежности и соответствии вашим требованиям. Ознакомьтесь с документацией и оцените качество кода и отзывы сообщества перед тем, как интегрировать новые библиотеки в свой проект.
рубрика ответов чата-гпт
Для правильного поиска библиотек для языка C вы можете использовать следующие подходы:
1. Используйте пакетные менеджеры:
- Обратитесь к документации вашего дистрибутива Linux, чтобы определить, какой пакетный менеджер у вас установлен.
- Используйте команды поиска пакетов в вашем пакетном менеджере, такие как apt search, yum search, pacman -Ss, zypper search, в зависимости от вашего дистрибутива Linux.
- Введите ключевые слова, связанные с библиотекой C, которую вы ищете, и просмотрите результаты поиска для получения списка пакетов, содержащих эти библиотеки.
2. Посещайте сайты репозиториев:
- Многие дистрибутивы Linux имеют официальные репозитории, где вы можете искать и устанавливать библиотеки.
- Обратитесь к веб-сайтам вашего дистрибутива Linux и найдите раздел, посвященный репозиториям, чтобы получить доступ к списку библиотек и инструкциям по их установке.
3. Используйте онлайн-ресурсы:
- Существуют онлайн-ресурсы, такие как www.cplusplus.com, www.github.com и www.nongnu.org, где вы можете найти различные библиотеки для языка C.
- Используйте поисковые системы, чтобы выполнить поиск по ключевым словам, связанным с тем, что вы ищете. Например, "C libraries for networking", "C libraries for graphics", и т.д.
4. Коммуникация с сообществом:
- Обратитесь к сообществам программистов на языке C, форумам и IRC-каналам, где вы можете помощь в поиске конкретных библиотек или рекомендаций относительно задачи, которую вы пытаетесь решить.
- Задайте свой вопрос в соответствующих группах в социальных сетях или на специализированных платформах, таких как Stack Overflow, где сообщество может предложить вам конкретные рекомендации по библиотекам, основываясь на вашей задаче или потребностях.
Общий совет: перед установкой или использованием библиотеки, проведите некоторое исследование, чтобы убедиться в ее актуальности, надежности и соответствии вашим требованиям. Ознакомьтесь с документацией и оцените качество кода и отзывы сообщества перед тем, как интегрировать новые библиотеки в свой проект.
У скриптомакак ни пичот! Повторяю! ни пичот!!!
> Представить программам таким образом устройства, которые логично было представлять в виде потока символов, было шагом вперёд.
Диск никак не поток символов, он набор блоков с квазипроизвольным доступом. Нахуя его делать файлом? Томпсон головного мозга.
vcpkg
https://pastebin.com/xaaVT3St
Чтобы сохранить подмассив.
Да, этот вариант подходит.
Учи Си.
По моему он тролит.
Учи последнюю версию и знай c89, чтобы максимально портируемое ПО под максимальное количество архитектур писать.
С отдельными диалектами и особенностями компилятора в процессе работы разберешься..но лучше на диалектах не писать
Как заставить функцию main применять в качестве аргументов кириллицy? chcp 1251, chcp 65001, SetConsoleCP() и SetConsoleOutputCP() не помогают, пытался использовать LPWSTR, но тоже не помогло, OS -- windows 10, компилятор -- gcc
А я обычно, когда проект компилирую в консольное приложение или же исполняемый файл, то прости пишу так
gcc main.c functions.c global.c
main.с это собственно файл с главным циклом программы, функцией main.
functions.c — это функции написанные для работы алгоритма
global.c — это файл с константами, чтобы из было удобно изменять, не залезаю в .h , хотя его и можно в .h запихнуть
Совсем неправильно делаю или надо как Вы сначала скомпилировать объектные файлы, а уже потом их слинковать в один исполняемый файл?
А я обычно, когда проект компилирую в консольное приложение или же исполняемый файл, то прости пишу так
gcc main.c functions.c global.c
main.с это собственно файл с главным циклом программы, функцией main.
functions.c — это функции написанные для работы алгоритма
global.c — это файл с константами, чтобы из было удобно изменять, не залезаю в .h , хотя его и можно в .h запихнуть
Совсем неправильно делаю или надо как Вы сначала скомпилировать объектные файлы, а уже потом их слинковать в один исполняемый файл?
и нахуй ты мне заголовок main скинул, сволочь, смешно думаешь? Ты вообще не вчитывался вопрос видимо
>>2896057
у тебя теже этапы компила в объекты и линковка проходят под капотом, конечно лучше контролировать данный процесс
ведь не обязательно кажый раз рекомпилить глобалы пральна? поменялось чота в функциях - ты рекомпилишь все файлы, я рекомпилю только объектник функций
как проекты станут больше хеловорлдов разница станет ощутимой
побитово прочитай ввод и распарси по табличке
Ведь обход какого-то крайне огромного графа(хоть в ширину, хоть в глубину) будет быстрее у C/C++, ведь многопоточность на си более настоящая, чем у питона.
Меня вообще смущает, что питон как-то более часто используется студентами/аспирантами/исследователями в написаниях и численных экспериментах. Ладно, допустим, что это за счёт кроссплатформенность, но почему тогда не джава(тоже кроссплатформенность)?
Так питон может либо на Си использовать не?
>Меня вообще смущает, что питон как-то более часто используется студентами/аспирантами/исследователями в написаниях и численных экспериментах.
Потому что питон используется как "клей" к числодробилкам на компилируемых языках, аля Си, плюсы, фортран. Питон - это язык более высокого уровня, который позволяет людям без особых навыков программирования относительно легко решать задачи предметной области.
Основную работу по вычислениям выполняют библиотеки на си/плюсах, как ты и сказал.
Алсо, питон можешь заменить любым другим скриптовым языком, аля R, Julia, Guile и т.д.
jit Только у pypy есть, у cpython никакого jit нет и не будет скорее всего.
Потому что нейросети это предметная область, как бухгалтерия. Бухгалтеры и ученые не программисты, их компьютер не интересует, им нужен язык для даунов чтобы проще было писать их алгоритмы не заморачиваясь ничем лишним. Поэтому они используют 1С и питон, так проще.
Кстати, раньше для этой нейромутатени использовали LISP, такая же высокоуровневая параша как питон, а может и хуже.
Ставлю вот build tools в надежде, что там есть. Какие галки ставить?
Как научиться читать? По отдельности гуглю каждую функцию и аргументы, но целиком строки не понимаю, не говоря уже о целых блоках.
Мимо вкаткун самоучка
1) Знать стандартную библиотеку (если такое вообще применимо к Си, лол)
2) Больше кодить
3) Больше чиать чужой код
4) Иметь хотя бы базовое представление о предметной области для которой написан код
Это же под линукс типа эмуляцию виндовской среды?
Ставь Code Block портабельную версию и не еби свой моск.
И какой дебаггер используется если я юзаю https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools
пикрил
>имена всех макросов
gcc -dM -E header.h
> и функций
Как напечатать определения функций - хз. Если там инлайн функции, то
gcc -fdump-tree-all header.h
появится куча файлов, среди них будет что-то типа a-header.h.005t.original, там все увидишь
бамп
бамп
include — директива препроцессора, которая включает в текст программы содержимое указанного файла.
Эта директива имеет две формы:
— #include "имя файла";
— # include <имя файла>;
Имя файла должно соответствовать соглашениям операционной системы и может состоять либо только из имени файла, либо из имени файла с предшествующим ему маршрутом.
Если имя файла указано в кавычках, то поиск файла осуществляется в соответствии с заданным маршрутом, а при его отсутствии в текущем каталоге.
Если имя файла задано в угловых скобках, то поиск файла производится в стандартных директориях операционной системы, задаваемых командой PATH.
как раз с угловыми кавычками и не сработало, я поменял на другие, думал дело в этом
Процессор предоставляет операционке возможность выстроить непрерывное адресное пространство на столько процессов, на сколько нужно. От 4КБ до 4МБ. Есть ещё 1ГБ. Ядро может тасовать эти страницы на своё усмотрение, редактируя специальную таблицу. Тем временем для обычного процесса пользователя ядро и компилятор могут абстрагировать этот механизм, дробя память кусками поменьше; но непрерывность в них уже будет обязательной, так как программы компилируются в бинарники с нативной адресацией процессора, и подменяться, как в механизме выше, уже не могут; да и не выгодно это будет в таком масштабе. Взглянуть на адреса переменных можно через printf "%p". Обычно их выравнивают на некоторую величину для оптимизации скорости доступа; даже рядом стоящие в одной структуре располагают не подряд, если те меньше машинного слова; как в стеке.
твой вопрос завист как от того что за ОС, так и от типа архитектуры процессора в общем случае.
вообще можешь маллокнуть себе 100байт себе и посмотреть сколько процессу выделится в итоге.
>Правильно ли я понимаю, что из-за того, что память выделяется "страницами" обычно по 4КБ, то даже выделив malloc'ом 100 байт, к примеру, процессу выделится пул 4КБ и последующие вызовы malloc, в случае если этого пула хватает на выделение, будут его использовать, а не требовать новую страницу?
Да. Там все немного сложнее, есть арены, чанки, но суть верна. Если нужны подробности - https://sourceware.org/glibc/wiki/MallocInternals
>И как быть, если надо выделить 2МБ? Эти 2МБ будут разбиты на несколько страниц, или это будет 1 страница размером 2МБ?
Зависит от архитектуры и размера страницы на этой архитектуре
Подробнее - https://en.wikipedia.org/wiki/Page_(computer_memory) , таблица "Page sizes among architectures"
>И в случае, если выделяется несколько страниц, то как будет происходить адресация?
Если совсем упрощенно: в процессоре есть специальная таблица, которая сопоставляет "виртуальные" адреса, которые тебе выдала ОС и "физические" - те, которые есть в железе. ОС выделяет тебе несколько страниц для твоего массива, у них виртуальные адреса идут по порядку, но физические могут быть разбросаны как угодно
https://en.wikipedia.org/wiki/Virtual_memory
поясните по пику плиз
void * - это просто указатель на какую-то область памяти без привязки к типу данных, которые там находятся. так?
а что значит empty? это какое-то ключевое слово? или имя переменной?
Если ты про свой пик то эмпти просто имя указателя. А воид да это наше все.
Ну так это метамем, типа этот чел, который на переднем плане, может указывать вообще на любую хуиту, поэтому он void*. Только хз почему empty,? И почему у "указателя" нет глаз? И почему чел, на которого указывает "указатель" держит закрытыми глаза? Вообще, empty void можно перевести как "пустая пустота", типа, наверное, когда глаза закрыты или их нет, то перед глазами одна лишь темнота, что метафорически можно связать с пустотой, поэтому типа депрессивный такой мем, типа пустота указывает на пустоту.
А вообще, это хуита какая-то! Иди спроси у создателя мема, что этот долбоёб хотел сказать.
Никто указывает на ничто! Типа такая провокация, такой бунд, либо тупо защитная реакция (видать в каком-то из мемов с "указателем", автор узнал себя и подгорел), что типа тот, что не значит ничего, указывает на то, что не значит ничего, на то, что абсолютно неважно, что вообще не имеет никакого значения!!!
Насколько я помню, они закрываются для того, чтобы не наследовались процессом через exec. Вроде как есть какой-то флаг чтобы сами закрывались, CLOEXEC вроде или что-то такое.
Пёс учись по книге 1978г.
Чтобы exec не унаследовал их дескрипторы, ну и просто чтобы не было дублирующихся дескрипторов, там же пайп переназначается на поток вывода в процессе-потомке.
Спасибо
Ебал примеры в капче.
Могу предложить, что иногда так код лакончинее получается, когда в одну строчку можешь запихнуть вместо 2
Код ошиби. Если значение не равно твоему - случился говняк.
Да, они просто гарантируют, что задержка не будет меньше, но ведь в случае с nanosleep() она будет намного больше. Если я вызову nanosleep(100) в реальности пройдет минимум несколько сотен микросекунд или даже несколько миллисекунд, что намного больше 100 наносекунд. Мб они в спец железе применяются, где есть какие-то аппаратные таймеры? Но у нас ведь все равно время ограничивается частотой вызова шедулера.
Напиши свои
Функции usleep() и nanosleep() предназначены для создания задержки в исполнении программы на определенный промежуток времени. Они могут быть полезны в различных сценариях программирования, но имеют свои особенности, когда речь идет о очень коротких задержках.
Основное назначение usleep() и nanosleep() - обеспечить задержку в течение определенного времени в микросекундах и наносекундах соответственно. Однако, существуют ограничения в точности, с которой они могут создавать такие задержки.
В операционных системах, где эти функции реализованы, существует выделенное время на выполнение задач, известное как квант времени (time slice). Квант времени является минимальным временным интервалом для выполнения задачи и может быть несколько миллисекунд.
Это означает, что если задержка, указанная в usleep() или nanosleep(), составляет менее кванта времени, то точность задержки может быть низкой. Например, если квант времени равен 10 миллисекундам, использование usleep() или nanosleep() с задержкой 1 микросекунда может быть не очень точным.
Также следует учитывать, что точность задержки может зависеть от аппаратной и операционной системы, на которой запущена программа. Различные системы могут иметь разные ограничения и реализации для таких функций.
Если вам требуется более точная и предсказуемая задержка, возможно, вам понадобятся другие методы, такие как использование аппаратных таймеров или библиотек с более высоким разрешением времени.
Сжечь ведьму нахуй!!!
>int main()
>{
> char pid{[}255{]};
> fork();
Это что за лабуда скобочная? Первый раз в жизни вижу.
Хлебушек? Не можешь выделить основное из многабукафф??
>В операционных системах, где эти функции реализованы, существует выделенное время на выполнение задач, известное как квант времени (time slice). Квант времени является минимальным временным интервалом для выполнения задачи и может быть несколько миллисекунд.
А остальное чисто для расширения кругозора.
Это хуита какая-то! Либо это какой-то неизвестный мне компилятор, который имеет свой "особый" синтаксис Си, либо просто ошибочная попытка объявить массив чаров в 255 элементов.
Да я читал статью с опеннета и наткнулся.
https://www.opennet.ru/docs/RUS/linux_parallel/node7.html
2004 год, может старые какие хаки. Не могу понять, чем обусловлено такое причудливое написание. Автор будто бы хотел обособить квадратную скобку от числа или имени переменной.
Хлебушек, я буквально это в своем вопросе написал другими словами, а ты вместо прочтения побежал кормить нейросетку.
Хлебушек, написано, что квант времени зависит от операционной системы. Если ты реализуешь операционную систему реального времени (без всяких твоих высокоуровневых-скриптомакакных шедулеров), где будет стоять приоритет на определённой задаче, т.е. произошло некое событие, которое само отправило сигнал прерывания процу, и проц переключился на то, что нужно, или "прыгнул" туда куда нужно. То в таком варианте почему не должны работать usleep() и nanosleep()?
К&R
Приведи пример ОСРВ без скриптомакакного шедулера/планировщика с поддержкой usleep и nanosleep.
> где будет стоять приоритет на определённой задаче
А приоритет между задачами по твоему кто распределяет? Не шедулер?
Да, анон, я хуиту написал! Я себе по-другому принцип работы ОСРВ представлял.
На инглише - легко
Знаю си,базу плюсов и алгоритмов. Физика давалась в школе так себе, но щас повторил школьный курс.
Куда копать?
Себя на натуральность проверь лучше, и в случае отрицательного результата оформи срыгос на жаваскрипт.
Почему у вам всегда такие абстраетные ответы? Если бы я знал как проверить я бы и не спрашивал? И при чом тут жава если тред по си
А как он поймет какой тип данных? Любые данные это ведь просто двоичный код, что целые числа, что дробные, что строки
>А как он поймет какой тип данных?
Тип данных зависит от спецификаторов, которые ты указываешь, что сканфу, что принтфу.
Во-первых, почитай эту статью:
https://metanit.com/c/tutorial/2.3.php
Во-вторых, после первой статьи, приобщись к этим двум статейкам:
https://kaf401.rloc.ru/Informatics/formats.htm
https://www.c-cpp.ru/content/scanf
После этого, думаю, станет яснее!
А вообще, чтобы сразу дать правильный старт по Си, советую эту книгу:
Stephen Prata "C Primer Plus, 6th Edition"
Также есть русский перевод, достаточно достойный перевод!
на торрентах тоже есть и ру и англ.
Опять слишком абстрактно!
>вместо однозначного ответа
А это что:
>Тип данных зависит от спецификаторов, которые ты указываешь, что сканфу, что принтфу.
?
Если хочешь ещё более однозначно, то, все "числа", которые ты вводишь с клавы, это, на самом деле, просто символы из таблицы ASCII (если бы я тебе так однозначно ответил бы, то ты бы, наверное, совсем охуел бы, поэтому в надежде на то, что ты не будешь "сюда" наводиться, я уберу эту часть пста под спойлер, ибо, если ты сейчас это прочтёшь, то совсем охуеешь!!!), которые являют собой, ничто иное, как двоичное число с разрядностью в 8 бит, только, для обозначения первых 128 символов таблицы ASCII, в число которых входят и цифровые символы, используют первые 7 бит этого двоичного числа (надеюсь, что ты таки не навёлся сюда, ибо сейчас ты можешь совсем охуеть от этой инфы!!!). Числа, которые ты ввёл с клавы, на самом деле строка символов (сишники такие строки называют массив чаров с нулём (нуль в данной ситуации это самый первый символ из таблицы ASCII, который имеет код 0х00 в шестнадцатеричной системе счисления (почему шестнадцатеричная система?, да потому что так компактнее обозначать двоичные данные (т.к. в шестнадцатеричной системе (надеюсь, всё-таки что ты не навёлся сюда, в противном случае ты, наверное, сейчас совсем охуеваешь) каждая цифра представляет 4 бита (2^4 = 16 (т.е. можно уместить алфавит в 16-ть цифр (0, 1, 2, 3, 4, 5, 6, 7 , 8, 9, A, B, C, D, E, F)), т.е. каждая цифра это полубайт (8 / 2 = 4)), следовательно, обозначения символов из таблицы ASCII в шестнадцатеричной системе занимают всего два символа (надеюсь, что всё-таки ты не навёлся...) заместо 8 в двоичной, либо трёх в восьмеричной и десятичной))) на конце), которую преобразуют в число, исходя из следующего алгоритма: подсчитывают кол-во разрядов (т.е. количество символов в числе (например, в числе 45 - два символа ( 410^1 + 510^0), а в числе 456 - три символа ( 410^2 + 510^1 + 6*10^0))), это можно делать при вводе символов (надеюсь, что ты сюда всё-таки не навёлся, ибо, если ты навёлся и сейчас читаешь это, то ты совсем охуел, и мне тебя жаль) с клавиатуры, как бы организуя цикл, который работает до тех пор, пока, например, не введён символ 0x0A, который обозначает перевод строки; и до тех пор, пока не введён символ, обозначающий конец ввода, можно подсчитывать в переменной (обычно этот подсчёт идёт в регистре (обычно употребляется rcx)) кол-во разрядов; после чего из строки символов достаётся по одному символу (можно с начала, а можно с конца строки, это неважно (т.к. у нас есть инфа о кол-ве разрядов, следовательно, мы можем использовать её для организации цикла)), из которого вычитается код символа '0' (т.е. 0х30 (т.е. 48 в десятичной системе (т.е., так как коды символов цифр идут подряд, то, чтобы получить, допустим, 5, мы от кода символа '5' (0х35 (т.е. 53 в десятичной)) отнимаем код символа '0' (т.е. 0х30 (т.е. 48 в десятичной)), следовательно 53-48 = 5))) и разница умножается на 10-ку, степень которой соответствует данному разряду (допустим, исходя из того, какое значение в данный момент времени находится в rcx), а результат складывается в переменную (обычно это регистр rax (и естественно, что весь процесс происходит в двоичных числах)), который в данный момент времени обозначает число, которое ввёл юзверь. Можно также организовать схему Горнера (пикрил 1(она выполняется быстрее, потому что требует меньшее суммарное кол-во операций)), но от этого алгоритма ты можешь совсем-совсем охуеть, поэтому не стоит (я всё-таки надеюсь, что ты не навёлся на этот спойлер, поэтому ты это не читаешь и не охуеваешь). Также неважна система счисления, также неважно какое число ты вводишь - целое, или вещественное, ибо алгоритм тот же, только способ хранения (различные там стандарты IEEE 754, всякие там дополнительные коды (но это уже совсем для полнейшего охуевания (надеюсь ты это не читаешь))) отличается, но получение числа из массива чаров одно и то же.
После того, как мы получили число из массива чаров, процессор его схороняет в участке памяти, который ты выделил для хранения своей переменной в нужном формате.
>вместо однозначного ответа
А это что:
>Тип данных зависит от спецификаторов, которые ты указываешь, что сканфу, что принтфу.
?
Если хочешь ещё более однозначно, то, все "числа", которые ты вводишь с клавы, это, на самом деле, просто символы из таблицы ASCII (если бы я тебе так однозначно ответил бы, то ты бы, наверное, совсем охуел бы, поэтому в надежде на то, что ты не будешь "сюда" наводиться, я уберу эту часть пста под спойлер, ибо, если ты сейчас это прочтёшь, то совсем охуеешь!!!), которые являют собой, ничто иное, как двоичное число с разрядностью в 8 бит, только, для обозначения первых 128 символов таблицы ASCII, в число которых входят и цифровые символы, используют первые 7 бит этого двоичного числа (надеюсь, что ты таки не навёлся сюда, ибо сейчас ты можешь совсем охуеть от этой инфы!!!). Числа, которые ты ввёл с клавы, на самом деле строка символов (сишники такие строки называют массив чаров с нулём (нуль в данной ситуации это самый первый символ из таблицы ASCII, который имеет код 0х00 в шестнадцатеричной системе счисления (почему шестнадцатеричная система?, да потому что так компактнее обозначать двоичные данные (т.к. в шестнадцатеричной системе (надеюсь, всё-таки что ты не навёлся сюда, в противном случае ты, наверное, сейчас совсем охуеваешь) каждая цифра представляет 4 бита (2^4 = 16 (т.е. можно уместить алфавит в 16-ть цифр (0, 1, 2, 3, 4, 5, 6, 7 , 8, 9, A, B, C, D, E, F)), т.е. каждая цифра это полубайт (8 / 2 = 4)), следовательно, обозначения символов из таблицы ASCII в шестнадцатеричной системе занимают всего два символа (надеюсь, что всё-таки ты не навёлся...) заместо 8 в двоичной, либо трёх в восьмеричной и десятичной))) на конце), которую преобразуют в число, исходя из следующего алгоритма: подсчитывают кол-во разрядов (т.е. количество символов в числе (например, в числе 45 - два символа ( 410^1 + 510^0), а в числе 456 - три символа ( 410^2 + 510^1 + 6*10^0))), это можно делать при вводе символов (надеюсь, что ты сюда всё-таки не навёлся, ибо, если ты навёлся и сейчас читаешь это, то ты совсем охуел, и мне тебя жаль) с клавиатуры, как бы организуя цикл, который работает до тех пор, пока, например, не введён символ 0x0A, который обозначает перевод строки; и до тех пор, пока не введён символ, обозначающий конец ввода, можно подсчитывать в переменной (обычно этот подсчёт идёт в регистре (обычно употребляется rcx)) кол-во разрядов; после чего из строки символов достаётся по одному символу (можно с начала, а можно с конца строки, это неважно (т.к. у нас есть инфа о кол-ве разрядов, следовательно, мы можем использовать её для организации цикла)), из которого вычитается код символа '0' (т.е. 0х30 (т.е. 48 в десятичной системе (т.е., так как коды символов цифр идут подряд, то, чтобы получить, допустим, 5, мы от кода символа '5' (0х35 (т.е. 53 в десятичной)) отнимаем код символа '0' (т.е. 0х30 (т.е. 48 в десятичной)), следовательно 53-48 = 5))) и разница умножается на 10-ку, степень которой соответствует данному разряду (допустим, исходя из того, какое значение в данный момент времени находится в rcx), а результат складывается в переменную (обычно это регистр rax (и естественно, что весь процесс происходит в двоичных числах)), который в данный момент времени обозначает число, которое ввёл юзверь. Можно также организовать схему Горнера (пикрил 1(она выполняется быстрее, потому что требует меньшее суммарное кол-во операций)), но от этого алгоритма ты можешь совсем-совсем охуеть, поэтому не стоит (я всё-таки надеюсь, что ты не навёлся на этот спойлер, поэтому ты это не читаешь и не охуеваешь). Также неважна система счисления, также неважно какое число ты вводишь - целое, или вещественное, ибо алгоритм тот же, только способ хранения (различные там стандарты IEEE 754, всякие там дополнительные коды (но это уже совсем для полнейшего охуевания (надеюсь ты это не читаешь))) отличается, но получение числа из массива чаров одно и то же.
После того, как мы получили число из массива чаров, процессор его схороняет в участке памяти, который ты выделил для хранения своей переменной в нужном формате.
Опять кучу бессмысленного текста зафигачили вместо ответа!
Задача такая. С помощью функции сканф я присваиваю какое то значение переменной
Если стоит спецификатор для типа данных int, значит и будет хранится она как int (вроде наверно, хз крч) то есть буквы и прочая шелуха тоже будет прочитана как int
Задача в том, что бы когда я вводил со своей шершавой клавиатуры, что угодно, кроме натурального числа, выскакивала ошибка и программа закрывалась. Для этого нужно что бы компьютер понял, что я ввел не натуральное число, но спецификатор любой символ сводит к какому то натуральному числу, так ведь?(его двоичному представлению) ПОЛУЧАЕТСЯ ЗАМКНУТЫЙ КРУГ
Ну тогда тебе нужно читать не инт, через спецификатор %d, а строку (%s) и проверять её:
Если в строке есть символы, которые не из диапазона 48-57 (т.е. '0' - '9', кроме символа ноль (но это должно быть условие проверки в цикле - закончилась строка или нет), т.е., если по ходу цикла выполняется условие:
if (str < 48 || str > 57), то break с ошибкой.
Правильно ли я понимаю, что тут сначала происходит возвращение элемента из массива buff по индексу bufp, а потом индекс bufp уменьшается на единицу?
>Правильно ли я понимаю
Нет, не правильно! Он первым делом уменьшает bufp, а потом делает ретёрн. Также, если сделать bufp--, только в этом случае, он сначала кладёт значение bufp в один регистр, затем его же в другой регистр, уменьшает этот другой регистр и кладёт по адресу bufp, но все операции, которые предшествуют новому изменению bufp, он проводит с тем регистром, в который он первым положил bufp. Но возврат из функции будет произведён, что в постфиксной, что в префиксной форме, с уменьшенным значением bufp, т.е., он тебе вернёт то значение, которое располагается в массиве buf на одну "клетку" ближе к началу массива.
это разное, погугли
Что значит одно и тоже? Я же написал в чём разница!
Ещё раз, в цикле это хорошо видно!
Вот, глянь на пикрил 2, вот тут хорошо видна разница. Результат это пикрил 3. А пикрил 1 это то, что происходит! То, что я выделил на пикрил 1 это ключевая! разница между префиксной формой и постфиксной. В первом цикле видно, что мы сначала прыгаем jmp на инструкцию, которая прибавляет по адресу переменной i единицу, а потом сразу же идёт сравнение этой переменной с 4, и, если меньше или равно, то прыгаем jle в ту часть кода, где идёт вызов ф-ции printf.
Во втором цикле видно, что мы сначала прыгаем на инструкцию, которая сохраняет значение переменной в регистре eax, после чего в edx помещаем значение, которое равно значению в eax, но увеличенное на 1, после чего значение из edx сохраняем по адресу переменной, и уже после этого сравниваем значение в eax с 4, и, если меньше или равно, то печатаем.
Разница в том, что, если используем ++i, то вся "работа" (арифметические действия, логические действия, и так далее) происходит с уже увеличенным значением переменной i на единицу, тогда, как в случае i++ вся работа происходит с, как бы, предыдущим значением переменной i. Если конечно предполагается какая-либо работа, допустим, есть наличие цикла. Но, если ф-ции нужно вернуть значение, то, как бы, сама инструкция ретёрн предполагает, что "работа" окончена и нужно вернуть конечный результат.
я чёт подзаёбся это объяснять! надо эту инфу со скринами сразу в шапку треда кидать.
Как сделать, чтобы сканфнутое значение в свиче срабатывало только на один "правильный" символ, а не на кашу после первого правильного? Если я введу Y123huy, то он пустит в case 'Y', а мне надо, чтобы в default.
Ну то есть, поменять местами принтф и ретёрн.
https://elixir.bootlin.com/linux/latest/source
Да! Без асма сложно. Асм позволяет дизассемблить любые ф-ции на Си, и смотреть, что в них происходит.
типа если у меня процессор такой то и такой то модели, надо учить ассемблер именно для этой модели?
Это тут причём? Конечно, нужно учитывать архитектуру, если ты кодишь на асме какие-нибудь системные штуки, но тебе это не нужно на первых порах изучения Си. Загугли что такое дизассемблировани, и тогда ты поймёшь для чего желательно изучать ассемблер, чтобы проще было освоить базу Си.
анон я макак, в регистрах не шарю, то есть в более смузихлёбских языках это аналоuг цилка repeat {} while ?
Которые просто переиначены на свой лад в каждом языке программирования?
Ну получается, что, если оно в условии цикла, то работает оно, как цикл с постусловием. Но, если тебе нужен именно цикл с постусловием, то лучше применять do{}while(условие), чтобы указать, что тут нужен именно этот вариант.
>>2942624
Гугли что такое машинное слово. Тут именно этот контекст.
А вообще, лучше чекни ещё из чего состоит, допустим, регистр rax.
> Карочи оператор switch ето говно. Он проверяет только первый символ
С подключением. Ты с нуля вкатываешься или с другого языка пришёл?
Я только на Си
Да, так и есть! Только учти, что в асме dw, dd, dq, что в Си short, int, long, long long соответствуют отталкиваются не о разрядности, а от совместимости, поэтому dw (как бы word) это не 64 бита в архитектуре х86-64, а всего 16 бит. Также и в Си int необязательно должен соответствовать 64-м битам - всё зависит от компилятора. Но корни растут именно от машинного слова. Так что тут проще сайзоффать в Си, а на асме знать разрядность проца и особенности архитектуры.
Чел, у тебя указатель на переменную и сама переменная, как это может быть одно и тоже? После компиляции указатель будет указывать на ту область памяти, в которой хранится переменная, и, естественно, если ты изменишь переменную, а после разыменовав указатель, то ты увидишь изменённое значение переменной.
sizeof( unsigned short ) равен 2, а sizeof( int ) равен 4 ;
gcc -ansi -Wall .
сурс:
int main(void) {
unsigned short var = 257;
return (int)var;
}
Почему выполнение этой программы завершается с кодом 1, а не с кодом 257?
Вот этот человек говорит что не все указатели можно друг с другом сравнивать
Но как я понял из другого видео, указатели - это просто какие то целые числа, показыавающие адрес переменной. Так почему нельзя сравнивать целые числа?
Выслал тебе подарочек по почте, прими, тварь!
типа зачем создавать указатели для переменных, если можно сразу обращатся к переменным
Кстати, если var сделаешь 258, то прога вернёт 2. Подсказку тебе дал, поэтому думай.
>>2946467
Ну можно исходить из того, что в Си очень часто приходиться использовать функции, если это не учебная прога, то ф-ции мастхэв. Также надо исходить из того, что в Си массивы/строки/структуры это тупо непрерывный участок памяти с N ячеек, устроенный определённым способом, который имеет определённый "вес" в байтах. Допустим, что у тебя есть целочисленный массив (int) размером в 1000 ячеек, каждая ячейка в этом массиве весит 4 байта, следовательно весь массив весит 4к байт. Теперь, представь, что тебе нужно передать этот массив в ф-цию, это получается получается, что тебе нужно копернуть 4к байт в отдельную копию, т.к. в Си при передачи аргументов в ф-цию создаётся копия значений каждого аргумента ф-ции. Поэтому в ф-цию тупо передаётся указатель на массив, который весит не больше 8 байт, в зависимости от системы. Во-вторых, если тебе нужно менять значение какой-либо переменной в ф-ции, то передав эту переменную в кач-ве аргумента, эта ф-ция не изменит значение этой переменной, потому что у ф-ции копия значения этого аргумента. Поэтому в ф-цию передают указатель на эту переменную, чтобы ф-ция могла бы "напрямую" работать с переменной. В-третьих, указатели позволяют строить сложные структуры данных, типа как массив структур, либо связные списки, деревья различные и т.д.
Есть хорошие видосы в ютубе, которые помогают понять, что такое указатели. Без понимая этого фундамента невозможно понять что-либо, что чуть сложнее задачек в пределах main(). Это мастхэв!!!
>если var сделаешь 258, то прога вернёт 2
Выяснил это до того, как запостить свой первоначальный вопрос.
Благодарю за отклик.
Самому трудно понять, что на самом деле происходит.
Гугление не помогло.
Пока самостоятельно выяснил, что преобразование типов осуществляется без ошибок.
Проверял такое: int main() { return 257; } И int main() { return -1; }
После этих проверок могу лишь предполагать, что та функция, обёрткой которой main() является, возвращает значения типа unsigned char.
Не знаю, верно ли это предположение. А если оно верно, то непонятно, почему так сделано.
все чем ты можешь помочь людям
Гугли исходник _exit
а я сам хочу
Если что, пишу под микроконтроллер.
То что в программах под микроконтроллер лучше не юзать динамическую память знаю и без вас.
Возьми указатель и посмотри.
memset(structpointer, 0, sizeof(structtype));
Допустим, у меня есть массив указателей на функции, и мне нужно каждую из них заменить функцией-обёрткой, которая совершает какое-то действие и только после вызывает оригинальную функцию. Не приходит в голову, как в скоупе функции-обёртки получить адрес функции, которую нужно вызвать. Возможно потому что это просто невозможно.
При этом я ограничен тем, как сторонняя библиотека вызывает эти функции, то есть я не могу, например, сделать как здесь
https://stackoverflow.com/questions/63395637/get-address-of-a-function-inside-of-the-function-in-c-c
Пример того, как это не может выглядеть:
https://pastebin.com/MzrnZq6t
Я только вкатываюсь в Си. Перекачу не так - будут недовольные.
Неужели для каждого типа массива свою функцию делать или есть более интересный способ?
https://ideone.com/MVBCIv
Вопрос такой: на чем основан gtk+?
Поверх какой библиотеки работает это?
За счёт чего делается графика?
Помогите перейти на более низкий уровень в си в области графики.
Всё должно нормально считать. Ты на компе у себя запускаешь или через форму эту? Может они \n хотят после суммы?
Строки 3-5 нужно раскомментировать
А в каком вузе это?
{
int i = -1;
while (hstr[++i] != '\0')
;
int decimal = 0;
int power = 0;
while (hstr[--i] != 'x')
{
const char c = hstr;
if (!(c >= '0' && c <= '9' || c >= 'a' && c <= 'f'))
return 0;
int number;
if (c >= 'a' && c <= 'f')
number = (c - 'a') + 10;
else
number = c - '0';
decimal += number pow(16, power);
power++;
}
return decimal;
}
Капец меня упражнение в K&R приложило. Это и есть ваш си блять?
{
int i = -1;
while (hstr[++i] != '\0')
;
int decimal = 0;
int power = 0;
while (hstr[--i] != 'x')
{
const char c = hstr;
if (!(c >= '0' && c <= '9' || c >= 'a' && c <= 'f'))
return 0;
int number;
if (c >= 'a' && c <= 'f')
number = (c - 'a') + 10;
else
number = c - '0';
decimal += number pow(16, power);
power++;
}
return decimal;
}
Капец меня упражнение в K&R приложило. Это и есть ваш си блять?
Ну. Допустим.
struct event {
eventSource* source;
}
struct eventSource{
int published;
event publishedEvents[1024];
}
Я хочу, чтобы структура event знала кто ее опубликовал, и чтобы эвентсорс - знал какие эвенты он опубликовал и сколько сейчас там эвентов.
Вот как мне такого добиться?
Просто сколько гуглю, везде с простыми примерами типа точка, имя-фамилия. Открыл K&R - там еще ноды показали, но все равно вот такой вот фигни, когда две структуры друг про друга знают - не вижу. Но ведь не может быть что это такой уж редкий пример и никто такого не использует.
Упражнение 2.3
Программирую в кодблокс, заметил две странности, во первых, после завершеия программы, консоль не закрывается автоматически (недавно узнал, что по идее она должна закрываться). Во вторых, работают функции, которые не должны работать без подключения библиотек (например getch() работает без conio)
Это какие то правки компилятора?
Всем добра!
Пишу в этот тред, так как более подходящего не нашел, скорее вопрос по ОС.
В общем ситуация следующая:
- есть пачка работающих процессов бд написанных на С (postgres) около 3-4к
- есть 64 GB ram и 4 swap
- ось redhat8, виртуалка wmvare
При выставлении overcommit_memory в 2 и overcommit_ratio в 95 - процессы при суммарной аллокации в примерно 66 GB начинают ожидаемо падать - при попытке аллоцировать новые куски с ошибкой couldn't allocate memory.
Далее фокус: при выставлении overcommit_memory в 0 - для того чтобы позволить overcommit и в надежде словить oom_killer, процессы чудесным образом перестают запрашивать 66GB и их аллокация держится в районе 61-62 GB
Могут ли быть какие-то причины еще, помимо логики кода, для такого поведения. В самом коде явных отсылок к overcommit_memory не нашел и логике основанной на нем не нашел. Но смотрел не глубоко.
Речь идет о значениях commited_as из /proc/meminfo
Резидентной памяти не касаемся, ее утилизация не доходит и до половины имеющегося объема
>Paul Deitel, Harvey Deitel
Кто-нибудь изучал по их книгам С? годнота или нет? Нужны отзвывы
Мммм авторвы которые хуячат книги по всем языкам программирования. Лучше сололеарн пробеги для начала
Нормальный будет вопрос, если разберёмся с понятиями. Что значит структура "знает" о другой структуре?
Если eventSource "публикует" новый event, то он будет содержаться в event.source? Если event опубликован, он будет добавлен в eventSource.publishedEvents, а eventSource.published будет увеличен на 1? Ну так это же тривиально: ты в любом случае будешь определять функции для работы с твоими структурами, например event_set_source(event, eventSource) и publish_event(eventSource, event). В одной ты присвоишь значение полю event.source, в другой добавишь event в eventSource.publishedEvents, заинкрементишь eventSource.published и вызовешь event_set_source(event, eventSource).
> Нормальный будет вопрос, если разберёмся с понятиями. Что значит структура "знает" о другой структуре?
Ну. То и значит.
Опять же, другой пример:
struct Employe {
struct Departament* departament
...
}
struct Departament {
struct Employe employees[1024]
...
}
Если я вот так вот напишу - мне компилятор ругается, что не знает никакого департамента. Поменяю местами - не знает никаких работников. Как мне написать, я так и не понял. Я так понимаю, надо как-то сначала определить имена для этих структур, а дальше где-то уже описать как эти структуры собственно выглядят. Но примеров такого не нашел. Или так вообще нельзя в Си? Ну, если нельзя, то как делать, кроме как указателем на void - не знаю.
А, вот ты о чём.
Да, тебе нужно задекларировать Department перед определением другой структуры, которая содержит поле типа Department, который ещё не определён.
struct Department;
struct Employe {
__struct Departament* departament;
__...
}
struct Departament {
__struct Employe employees[1024];
__...
}
Я прочел. Но все книги хуита. Там просто разбирают по частям циклы, структуры и либы. А прогать не учат.
просто пишешь код, открывай кернел модули в си и пытайся понять.
https://en.wikipedia.org/wiki/ASCII#Bit_width
The committee considered an eight-bit code, since eight bits (octets) would allow two four-bit patterns to efficiently encode two digits with binary-coded decimal. However, it would require all data transmission to send eight bits when seven could suffice. The committee voted to use a seven-bit code to minimize costs associated with data transmission. Since perforated tape at the time could record eight bits in one position, it also allowed for a parity bit for error checking if desired.[3]:217 §c,236 §5 Eight-bit machines (with octets as the native data type) that did not use parity checking typically set the eighth bit to 0.[30]
если поменять \n в if Letter == '\n' на 13, то она перенесётся, а так нет
Скорее всего задействуется виндовая последовательность символов переноса строки \r\n, а не просто линуксовая \n
действительно, через \r сработало
а \n получается попадает в буфер после считывания \r и ждёт там?
Чтобы узнать, попробуй очистить буфер чтением из него (поставь до или после вызова getche):
while((Letter = getchar()) != '\n' && Letter != EOF);
Не забудь про ; в конце while т.к. цикл пустой.
640x360, 0:08
А прикольно, что мы до сих пор с ней носимся. _)
Потому что ascii
Ну для линукса всякие QT, GTK и прочее это обёртка над X11 или Wayland
Те в свою (вроде) уже оборачивают собой все возможные драйвера под различные видеокарты
А дальше уже железо начинается
0xC0000005 это код ошибки, а именно access violation. Я хз, как в винде память устроена, но по адресу 0x5 ничего доступного твоему приложению точно не может лежать.
порядок выполнения постфиксного инкремента больше чем у разыменования
Заметил, что у многих системных программ та же история.
Конечно за исключением если их специально не скомпилили через gcc -s или не обработать через strip.
Я classical web monkey. Хотел перейти на что-то серьезное. Аноны с треда про раст кинули в си, сказали для начала нужно начать с этого. Сколько месяцев нужно, чтобы отдуплить за идею си Разбираться, понимать.
Вводные:
У меня нет никакого понимаю о низкоуровневом программирование.
Честно говоря, я не совсем понимаю для чего мне понадобится си. Наверное, мозг засорен высокоуровневым программированием. Думаю, в процессе написать какой-нибудь пет проект, куда войдут все изученные темы.
Да ни для чего.
Придется тебе придумывать свои охуительные обучающие идеи.
Благо в старых книжка по Си таких было куча.
Разумеется, в серьезных проектах нужны программисты,но ты просто не поймешь эти программы из-за высокой сложности не связанной непосредственно с Си, а просто созданной из-за сути задачи
>что-то серьезное
С Паскаля тогда начни.
>Честно говоря, я не совсем понимаю для чего мне понадобится си
Тогда тебе си точно не нужен.
>Аноны с треда про раст
Раст проще си.
Это копия, сохраненная 22 января в 01:27.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.