Это копия, сохраненная 18 января 2020 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
Пожалуйста, пользуйтесь https://ideone.com/ или https://pastebin.com/ для вставки кода, если он длиной больше нескольких строк или содержит [i] или ∗.
Что читать:
- Brian Kernighan, Dennis Ritchie "The C Programming Language": http://www.cypress.com/file/56651/download
- Stephen Prata "C Primer Plus, 6th Edition" (2014): относительно свежая, знает про C89/C99/C11, описывает различия, объемная (около тысячи страниц), годная, с вопросами, упражнениями и ответами. Читать после K&R или до.
- Zed A. Shaw "Learn C the Hard Way" (2015): годное пособие для гуманитариев для гуманитариев!
- Немного примеров хорошего стиля: http://www.oualline.com/books.free/style/index.html
- ООП, например: http://www.cs.rit.edu/~ats/books/ooc.pdf
- Стандарт ISO/IEC 9899:1999 (C99): http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf (драфт)
- Стандарт ISO/IEC 9899:2011 (C11): http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf (драфт)
- Черновик стандарта ISO/IEC 9899:202x (C2x): http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2385.pdf
- man/Dash/zealdocs
Чем компилировать:
- Очевидный GCC.
- clang: оче годно, батя рекомендует.
- Intel C++ Compiler: оптимизации, тысячи их.
- Visual Studio 2017 Community Edition: внезапно этим стало можно пользоваться, особенно с тулсетом clang/C2. Поддержка C11 на уровне "есть все, что тебе понадобится в реальном проекте плюс кривая библиотека". Анализатор кода в комплекте.
- Pelles C (шиндоуз онли): поучиться, вкатиться в C11 (стандарт полностью реализован, имеются в том числе threads.h и прочие stdatomic.h), но количество багов в оптимизаторе и редкие апдейты напрочь отбивают желание собирать этим что-то сколько-нибудь серьезное.
- TCC: очень маленький компилятор с багами и поддержкой C99. С ключом -run умеет компилировать код в память и запускать его, что позволяет писать скрипты прямо на сишечке.
Что еще почитать:
http://c-faq.com/
FAQ из comp.lang.c. Древний, но все еще актуален.
Samuel P. Harbison, Guy L. Steele Jr. "C: A Reference Manual, 5th Edition" (2002)
Ебаный пересказ стандартов C89 и C99 (включая стандартную библиотеку). Для не осиливающих стандарт в оригинале. Читать в качестве подготовки к собеседованиям (есть задачник с ответами) и для ознакомления с масштабами пиздеца перед написанием своего парсера/компилера.
Peter Van Der Linden "Expert C Programming. Deep C Secrets" (1994)
"Си: грязные истории". Смехуечки, немного объяснений, чем обусловлены особенности языка, всем известные подводные камни кто там ругал косяки в JS? у нас в сишечке их гораздо больше, просто они лучше спрятаны, немного байтоебли и непонятно откуда взявшаяся глава про старинные плюсы. Читать в качестве сказки на ночь (на пару вечеров хватит).
Richard M. Reese "Understanding and Using C Pointers. Core Techniques for Memory Management" (2013) - почитать, вкатиться в указатели.
Ben Klemens "21st Century C: C Tips from the New School" (2012)
Paul Deitel, Harvey Deitel "C for Programmers with an Introduction to C11" (2013)
Stephen G. Koch@n "Programming in C (3rd Edition или 4th Edition, если найдется)" (2014)
MISRA Ltd. "Guidelines for the Use of the C Language in Critical Systems" (2013)
Набор рекомендаций по написанию надежного кода на C (промышленный стандарт). Читать - однозначно, следовать - вдумчиво и без фанатизма. Также можно посмотреть https://www.securecoding.cert.org/confluence/display/c/SEI+CERT+C+Coding+Standard и http://web.archive.org/web/20190213011655/homepages.inf.ed.ac.uk/dts/pm/Papers/nasa-c-style.pdf
Еще более длинный список: http://www.iso-9899.info/wiki/Books#Learning_C
Онлайн-утилиты:
- https://godbolt.org/ - Compiler Explorer позволяет посмотреть выхлоп компиляторов для введенного куска кода (больше полусотни разных версий компиляторов).
- http://cdecl.org/ - С Gibberish ↔ English помогает читать сложные сишные декларации.
Прошлые треды:
- №47: http://arhivach.ng/thread/475391/
- №48: http://arhivach.ng/thread/495505/
- №49: http://arhivach.ng/thread/496205/ >>1500890 (OP)
Нужно сохранить файл.
Так вот, он сохраняется куда-то в "С:\Documents and Settings\User\Application Data\proga\file.ololo"
А надо его сохранить рядом с папкой, откуда exe запускается.
Так вот, вопрос: как из строки С:\Documents and Settings\User\Application Data\proga\file.ololo получить file.ololo
и как правильно его сохранить так, чтобы путь указать относительный, и относительно папки с программой?
Путь содержится в переменной static char Жpath, где вместо Ж - звёздочка, от которой разметка здесь едет.
>Так вот, он сохраняется куда-то
Так вот, ты программист или не туда зашел петушок? Файлы не сохраняются сами куда-то, они сохраняются куда ты написал сохраняться.
Я спросил о том, как из полного пути в переменной
>const char ☀path = "С:\Documents and Settings\User\Application Data\proga\file.ololo получить file.ololo";
извлечь только имя файла
>char ☀name = "file.ololo";
Ну и как правильно сохранить этот file.ololo в папку, рядом с exe-шником.
То есть, какой путь относительный должен быть у файла?
Ну, там "./file.ololo", или "/file.ololo" или же просто "file.ololo", чтобы оно сохранилось и не выёбывалось мне больше.
Я только вкатился в этот говнокод. Трудно разобраться что к чему там.
Там столько всего изменили - пиздец просто. Нихуя не пашет и крашится.
Вот здесь где-то ошибку бьёт: https://github.com/uTox/uTox/blob/37dba1af57b0b615abd1c649ba551b21e796a9d0/src/windows/filesys.c#L95
И прога закрывается нахуй, засирая дебаггер.
Оно пытается лезть в "С:\Documents and Settings\User\Application Data\Tox\" какого-то хуя.
В то время как предыдущие версии были portable.
https://pastebin.com/9itmEmmz
Правильно лия понимаю что чтобы строки всегда хранятся в переменных под названием "буфер" на топ уровнях? А так же в одном буфере могут лежать разные типы?
>Почему эта адская херня компилится, как вы вообще живете сишники?
Ну так это же не жс, а прокладка над ассемблером, понятное дело что тебя в написании подобной хуйни никто не ограничивает.
>Правильно лия понимаю что чтобы строки всегда хранятся в переменных
Да в каких хочешь храни, лол, нет.
>на топ уровнях
В скомпилированном бинарнике конечно в отдельную секцию вынесутся компилятором, но в коде — нет.
>А так же в одном буфере могут лежать разные типы?
Да, вопрос только в том как ты эти типы интерпретировать будешь. Си вообще похуй на подобные вещи, это же ебучий кроссплатформенный ассемблер, для него это всё байтики.
И именно на подобной хуйне, кстати, базируется 80% "сливательных" уязвимостей и просто эксплойтов всего, что торчит в сеть (если например запихать туда снаружи нужное кол-во мусора, то можно получить доступ ко всем внутренним данным, или просто внедритьсвой код). Так что ты теперь у мамки хацкер, поздравляю.
union ieee754dp {
struct {
__BITFIELD_FIELD(unsigned int sign:1,
__BITFIELD_FIELD(unsigned int bexp:11,
__BITFIELD_FIELD(u64 mant:52,
;)))
};
u64 bits;
};
помимо вариадиков, при помощи union ты можешь для одного и того же куска памяти иметь разные представления
к, примеру, можно (зная платформу) разобрать вещественное число на мантиссу-экспоненту или как оно там будет представляться
или к примеру, представить 64 разрядное целое как 2 32х разрядных
или представить пакет в бинарном протоколе как целый кусок памяти или как набор полей
или представить битовое поле как целый набор битов, так и как набор битовых полей
ну, в общем, наверное, уже понял, все такие применения (помимо эмуляции variant)
> извлечь только имя файла
strrchr('\\'), strrchr('/'), выбираешь тот, у которого адрес больше, прибавляешь 1. Если оба NULL, то у тебя уже имя файла без директорий. Можешь сделать то же самое циклом, будет быстрее.
>>19509
А в чем проблема реализовать? Просто переменные жирные получатся.
>>19559
> зная платформу
> представить битовое поле как целый набор битов
И потом начинаются всякие -mms-bitfields. Нахуй. Если ты начал полагаться на то, как именно лежат биты в битфилде - у тебя уже проблема, просто ты о ней еще не знаешь.
> представить пакет в бинарном протоколе как целый кусок памяти
А потом ты такой портируешь свой код на мк (сейчас это модно, IoT всякие), а там выравнивание другое сказал бы про endianess, но PowerPC успешно сдох, и эта проблема уже не так актуальна. Пакеты парсят/собирают исключительно struct.field = get_u32() (руками, наколеночной кодогенерацией или какими-нибудь протобуферами). Если ты делаешь не так, у тебя опять же проблема, об которую ты однажды споткнешься.
Поэтому union - это такая хуйня для экономии памяти, не более. Ну еще можно сжав зубы иногда делать type punning (хотя проще -fno-strict-aliasing и скастить кастом).
>А в чем проблема реализовать? Просто переменные жирные получатся.
Ни в чём, можно даже и без жирных переменных. Просто получится хуйня на постном масле вместо встроенной в язык конструкции.
>А потом ты такой портируешь свой код на мк
Михалыч, ну не хватает мужыкам на заводе работы, ну хуле ты докопался?
> ну хуле ты докопался?
Потому что мне недавно дали вот такое:
struct smth {
...
union {
long xxx_offset_in_file; // Лежит в файле.
struct something_else ∗xxx_ptr; // Патчится при загрузке.
} some_field;
...;
};
Эта хуйня записана в файлы (тупо fwrite), формат файлов ломать нельзя, файлы обрабатываются софтом, а софт надо собрать под 64-битную машину (ну 2019 на дворе, пора бы уже). А еще эти юнионы не выровнены. Представляешь, как весело править это говно?
А что плохого-то? Считай что создали тебе фронт работы, лол.
у тебя пожатые структуры будут, без выравнивания..
которые ты будешь на сетевой пакет накладывать..
>Если ты начал полагаться на то, как именно лежат биты в битфилде
для внутреннего представления в программе - норм
понятно что наружу это не должно торчать
>union - это такая хуйня для экономии памяти
это стандартная ошибка, считать что union для экономии памяти
не для экономии, а для того чтобы представлять один кусок памяти разными способами
> у тебя пожатые структуры будут, без выравнивания
Именно. А потом я их читаю там, где выравнивание обязательное, и ко мне приезжает автобус SIGBUS.
> надо 79
Ты к нам из 79?
> как форматировать ваши ебаные реаллоки
Считай размер заранее, переноси аргументы в соответствии со стайлгайдом (обычно после переноса либо просто втыкают дополнительный уровень табуляции, либо располагают аргументы ровно под предыдущими).
>79
Удобно же. Можно лампово кодить в текстовом режиме 720x400 на ЭЛТ.
>Считай размер заранее
Точно! Как только не пробовал, а эта святая простота в голову не пришла.
https://pastebin.com/K1E1VmxT
Пользуйтесь. За три бакса могу сделать, чтоб PQpop реаллокал обратно.
> За три бакса могу сделать
Проиграл. Типичный сишник с десятью годами опыта ищет работу в реалиях 2020. Выживаете, дедушка?
https://github.com/PolazhinetsA/algo/tree/master/huffman
inb4 зачем принес?
- лучше спится после ночного бампа
всем ночникам лампового настроения и... >>18953
мимо присоединяюсь к пожеланиям
>увеличивает размер
>не восстанавливает исходные данные
ну чисто анекдот про советскую программу для lossless-сжатия
Невозможно с первого раза правильно написать хафмана. Смирись.
Впрочем, я посмотрел и слегка охуел:
> rewind(fsrc);
> huffman_encode(stdout, stdin);
> rewind
> stdin
Впрочем, я посмотрел еще.
> невозможно с первого раза правильно написать хафмана
Знаешь, чем linked list от дерева отличается? И как это связано с тем, что выхлоп вот этой маленькой, но очень известной программы сжимается неверно, даже если исправить предыдущую проблему?
#include <stdio.h>
int main(void){int a=0,b=1,n,i;for(i=34;i--;){n=a+b;a=b;b=n;while(n--)putchar('Q'-i);}}
Аноны, подскажите по вопросу.
Как правильно делать проверку переменной на превышение ее максимального значения.
Например длинну массива или некий счетчик.
Я всегда пишу <= >= < >
Но часто в другом коде встречаю ==
И решил задуматься почему.
Мой вариант позволяет в некоторых ситуациях программе нормализоваться после сбоя и или будет иметь повторяемое поведение.
С другой стороны, теоретически существуют ошибки, которые могут остаться незамеченными и их отлов будет пиздецовым гемороем.
В то же время срыв == ведет к UB и с одной стороны максимизирует ошибку, с другой дебаг подобной херни может тоже быть проблемным.
Как правильно то?
так, эта штука пишет символы от '0' до 'Q':
'0' - fibonacci1 раз
'1' - fibonacci2 раз
и т.д.
С таким распределением получается
0
01
001
0001
00001
000001
...
Ладно, в худшем случае придется за раз класть больше 32 бит. Я предусмотрел 64, но надо бы 256. Фиксится как нефиг делать, и у меня другая проблема. Делал пресловутый дебаг принтфом, чтоб посмотреть, какие самые длинные коды получались (52). И почему именно первые 50000 байтов из Мартина Идена оно восстанавливает нормально, а если взять 100000 - то пиздос?
Да лень было test.c красиво писать. Да, кто-то может не знать, не повесить какой-то файл на дескриптор и попробовать закодировать с клавиатуры.
бляяяяяяя, я забыл суммировать веса дочерних узлов))))
>софт надо собрать под 64-битную машину (ну 2019 на дворе, пора бы уже)
Это не причина, а долбоебизм и вредительство - ломание работающего без причин и имитация деятельности этим якобы переписыванием.
Под 32 бита все прекрасно компилилось и работало, а под 64 - хуй!
бля, я долбоеб по ходу
Все таки тихий час - чудодейственная мера. Там ведь библиотека только в собранном виде уже, а я когда инструментами 2008-й студии компилировал и линковал с ней, все было норм, но на 10-ке работало только в режиме совместимости (оно winsock юзает), и я в ответ на эту жалобу от пользователя решил поступить радикально, поставил на ноут 10-ку, инструменты сборки от новой студии и прописал путь к компилятору с целевой архитектурой x64. Пиздос. А ведь между XP и x64 огромная пропасть, в которой еще ой как много места для x32. Пиздос я кретин, только сейчас это осознал. Всем добра.
> для него это всё байтики.
То есть char это основная единица в C? Но ведь существуют только 256 битовых масок для одного байта, то есть можно получить всего ничего букв. А где в комплюктере можно поглядеть какой букве какое число соответсвует? То есть если инт состоит из 4 байт, а в байте у нас три десятичных разряда, то в инте 3x4 десятичных разряда, то если
456 789 987 899 какой либо инт,
из него можно выслюнить 4 char (456, 789, 987, 899) ?
> А где в комплюктере можно поглядеть какой букве какое число соответсвует?
Компьютеру по большей части похуй. Как запрограммируешь - так и будет. Где и как лежат кодовые таблицы - зависит от ОС. Но у нормальных людей уже юникод давно, юникод смотрят на unicode.org (если хватит усидчивости, чтобы продраться сквозь тысячи страниц стандарта).
> то в инте 3x4 десятичных разряда
Десятичные разряды неудобные, поэтому 32-битный int представляют как 4 char (даже в сишке есть распространенное расширение под это: char c = 'A'; unsigned int x = 'ABCD').
c = getchar ();
//
//
которое всё в ассемблер переделает или что?
Думаю, без расширения можно:
int64_t istr = ∗(const int64_t ∗)"pidoras";
И потом передавать куда угодно без всяких выстрелов в ногу и медленных копирований. А распечатывать так:
puts((const char ∗)&istr);
Хотя с короткими строками один хрен быстрее поразрядная сортировка подсчетом, а не дженерик хуита с operator<...
Зато кто-то посмотрит в твои строки, а там "DCBAHGFEQLKJI...". Это само по себе немного круто.
Намного лучше. Хотя бы тем, что любые архивы не из DOS поддерживают юникод, то есть все. А zip всё еще какашка, корраптящая имена файлов. И это в 2020 году, пиздец, интернету уже 20 лет, а zip всё еще говно говна из каменного века. Да, я знаю что теперь пропатчили, но уже поздно, слишком поздно, мир засран кривым zip дерьмом так что уже не вычистишь.
При чем тут я? Ты качаешь из интернета rar и ты уверен что с ним всё в порядке. Ты качаешь zip и нет никаких гарантий что файлы там не попорчены, это русская рулетка. Zip зашкварен, им попросту нельзя пользоваться, т.к. нет никаких гарантий что все пользуются правильной его версией с правильными флагами.
int main() {
const char suit[4] = { "Hearts", "Diamonds", "Clubs", "Spades" };
printf ("suit[2]= %s\n", suit[2]);
printf ("suit= %s\n", *suit);
return 0;
}
Подскажи почему printf ("suit= %s\n", suit);
printf ("&suit= %s\n", &suit); эти двестроки не выводят ничего.
Ап, вы охуели, не отвечать.
спасибо, я уже вкурил
тк переменная обьявлялась как static в хеадере, то каждый исходник, импортирующий его имел собственную его копию с одним именем.
теперь мне интересен вопрос по поводу возвращаемых данных, удобно чекать успешность выполнения через логику, те возвращать какой-либо значение отличное от null и 0. то что main() возвращает ноль - так сложилось исторически?
Есть тут си-синьоры? Смотрите какая вакансия: офис в Черногории, 10 минут от пляжа, зп 3к$ в месяц.
https://moikrug.ru/vacancies/1000054559
Что ты имеешь ввиду? Я к тому что массив чаров это одна строка, он же пытается сделать массив массивов. как то можно это сделать таким образом?
Там звёздочка перед suit[4] , это пример массива указателей из Дейтелов. пробовал значение указателя получить.
Я хз как правильно и коротко вопрос сформулировать. Кинь ссылкой хотя бы.
Тому шо в char помещается цифоры от -127 до 127. Твоя тыща прогоняется по этому диапазону начиная с нуля и останавливается на -24.
Поскольку я на си вкатился со скриптовых языков, у меня в голове закрепилась привычка что рантайм в случае чего потом потычет в то место где что то не так. Когда особенно много изменений в код вношу и внезапно программа начинает падать, просто теряюсь, но помаленьку мне вносить изменения тоже некомфортно.
Можно ли какимнибудь дебагером эти драные нульпоинтеры отловить? Потому как остальное вроде как при компиляции отлавливается, особенно с -wall в llvm.
дели модули, пиши тесты
разрезай приложения на функционально отдельные части, для удобства контроля промежуточного состояния данных. ну и используй дебагер - все нормальные иде могут дебажить искоробки. если работаешь много с кучей - юзай valgrind
странный вопрос. начал изучение С лет 8 назад, за это время написал игру на спектрум (sdcc+asm), реверсить что-либо желание как не было так и не появилось.
Может быть дашь совет какой? Как вкатиться в низкоуровневое программирование? Нравится СИ, вот теперь пересматриваю главы КР 4, чтобы хорошо все запомнить про области видимости, связывание и т.д. (курс на степике прохожу). Куда дальше двигаться, какие проекты писать? Какие проекты на Си написать, чтобы так сказать, был норм уровень, и можно было переходить к ассемблеру?
>Поскольку я на си вкатился со скриптовых языков
В си надо вкатывать с архитектуры процессора и ассемблера.
Напиши кернел
https://pastebin.com/Ve1TnrFL
> В си надо вкатывать с архитектуры процессора и ассемблера.
Что бы уверенней использовать запрещенные стандартом языка приемы и завязываться на архитектурно зависимые хаки?
Может в каком то ограниченном и архитектурно-зависимом коде это и допустимо, но во всех остальных случаях я бы предложил всем таким людям питаться путем прокачивания еды через трубочку введенную в анальное отверстие, ведь та самая дырка, в отличии от первой которая загружена еще и дыханием, большую часть времени все равно тупо простаивает, а архитектура организма вполне позволяет ее задействовать для подкачивания питания в желудок параллельно.
> Может в каком то ограниченном и архитектурно-зависимом коде это и допустимо
Когда подрастешь, ты узнаешь, что весь сколько-нибудь сложный код на Си напрочь непереносим. В лучшем случае непереносимые части лежат в отдельной либе, но они обязательно есть.
Пушто CLANG конпелятора здорового человека, а не ваши эти GCC тьху блядь накатят и ябутся потом..
#ifdef YOBA_ALGO_CMP_1
inilne void yoba_algo_1(...) {...}
#endif
#ifdef YOBA_ALGO_CMP_2
inilne void yoba_algo_2(...) {...}
#endif
И так далее. Содержимое фигурных скобок идентично, тоже какими-то дефайнами можно его штамповать. Но это же лютая дичь.
Есть мысля, что для бытовых задач сойдет и производительность с вызовами функции, зато чистеньким интерфейсом, а для конкретных сложных высоконагруженных задач все вспомогательные структуры данных реализовывать эксклюзивно, монолитно с основным кодом, не претендуя на реюзабельность этой хуеты, абстрагированной математически, но не технически. Но ведь чувствуется, что вот она, заветная универсальность, всего-то пары синтаксических ништяков не хватает, эх... дискасс.
>для бытовых задач сойдет и производительность с вызовами функции
она всегда сойдёт. не знаю таких ситуаций когда CALL-RET был большой проблемой. на старых системах это ещё и выигрыш в размере кода.
ну, я бенчмаркал, норм так в пару раз скорость выросла, как захерачил инлайнами все
>на старых
Противоположность актуальных же. Где-то у Таненбаума читал, что узкие места смещается то в сторону гигагерцев, то в сторону гигабайтов. И вот в наше время предпочтительней загрузить память, которой жопой жуй, инлайнами и прочей векторизацией, чтоб процы, которые бедняжки уже давно уперлись в потолок по тактовой мощности, смог задействовать все свои альтернативные законы Мура вроде первых кешей, конвееров, хуееров и т.д.
>Сам прибегал к дефайну перед инклудом, типа макрос-обработчик, но это какая-то лютая дичь, к тому же в одном коде не получиться дважды с разными типами данных использовать
Самое адекватное. Смотри например gnu scientific library. И с типами спокойно используется.
//yoba.inc
inilne void yoba_algo_##YOBANUMBER_##YOBATYPE(...) { if (YOBAPREDICTATE) }
//yoba.h
#define YOBANUMBER 1
#define YOBANUMBER float
#define YOBAPREDICATE(a,b) ((a) < (b))
#include "yoba.inc"
#undef YOBAPREDICATE
#undef YOBATYPE
#undef YOBANUMBER
#define YOBANUMBER 2
#define YOBATYPE double
#define YOBAPREDICATE(a,b) ((a) > (b))
#include "yoba.inc"
#undef YOBAPREDICATE
#undef YOBATYPE
#undef YOBANUMBER
Еще лучше конечно взять С++
и что ты бенчмаркал? звучит как разница зависящая от компиляции и позиции солнца в системе - загрузки её другими процессами. давай конкретный воспроизводимый пример.
>>23025
но из этих кешей, чем меньше программа, тем реже тебя будут вытеснять другие программы системы.
хотя этот тезис я слышу давно, что больше писать давно выгодней. ну хз, я не упираюсь в своих задачах в это.
Меня трясет от новых стандартов с++, языков высокого уровня. Я чисто для себя, вот
Тебе шашечки или ехать? Меня вот тоже от с++ ажтрясет, особенно от его перегруженности. Я си ковыряю только для хобби поделок, тк что-то серьезное на нем не написать, а для решения личных нужд он не подходит - питон лучше. Если ты хочешь связать с этим свою профессию - дрочить Си тоже не вариант, рынок узкий, вакансий мало, а поработав с любым динамическим языком/удобным статическим (например go или шарп) ты поймешь что нюансы этих языков не значительны на фоне знания фреймворка, и зная один можно с минимальными усилиями перекатываться в другой. Так что просто определись что ты в итоге хочешь получить от языка и нужно ли тебе вкатываться в низкоуровщину или хватит просто тыкать ее палкой для петпроектов.
>давай конкретный воспроизводимый пример
Да мне уже неловко как-то свою хуиту светить.
https://github.com/PolazhinetsA/lzwarc
Короче, скармливаю этому говну 212-мебагабайтовую оффлайн версию HTML-справочника по стандартной библиотеке C++ (cppreference.com), оно сжимает до 75, и после того, как захерачил всю хеш-таблицу инлайнами, стало делать это не за 10 сек, а за 5. Вот прям стабильно.
>от позиции солнца в системе
Ровно первый раз. Потом все, что надо, уже в нужных кешах, и жесткий диск перестает быть узким местом.
и
char buf[100];
это абсолютно одно и тоже, да?
Нетъ
1 хранится в куче, 2 в стеке
const можно сбрасывать, если значение не optimized out
прикольно. только я пока не могу скомпилировать без ключа оптимизации. и у тебя варнингов столько, и это ещё без флагов. зачем ты ставишь перед аллоками конкретный тип, если присваиваешь другим типам? тогда уже присваивай к void@
>без -O3
Потому что я поскупился продублировать инлайны из htbl.h для линкера, а без оптимизаций конпелятор такие продвинутые пожелания не выполняет и херачит вызовы.
>каст маллоков
Где конкретно? В макросо-реализованных расширяемых структурах данных с заголовочными интами по отрицательным индексам - для арифметики указателей. Типа, выделил память начиная с этих интов, но взял указатель уже на однородный буфер, что парой слов дальше, ведь к элементам чаще обращаешься, чем к контрольным счетчикам.
Ну, я и не хотел их юзать, пока не попробовал и не увидел значительную разницу в скорости. Именно htbl прям стопицот раз/нсек дергается. Не критичные вещи там чистенько по-отдельности идут, с инкапсуляцией (typedef в .c, void в интерфейсе) - так, чтоб потом эти ништяки в любой другой проект стащить можно было.
> , а без оптимизаций конпелятор такие продвинутые пожелания не выполняет и херачит вызовы.
он вообще не соберёт проект. ты правила не знаешь, проставь везде static inline .
сегфаулт словил когда сжимал glext.h
lzwarc a ./tmp/arch.lzw ~/dwn/glext.h
компилировал на cygwin32.
./lzwarc x ./arch-inline.huff ./html_book-e.tar
а вот это выдало файл с названием html_book-e.tarhtml_book.tar
Неделю назад переписал на C++, но, не поверишь, только что, вот прям перед этим скрином психанул, взял и rm -rf cpp. Пофиг, она неактуальная была.
>>23833
Аа.. по скрину не понял, в чем прикол.
>>23834
htbl_init? Так там вместо каллбэков макросы перед инклудом. Лямбды через конструктор - на случай использования в менее замороченном и более красивом коде.
>./lzwarc x ./arch-inline.huff ./html_book-e.tar
>а вот это выдало файл с названием html_book-e.tarhtml_book.tar
А, ну все правильно, там задается папка назначения, а не имя выходного файла. Ведь файлов в архиве может быть много, они со своими именами распаковываются. А слитно, потому что путь назначением со слешем в конце писать надо. Да, у меня с автоматизацией всех этих пользовательских нюансов вообще тьма-тьмущая, даже вскрывать не стоит)
Там еще кое-какие пояснения в комментариях в arc.c - можно не разбираясь в коде все серое // глазами собрать.
да я тебе патч с тестом дам. хотя я уже вижу разницу всего в 114 на 101 секнд. щас сделаю сборку без каллбеков но и без инлайнов, и думаю, будет тоже что и с инлайном.
Думаю, с одним большим файлом не должно быть такой разницы, как с множеством маленьких, потому что словарь до 2^14 забивается и отпадают обращения к хеш-таблице по поводу добавления.
>Да, у меня с автоматизацией всех этих пользовательских нюансов вообще тьма-тьмущая, даже вскрывать не стоит)
Типичная олимпиадная пердоля. Даже с командной строкой обосрался сделать нормально, что уж говорить про графические интерфейсы. Вот почему линукс говно и останется говном вечно.
этот файл:
https://en.cppreference.com/w/File:html_book_20190607.zip
я его распаковал в ~/dwn/html_book/ и сделал ~/dwn/html_book.tar из содержания
в папке с проектом:
sh ./test.sh ~/dwn/html_book.tar
sh ./test.sh ~/dwn/html_book/
результат1 (cygwin32 на win7 ноуте с отвалом гпу. я плакал когда гонял на нём тест 3тий раз а он издавал истошный гул): https://pastebin.com/R90zydMM
результат2 (lubuntu32): https://pastebin.com/H5jwGHGj
патч: https://pastebin.com/a5cMBvS7
и того:
да хз. разница не значительна, как по мне. не понятно, будет ли она на больших числах увеличиваться. мне кажется тебе лучше задуматься, почему у тебя один файл кодируется в 2 раза дольше и сжимается в 2.5 хуже, чем сотни. я бы вообще не делал поддержку многофайловости - для этого есть tar.
Понимаю, что в Си нет конкретно понятия "модуль", но всё же хотелось бы понять с философской точки зрения структуру современного приложения на Си с высоты птичьего полёта. Как вообще в этом разобраться? Хотел скачать книжку Си в 21 веке на русском, но петухи поудаляли все ссылки с Вконтакта. Может есть у кого?
Есть ли какие-то принципы типа "Один .c файл - одна ответственность" для Си? Есть что-то типа SOLID для Си?
Посмотри эту
Посмотри, как большие опен-сорсные проекты устроены. Блендер, например, или старые версии инкскейпа (до портирования на кресты).
А у них есть какие-то документы описывающие архитектуру? Читать миллиарды кода не хочется, хочется взглянуть в целом, с высоты.
>А у них есть какие-то документы описывающие архитектуру? Читать миллиарды кода не хочется, хочется взглянуть в целом, с высоты.
Есть, но придется поискать по сайту. Плюс там обычно не вся архитектура, а какие-то отдельные куски. Да и код обычно не такой уж и сложный, можно за пару дней общее представление составить.
обайтоебливание bmp-картинок с ватермаркой "laba2_2019"
Работа с аудио и видео.
Работа со всяким компьютер виженом.
Низкоуровневая работа с сетью.
Создание утилит для Линукс.
Да ты ахуел такие вопросы задавать? М? :3
Хард реал тайм, где запрещено динамическое выделение памяти. Навигационное оборудование, управление всякими рулями и тормозами, искусственные водители ритма сердца, вощим все от чего зависит твоя жопа ирл.
Какой стек, там 99% переменных - глобальные. Тот еще говнокод по сути, но по другому нельзя.
Эскобар
Хуяуструп. Вы ошиблись тредом.
Такое легче в класс обернуть и все.
чтение K&R c выполнением всех упражнений, обязательно несколько раз перечитать приложение где описана спецификация языка
компонентно-ориентированное прогаммирование, работа через интерфейсы (com, gtk..)
а попробуй на крестах
там есть, к примеру, обобщенные лямбда-функции, которые инлайнятся (при включении оптимизирующих флагов компилятора, само собой)
вдобавок ты всегда это сможешь контролировать просматривая ассемблерный листинг (даже онлайн godbolt)
да и обобщенный код приятней писать на шаблонах, чем на макросах
но я не настаиваю, и не ради холивара это написал
>патч
Ой, чувствую себя обезьяной. Я и свое-то добро заливаю через кнопку upload, потому что github перестал водить за руку, что в консольке прописать, при создании репозитория. А это вообще хз, как юзать.
>задуматься
Потому что в разных файлах разнохарактерные данные, а я сброс зажравшегося словаря поленился сделать. Файлы, уже сжатые более совершенным алгоритмом, даже больше становятся после LZW, но когда их отдельно прогоняешь, архиватор видит невыгодную разницу и оставляет исходный.
>для этого есть tar
Дык мне интересно все в комплексе пилить. Так-то без 10 лет опыта, квадратных очков и тельняшки вообще кроме велосипедов мало что сделаешь.
Да кресты вообще вкусная штука, позволяет на двух стульях сидеть: и синтаксический сахар со всякими автоматизациями, как у сверхвысокоуровневого языка, и как на сишечке пишешь, где надо. Но у меня пока вкус до чистой Сишечки.
попробуй тогда через реализацию интрузитивных структур данных сделать, это позволит реализовать adt без макросов..
Работающий раньше в <3.14 функционал полностью помечен как депрекейтед, какая-то часть вообще пидорнута и нужно ролбечиться
На замену добавлен очередной велосипед связанный вообще с уведовлениями, где трей икон это седьмая вода на киселе и вообще ненужно. Еще и анально прикручено к дбусу
Я что-то делаю не так или тут и в правду полемеры проебаны и проще перекатиться на плюсы?
Мимо веб макакич
Ибо нехуй. Напрямую через WinAPI ебашить надо. А под Linux отдельную препроцессорную ветку писать X11.
я бы взял тупо sdl.
>Напрямую через WinAPI ебашить надо.
Лучше в сибилдере кинуть компонент мышкой на форму, клик, пык, и готово. С винапи можно баловаться если твоя программа уже написана на msvc, тогда уже деваться некуда. А линуксовые либы вроде qt и gtk на винде это как кушать шваброй через жопу.
Цель блять была написать хеллоуворлдовую трей апплекуху чтобы выпаршивать балансы со всех счетов и нагрузку на впски
Сначала было лень заморчаиваться и пошел ковырять JS
Вспомнив 200мб рам хромиум врапперах и ограниченном системном интерфейсе понял что затея так себе
Питон не люблю но попробовал и его
Накатив бинды на бинды биндов ffi я ибу что
Написал первый хеллоуворлд, скомплюклировал, рам все равно каким-то боком жрало 40мб+
Не люблю питон и решил просто катиться дальше
Поднимаю штангу DSLы в две строчки
Qt5 бинды отсутствуют, приходится пердолить GTK
Вдруг выясняется, что нужно писать свои сишные структы и прочий пездец разворачивая забинженные объекты в фп пердоленье и обратно
Нашел бинды повыше, поковырял формочки но нужным мне systemtray отсутствувал
Решил попробовать С, заодно разобраться в этих поентерах маллоках и прочей куйне
Опять какой-то пиздец с GTK, что указал выше
Похоже выучить кресты - самый простой вариант
вообще, по странному случаю вспоминаю подкаст слушал, там обсуждали это проблему. как не странно, но говорят на дельфи можно норм накросплатформить на эту тему.
а ещё wxWidget и что-то там ещё они упоминали, не помню уже...
>А это вообще хз, как юзать.
сохрани в файл. пропиши в гит-директории
git apply путь-до-патча
>Дык мне интересно все в комплексе пилить.
ну, если тебе интересно. я таким способом так ничего и не написал. а только когда начал себя ограничивать.
allocbuf + ALLOCSIZE - allocp >= n
как мы принтер сравниваем с интом?
А я понял,если из поинтера вычесть поинтер, то ответ будет количество элементов мнжду ними. Пипец
указатель
под линуксом? какой de? у каждого de есть не одно приложение, которое позволяет кастомизировать трей, всего лишь пиша высокоуровневые скрипты.. вплоть до однострочников на баше..
Сижу на ш3 и знаю про блокс и тд
Хотелось что-то все-таки накодить и может допилить в будущем билдер таких треев
Скопировал хеллоуворлд Qt5 C++, уже допердолелся до парса первой нужной страницы
Доволен как слон
Проще взять что-то легковесное вместо GTK.
Если нативные компоненты не нужны, то:
https://github.com/ocornut/imgui
Если нужны, то:
https://github.com/andlabs/libui
А вообще мелкий гуй лучше на Tck/Tk делать.
>Tcl/Tk
А вроде неплохо, выглядит полегче WinAPI. Осталось понять, как вообще использовать.
Мимо
> А вообще мелкий гуй лучше на Tck/Tk делать.
Не лезь туда няшечка ты кавайная
Она тебя сожерт же, почто ты ...
> puts ААААаааааААаааааааа
если чего то "хочется накодить" то пишешь програмку на си которая будет тебе выдавать инфу по нагрузке на впски в cout, настраиваешь i3status чтобы он подхватывал эту программку и все
вторая програмка будет выдавать твои балансы со счетов, также в cout
НО непонятно зачем, имхо скриптовыми обвязками (которых полно в i3status) либо заменами i3status можно это быстрее сделать
или возможно тебе будет удобней выводить информацию не в строку, а вообще иметь системный монитор на экране, тогда и вообще надо conky настраивать
>imgui
Прикольная тема. Можно делать окошки интерфейсов прямо в играх с полноценной графикой, и я не заметил тормозов даже на старом ноутбуке.
/tmp/cch0LAjo.o: In function `main':
main.c:(.text+0x4f): undefined reference to `sqrt'
collect2: error: ld returned 1 exit status
(строка #include <math.h> в наличии)
Что это за нахер вообще? Чем же линукс лучше виндовз в контексте программирования на си?
Нууу, почти.
Стандартную же библиотеку он не требует явно, потому что gcc несколько более интеллектуален в отношения с ld, чем ты.
В любой IDE под Windows достаточно всего лишь указать подключаемые библиотеки в самом коде программы, который ещё и проверяется как минимум на синтаксические ошибки и запускай программу на здоровье. А тут пердолинг какой то
В Clion установленной в Windows были непонятные мне и не работающие в Windows опции: профилировщик, валгринд мемчек, чего-то там с гитхабом. Я ожидал что в линуксе это всё заработает само собой, а в итоге получил что теперь данная IDE без пердолинга с терминалом реально ничего сложнее хеллоуворлда не пишет
Я не знаю, попробуй начать свой путь самурая с С, а не с IDE.
Разберись, что делает препроцессор, что компоновщик, а что на твоей совести.
Нудно, да и ничему тебя не научит, кроме копипаста команд.
Команды терминала всего лишь отображают этапы сборки проекта, что в свою очередь относится к знанию языка. Ну, то бишь, знание, как это все конпелируемое работает, есть мастхев именно для Сишника.
хуйцы сосал, бочку делал?
Нравится ли ему борщ.
Почему это ебаное программирование такое? Почему после вывода одного символа - идёт всё по пизде.
Скажи спасибо, что сегфолт не выдает.
Си это ебаный язык для ёбнутых, меня знакомый попросил задачку решить а я не могу заставить это дерьмо из функции массив символов передать нормально.
BLYAD - это имя локальной переменной, которая содержит в себе адрес первого элементам массива, память под который выделена в стеке. Функция SUKA завершила своё работу и пямять, которую занимали её локальные переменные в стеке - совободилась. Поэтому, когда ты обращаешься к этой памяти, программа тебе говорит: ТЫ ЧЁ АХУЕЛ ПЕС? ИСПОЛЬЗУЙ MALLOC ЕСЛИ ХОЧЕШЬ СОЗДАТЬ МАССИВ НЕ В СТЕКЕ, А В КУЧЕ!
Чё, хорошо, когда за тебя джава сама управляет ресурсами?
Ты выделил на стеке массив чаров в функции, после выхода за область видимости он удаляется, а ты возвращаешь указатель на эту область памяти.
Ты должен его через new объявлять и не забыть после вызова функции через delete[] удалить.
The type suseconds_t is a signed integral type capable of storing values at least in the range [-1, 1,000,000].
Ну и?
Ну юзай useconds_t.
А ms это что? Тоже от -1 до 1,000,000?
Костанты MSisS (то есть MS in S, то есть MicroSeconds in Second) тоже до 1,000,000?
Микро - это сколько так-то?
MicroSeconds in Second?
Ну, в секунде 10^6 микросекунд, кста.
И где ты тип ровно на миллион найдёшь?
Причём тут С, б?
Нет, это я долбоеб и на автомате привычный для меня new написал.
Анон выше верно написал, нужен malloc.
Бля так и знал, пригорел что нихуя не получается и не мог нормально головой подумать. Благодарю.
пиши по английски, наверно русский тебе не родной.
нет. a - это не указатель, это само начало памяти.
Лучше второй printf заменить вот на такой, чтобы понятней было, что a и b - это почти одно и то же:
// Выведет 1 1 2 2
printf("%d %d %d %d\n", a[0], b[0], (a + 1), (b + 1));
Да если бы. В си тред я в первый раз пишу.
Не ебанутый, просто си это машинный язык, а не алгоритмический. Массивы и другие большие объекты нельзя возвращать, стек обосрется.
Есть ли смысл установить вместо Минта Убунту? А то тут плохо про Си на Минте пишут: https://forums.linuxmint.com/viewtopic.php?t=193114
http://mintlinux.ru/forum/thread8974.html
устанавливаешь все нужное
CentOS либо Fedora.
10 лет сижу на Fedora, полёт нормальный. Никогда ни с чем проблем не было.
Да ты ж просто рукожоп. Даже такая параша, как пикрелейтед, вполне работает и делает то, что нужно - возвращает массив строк.
ээээ мутный какой-то подходи на наш ftp-сервер, побазарим за GNU
> Массивы и другие большие объекты нельзя возвращать
Массивы нельзя возвращать, потому что синтаксис не позволяет, а синтаксис не позволяет по историческим причинам. Структуры любого размера (в том числе структуры, внутри которых массив) возвращать можно, там внутри немного магии, но все равно можно.
>>26601
> "a" константный
Это просто следствие того, что массивы нельзя присваивать. А нельзя присваивать, потому что массив по правую сторону от = как обычно деградирует до указателя.
> нельзя написать
Еще как можно. int ∗b = (int[]) {4, 5};
ты сабж читал? если ты создаёшь массив внутри функции и вызываешь её, то в стеке инициализируется несколько полей памяти, которые закрепляются за массивом, после того как функция завершается все эти поля изымаются из стека и сразу же занимаются перемнными из следующих команд. Как ты собрался их возвращать?
А как ты возвращаешь числовую переменную? Она же тоже в стеке и освобождается при выходе.
Тебе стоит изучить как работает вызов функции на ассемблере. Во-первых, значение этой переменной может быть не обязательно в стеке, а может быть в регистре. Во-вторых, у каждой функции есть адрес возврата, куда она возвращает управления по окончанию своей работы и есть специальное соглашение, куда функция записывает то что называется её возвращаемым значением, чтобы это значение можно было использовать в вызывавшем функцию коде.
> ты сабж читал
Ты мой пост читал?
> после того как функция завершается все эти поля изымаются из стека и сразу же занимаются перемнными из следующих команд
Все так. Только тебя это ебет в одном лишь случае: если ты вернул указатель на локальные переменные. Так делать не нужно. Если ты возвращаешь структуру, и эта структура в регистры не влезает, то вызывающая функция неявно создает под нее переменную, и результат в эту переменную копируется, т.е. фактически struct s func(void) { struct s result = {0}; return result; } преобразуется к struct s∗ func(struct s ∗hidden_buffer) {struct s result = {0}; ∗hidden_buffer = result; return hidden_buffer; }. И никаких проблем. Можно было бы возвращать и массивы точно таким же образом, но вот беда: когда ты пишешь return array, сишка видит return &array[0]. Такие дела.
Конкретно к Си у меня нет никаких претензий или негатива, как может показаться. У меня есть негатив к тому, что я должен делать банальные задачи в каловом редакторе, не используя некоторые дефолтные функции (да-да по типу printf). И кому эти навыки нужны в 21веке, где все стремится к скорости, а не к качеству.
Если что, то это мелкий слив заданий - https://github.com/jraleman/42 . Piscines - бассеин, местный жаргон, прописка в хату. 4 недели по 10 часов в день.
Пока челики пыхтят по 70 часов в неделю, то другие проходят питон+ дата сайенс на курсере и устраиваются через пол года за 100 к девальвированных рублей. И где нуб трапа?
> Стоит ли лезть в это болото, если на дворе 21 век, а мне не обязательно знать как мои предки выкапывали сральник на улице?
мне похуй, можешь не знать.
> И почему их взгляд остановился на Си, че не Ассемблер?
а то ты сам не знаешь ответ на этот вопрос.
> И кому эти навыки нужны в 21веке, где все стремится к скорости, а не к качеству.
> И где нуб трапа?
хуй знает, я не работаю, мне лень.
А мог бы на нормальном языке писать
Не себе пишу, в этом то и дело.
Пруф
Задаётся строка, заменить все suf1 на suf2.
Главная:
https://pastebin.com/rZKuDSxf
Свои функции для работы со строками
https://pastebin.com/6nnEEwCx
Всё должно быть динамическое. Без ёбли со своими фунциями работает нормально:
https://pastebin.com/VT7GBgbe
Пиздабольная мерзость - это твой среньк.
Анон спрашивает, как функция возвращает значение переменной, если значения переменных хранятся в стеке, который освобождается.
Я ему отвечаю, что значение не обязательно может хранится в стеке.
Можно значение переменной записать в регистр и функция может вернуть значение в регистре.
Для этого надо знать ассемблер.
Или может ты отрицаешь, что когда я пишу на ассемблере ret, то я ПЕРЕХОЖУ по адресу откуда мою процедуру вызвал вызывающий код?
Я хотя бы потрудился чё-то в памяти освежить из универского курса асемблера, прежде чем пукнуть, а ты просто сренькаешь.
Тут проблем намного меньше. Значение возвращается так же как возвращается указатель, это по факту стандартный тип языка, инт, флот, чар, поинтер, которым язык может свободно оперировать. В C нет механизмов оперировать с массивами как с отдельными юнитами.
> C does not provide any operators for processing an entire string of characters as a unit.
page 87
Проблема в том, что есть char и есть char, и к char нужно добавить char, но ещё проблема в том что нельзя из char* взять рандомный элемент и перенести его в другую функцию.
я её даже не искал. но если бы меня спросили за сортировку, я бы из жопы пузерёк достал и был бы таков. зачем мне это говно запоминать даже? если нужно прочитаю на википедии - освежу в памяти.
+1, тем более сейчас всё на генериках. Ну так для общего развития можно пропердолится в рекурсию в отпуске.
Мне кажется, что когда спрашивают за сортировку, то они не хотят этим сказать, что ты её будешь писать, а хотят проверить какие ты знаешь методы сортировки и знаешь ли ты как они работают, то есть понимаешь ли какую сортировку в каком случае применять.
ничего я не понимаю, я знаю только квиксорт и всё. объяснить я его не смогу. сортировка это узкоспециализированная хуйня, над ней бьются серьёзные математики, а мы просто пользуемся, как мы пользуемся процессором не переизобретая его.
но сколько я программирую, я не понимаю, откуда вообще может взяться массив памяти в один момент который ещё и нужно отсортировать? чаще данные приходят последовательно, или ты их обрабатываешь последовательно. и зачем заниматься свопом данных, быстрей формировать список.
сортировать то по разному надо
кому то быстро, не учитывая того что в наихудшем случае будет провал по скорости (привет быстрая сортировка)
кому то нужно делать частичные сортировки (например, осортировать только для 5ти первых)
кому то нужно делать стабильные сортировки (те у которых не меняется порядок следования одинаковых элементов)
кому то нужно делать вообще сортировку последовательностей, те данных которые не влезают целиком в доступную оперативную память
и оказывается, что все те виды сортировок, что препод тебе в вузике на втором курсе уныло рисовал на доске, потребны..
еще есть и специфичные сортировки, типа сортировки куч, к примеру..
и правда, код функции, напичканой внутри мемсетами, реалоками и каллоками иначе как "парашей" не назовешь
первый признак непрофессионала: по любому поводу срать маллоками, каллоками, реалоками, мемсетами и прчоей аналогичной парашей
ну а что ты имеешь против мемсетов и мемкопи, например?
ты мне лучше скажи, что вас к этому ведёт, заниматься всякой хуйнёй помимо стандарта?
и нет блять, это не вопрос производительности.
Что ты имеешь ввиду?
Нет, не подумай что я UDP считываю, внутри UDP лежит другой пакет со своим заголовками.
ну то есть, и как ты с одной машины на другую будешь передавать типы отличные от char ? а если у них отличаются порядок байт в типах.
Сейчас бы в серьез думать о bigendian в своем васянокоде. Какой милый мальчик, играется во взрослого.
Сбрасывать память целиком не надо, потому что вписать какой-нибудь char в новую версию структуры, в итоге проебаться в alignment'ом и долго искать баги.
В смысле переносить на другую машину? У нас ни каких машин кроме обычных компьютеров из DNS в принципе не было, нет и не будет никогда.
> Сложно ли написать свою виртуальную машину в целях обучения?
Нет, не сложно. Простейшая виртуальная машина это switch(opcode) внутри бесконечного цикла.
>>27736
Если задача - хранить, то можно использовать битфилды (хотя в первую очередь стоит подумать, нужна ли тебе такая экономия на памяти за счет процессора).
Если задача - передавать между машинами, тогда однозначно маски, потому что про битфилды обещаний со стороны языка мало, а компиляторов много.
В крайнем случае, если тебе пиздец как нужна скорость (т.е., если вариант с масками и сборкой из байтиков уже написан и тормозит), тогда можно и memcpy поверх структуры с битфилдами, но с проверкой внутри сборочного скрипта, что компилятор реализует все так, как ты ожидаешь, а не как ему больше нравится.
> но с проверкой внутри сборочного скрипта, что компилятор реализует все так, как ты ожидаешь
О, а я тоже подумал, что хорошо бы написать некий тест, который проверяет всё ли располагается в памяти "как ожидается" и если да, то через указатель, если нет, копируем с масками.
Например при вводе 42.005 должно вывести .005
Пока на ум приходит только одна идея, сконвертировать float/double в char через snprinf() или asprinf() найти '.' через strchr() и дальше уже напечатать через %s
Это единственно верное решение?
На сколько я знаю, у printf есть модификатор, которые позволяет урезать число цифр после запятой, но не до запятой.
Если написать printf("%1.1f", 13.14);
То вывод будет 13.1
Если написать printf("%10.1f", 13.14);
То вывод будет ________13.1 (где _ - это пробел)
То есть модификатор для целой части может выводить дополнительные пробелы, но не может уменьшать количество цифр в целой части.
Так что выход для тебя - выделить дробную часть и вывести её как отдельное число.
Можешь сильно упороться, разобраться побитово как хранится в памяти число с плавающей точкой и выделить оттуда дробную часть. Погугли, "как хранится в памяти double", слабоумие и отвага!
int i = f;
float r = f - i;
printf("%.3f", f);
float f = 45,676;
int i = f;
float fraction = f - i;
float intermediate = fraction *1000;
int r = intermediate;
printf(".%d", r);
как же клево знать арифметику.
и немножко алгебры
Если float > INT_MAX твой код сосет, если после запятой идет 005, то у тебя будет 5 а не 005
>>27340
да я хотел просто выебнуться, сейчас признаю свое хуевое поведение
попробовал сделать сам, и в итоге не меньший говнокод получился:
https://pastebin.com/V7mAKBBi
"питон+ дата сайенс на курсере и устраиваются через пол года за 100 к девальвированных рублей" Инфа сто процентов или "но есть один ньюанс" ?
struct {
type1 memb1;
type2 memb2;
...
char stroka[0x1000];
};
но не маллокать для каждого экземпляра все 4+ килобайта? Типа, именно эта строка в конце дается только один раз, и места требует ровно под свою длину, но лежит в виде фиксированного массива внутри структуры, чтоб обращаться по офсету от адреса самой структуры, а не дополнительные указатели разыменовывать. И менеджер кучи вдвое меньше дрочится, когда таких структур 100500, и память экономится...
Ты, вероятно, имел в виду:
struct {
type1 memb1;
type2 memb2;
...
char stroka[]; // char stroka[1] в С89
};
Да, абсолютно нормальная практика.
ох, мне пора баеньки.. Действительно, к чему это 0x1000, когда никто смотреть не будет, по размеру ли я индексируюсь. Не знал, что в C99 можно без [1]. Спасибо, анон.
>В C нет механизмов оперировать с массивами как с отдельными юнитами.
>>26632
Вдумайся в смысл. То что нет способоа это ежу поеятно, капитан, это аообще не вопрос. Проблема в том что само желание возвращать массивы в си это дебилизм, признак незнания языка. Возможности нет не потому что разработчикам было лень или еще что, а потому что и ре должно быть такой возможности, в стек нельзя совать большие объекты. Да, структуру можно, но структура не большая по дефолту, лишь несколько чисел, а массивы большие как правило, их смысл - хранилище данных, база, а смысл структуры лишь обертка для нескольких переменных.
Весь вопрос не в доках к языку, что есть или нет, а в непонимании что си это не алгоритмический язык абстрагированный от железа, в таком случае естественно ожидать возвратов всего, а машинный язык, привязанный к аппаратной архитектуре, чем является стек.
Пипец ты содомит. Вот закостылил проблему с 0,005
https://pastebin.com/jaMAX3pv
дальше лень копаться
интересно, биткоин это какой-нибудь фронт енд для ллвм с поддержкой куда?
Вот к примеру, чтобы взять значение из rsi, делается так:
asm ("команда" : "=S" (переменная назначения));
Проще говоря, какой дескриптор тут нужен вместо S, чтобы получить пронумерованный регистр?
почему это гулпый вопрос? но нужно добавить, это вопрос про gcc(?).
хз как на x86-64, но на 32:
asm ("movl %%eax, %0 \n" :"=m"(x))
гугли там модификаторы, =m - это вроде в глобальную переменную прописать.
Это вежливая просьба к компилятору, что хорошо бы чтобы ассемблерный код этой функции был вставлен прямо в ассемблерный код программы в каждом том месте, где функция вызывается. Это, при правильном использовании, позволяет сэкономить на "... passing arguments variables, return address, return value, stack mantle and its dismantle, etc."
https://www.thegeekstuff.com/2013/04/c-macros-inline-functions/
Где сейчас вообще используется С или это просто по фану?
Везде. И если тебе так не кажется - присмотрись! Все в мире пропитано духом Си, и без K&R не видать тебе просветления ни в одной отрасли погроммизма.
А духом Си можно пропитаться без Кернигана Ричи? Устаревший типа. Мне напели что там вообще примеры из книги не компилируются
Ой, один хуй вводный курс не наденет тебе на голову все детали стандарта, ибо на то он и вводный, чтоб осилить. Так лучше читать годноту.
так бля, разобрался, у меня glibc 2.27, а потоки c11 завезли в 2.28, но ОС не спешит перекатываться на свежие версии, а накатить прям вместо той, что стоит по-дефолту, чревато поломкой при обновлениях. pizdos
>примеры из книги не компилируются
Только из последней главы, где системные вызовы. И это не сильно мешает разбирать сами примеры.
>Устаревший типа
Багаж в виде K&R тебе только поможет врубиться в нововведения, обузой он уж точно не будет.
Там всего 200 страниц, остальное справочник.
ни в коем случае не жалуюсь, но хотелось бы няшного стандартного интерфейса, переносимого наконец куда-то на винду
ооо либераху порвало
Я правильно понимаю что все строки сохраняются в огромный буфер, который мы делали в прошлой главе, и который является екстернал переменной?
Нет.
Теперь в буфере сохраняются только указатели на строки, но не сами строки.
Аллок, который ты подсветил как раз выделяет ровно столько памяти, сколько нужно под текущую строчку.
Так без этого кода эта программа не будет работать? У нас же есть функция strcpy(char , char ), которая копирует в огромный буфер allocbuf[] наши строчки одна за другой? И указатели, которые лежат в массиве ведут на куски этого буфера?
Всё, я познал C
>- 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 или до.
Ролл. От 0 до 4 Мозг и Денис, от 5 до 9 Стивен
И то и другое не вариант?
Сначала КНР, он потоньше.
У меня, кстати, ещё вот такая книжка есть:
https://www.ozon.ru/context/detail/id/928388/
Очень мне нравилась, когда по Си угарал. Многое оттуда почерпнул. Если найдешь где скачать без СМС, полистай.
>И то и другое не вариант?
Я хотел сначала ролл, потом второе.
>Если найдешь где скачать без СМС, полистай.
Спасибо, обязательно полистаю.
этаж хуйня не будет работать. == выполняется раньше чем =
send(_sock, "HTTP/1.1 400 Bad Request\r\n", 26, 0);
Что не так в этой божественной строке кода?
мейби что то с портами, типа клиент стучится на сокет порт, и не знает что придёт хттп
попробуй 500 ошибку кинуть (ошибку сервера)
напиши плагин для браузера который работает с твоим сокетом и радуйся
какая аутентификация? Короче, моя программа полностью хавает POST-запрос с JSON-ом в конце, парсит всю хуйню и т.д. и т.п., после чего сразу отвечает 200 или 400. Там еще какая-то промежуточная перекличка должна быть??
бля, у меня уже все жестко написано по-байтоебски, мне бы только разобраться с последней траблой - чтоб клиент, который не догадывается, что его запросы обрабатываются на уровне laba2.c, видел серьезный такой, усатый в тельняшке респонс
Как лучше всего (в плане оптимизации - скорость выполнения, количество тактов) заполнять память по указателю?
char offset;
for(offset = 0; ... ; offset++)
{
(char ∗)(0x123 + offset) = data;
}
Или
char ∗ptr;
for(ptr = (char ∗)0x123 ; ... ; ptr++)
{
∗ptr = data;
}
Я бы посмотрел как устроен memset
Наверняка самый быстрый способ с использованием 64 бит значения или вообще SIMD
Что-то вроде:
long values; // fill it with 'value'
for (ptr = start; ...; p += 8)
{
(long)ptr = values;
}
Нет, я просто зашёл в тред и написал пост, не обращая внимания на циферки.
>что ты как джавист
сказал он мне, когда я приперся с вопросами про HTTP Server API для Windows... Нахуй это ваше байтоебство - психическое отклонение.
> Что не так в этой божественной строке кода?
У нас TCP. В редких, но все же вероятных ситуациях строка может отправиться не полностью, счастливой отладки. Алсо, где вторая пара \r\n в конце?
>>30855
ptr + offset не всегда возможно оптимизировать до ptr += offset автоматически (алиасинг и все такое).
Я уже и \r\n, и \r\n\r\n, и \r\n\r\n\r\n\r\n пробовал. А кейс с разбиением 30-байтовой строки на части (лол) - не моя ответственность, я респонс отправляю, а принимает его полноценная реализация протокола.
В тестовом клиенте (ниже) его и юзаю, но winhttp - это же только для клиентского и есть, нет? Непонятно, как там серверную очередь делать, для этого видимо HTTP Server API существует. Я ошибаюсь?
>>31252
После закрытия дочернего сокета разве не должно флашиться? И нет, проблема не в этом. Мой тестовый клиент все распечатывает (200/400). А нормальным программам почему-то похуй.
> пробовал
Хорошо, а что именно у тебя не работает? Какого поведения ты хочешь от браузера, и что происходит? Ты хочешь вежливо послать нахуй браузер? Так отправляй полный респонс: "HTTP/1.1 400 Bad request\r\nContent-Type: text/plain\r\nConnection: close\r\n\r\nGo fuck yourself."
А браузер не отображает status line, если кроме нее ничего нет? Вообще, это я с браузером решил поиграться. Там свой клиент, и мне жалуются, что вообще никакого ответа с сервера нету, хотя знающе так говорили, что хватит любой хуйни типа 200/400. Неловко ламповый Си-тредик этим загружать... Пойду спать, забей анон.
> знающе так говорили, что хватит любой хуйни типа 200/400
Хватит, чтобы браузер понял, что у тебя ошибка. А чтобы еще и пользователь понял, нужно посылать тело.
> жалуются, что вообще никакого ответа с сервера нету
А ты точно соединение правильно закрываешь? SO_LINGER там или shutdown() какой-нибудь? Может там клиент не хочет неожиданно получать -1 от recv().
Ценный совет, замечу. Вчера пренебрег, что привело к полету стеклянной бутылки в стену и метлы в монитор РОТ ЕБАЛ ЭТОЙ ВИНДЫ ССУУККАА
Дядь, лечи нервы, я не представляю, как бы ты на реальной работе прогером психовал.
Да я и на винде в консольке.
дя
>я умный и красивый
И что? Это ни как не связано с тем, на что ты отвечаешь. Видимо не такой уж и умный, раз не понимаешь, что "ум" - вещь многогранная, в зависимости от ситуации и контекста означающая совсем разные вещи. Видишь, в данном контексте ты довольно тупой, но в других можешь быть и умным.
ну, к примеру, у тебя будут так называемые "чанки", это массивы фиксированной длины, связанные между собой в список, память под чанки же может выделяться через организацию пула
это один из вариантов реализации, коих много
Так можно?
а первое кто освобождать будет?
Ну, если, например, в цикле маллочишь и передаешь указатель функции, делегируя ей ответственность за free, то ок, какие проблемы.
>malloc
Орнул
Аноны, поясните, пожалуйста, что не так?
Выходит пикрил.
Думал что это из-за того что использую i-1 в строке, которая с нуля идет, но попробовал переписать с начальным i - единицей, все равно эта ошибка вылазит, в чем проблема?
(на сайте не компилируется, т..к не открывает string.h, через vs19 компилируется, но выходит пикрил при попытке ввода слов)
> Аноны, поясните, пожалуйста, что не так?
1) Пользуешься уебищными функциями с _s.
2) gets_s() хочет два аргумента, передаешь один.
3) Не проверяешь конец строки (не ввел точку в конце - получил вот эту самую С0000005). И во внутреннем цикле тоже не проверяешь.
4) Не проверяешь, что symb сам пробел.
Остальное вроде ок.
char^ alloc(int n)
или
char ^alloc(int n)
в книге настаивается на втором варианте, так как это мнемоник который показывает нам что чтобы его развернуть надо поставить перед переменной звёздочку. Но я никак не могу привыкнуть как не пытаюсь (после плюсов) и подмывает юзать первый вариант.
Писать звездочку слитно с типом кажется хорошей идеей ровно тогда, когда объявляешь одну переменную, являющуюся простым указателем (или указателем на простой указатель). Как только начинаются указатели на функции, указатели на многомерные массивы, много указателей char ∗p, ∗q; сразу приходит понимание, что первый вариант - полная хуета.
Не приходило в голову, что при одной переменной, правильнее слитно с типом, а с несколькими правильнее слитно с переменной?
А зачем мешать? Что за двоемыслие? Смысл всех этих декорирующих звездочек, скобок и прочего в том и только в том, чтоб отобразить последовательность операций, приводящих к описанному типу. Нечего тут косплеить.
ja[0] += pidoras[0],
ja[1] += pidoras[1],
ja[2] += pidoras[2]
Писать
YOBA_MACRO(ja, +=, pidoras, 3)
?
Отдельно для трех, например, легко сделать
#define COMBINE3(dst, op, src) \
(dst[0] op src[0], dst[1] op src[1], dst[2] op src[2])
Но умеет ли препроцессор генерировать N аналогичных строк по шаблону?
> Есть ли какие-то нативные средства
Да. Внешний кодогенератор на питоне, перле, баше или даже на самой сишке.
> Но умеет ли препроцессор генерировать N
Сорт оф. Ты можешь дважды вызывать combine3 из другого макроса, тот другой тоже вызывать дважды, и... тридцати двух уровней вложенности тебе точно хватит.
если не нужна помтоянная автоматизация, то такое генерится в экселе или блокноте++ за пару минут
ls ../LearnC/ | clang
ЧОМУ ЭТА ХЕРНЯ НЕ РАБОТАЕТЙ
>больше одного обьявления на строку в большинстве случаев - говнокод
>мимокрестовик
Всегда стараюсь объявлять переменные одной строкой и в самом начале подпрограммы.
моя утилита которая выковыривает юрл | clang
clang не может быть частью пайпа?
Если объявляется переменная, то звезда относится к этой переменной, соответственно и место ей рядом с именем переменной.
Если объявляется функция, то звезда относится к типу возвращаемого значения, а переменной как таковой нету, соответственно ее уместнее приклеить к типу.
Так подсказки intellisense более внятно читаются, на мой взгляд.
Алсо, в с++ не во всех контекстах возможно придерживаться строго одного стиля.
Разные понятия
Нет таких условностей, анон. Функция тоже может возвращать указатель на многомерный массив или указатель на функцию, например. Только отображение последовательности операций, чтоб получить тип слева, и никак иначе. Остальное от гуманитариев. Привыкнув к написанию слитно с типом даже в отдельных случаях, неизбежно будешь путаться, столкнувшись, скажем, с
typedef float (EdgeList ∗)[2][3];
Если в голову приходят мысли писать иначе, значит логика Сишных деклараций НЕ ОСИЛЕНА, поциент не мыслит верными категориями, и каждый нетривиальный случай для него мини-головоломка, что есть совсем не айс.
Ну, например, ты хранишь какие-то 24-битовые штуки по адресам, кратным dword. Размер 3 байта, выравнивание 4 байта. А еще в многомерных массивах бывает выравнивание начал строк. В bmp каждый пуксель - 3 байта (RGB), но даже если шириника картинки - 611, все равно каждая строка будет начинаться с адреса, кратного 4.
>шириника
Не совсем понял
ок 24 битовая штука.. 24 / 8 = 3 байта
пусть есть массив
ХХХOOOOO|XXXOOOOO|XXXOOOOO|...
То есть X это полезная нагрузка, O это пустые байты, чтобы
блок XXXOOOOO делился на dword ?
То есть XXX - размер (3)
OOOOO - выравнивание (4)
а что тогда XXXOOOOO ?
Выравниваем по 4 байтам. Включая полезную инфу. Количество O - это не шаг выравнивания, а пэддинг.
Ты хочешь дать шлангу в stdin имена файлов через пробел? Я понимаю, если бы единственный исходник распечатать в пайп, это еще логично (тоже не работает). Короче, палю годноту. Обратные кавычки есть.
$ clang `find ../LearnC/`
Команда внутри выполняется и ее вывод встает заместо кавычек. Да, анон выше поправил, потому что ls папки не печатает путь, а конпелятор не знает, где ты ls-ил. Алсо, хз зачем даже find, когда можно просто
clang ../LearnC/∗.c
Естественный отбор.
Хуя ты от первоначального тезиса оторвался в 2 хода... Говно - интерфейс сишных библиотек от мелкомягких. Используются они на винде. Чувствуешь? Анон назвал X говном, потому что X говно, обозначив то, что имеет ввиду, более кратким названием Y, где используется X. Ты же обвинил его в предвзятости к Y. Трагически погибни. Добрый вечер.
проиграл
Тем не менее, венда то еще говно. ГНУ Операционная Система Имени Профессора Компьютерных Наук Ричарда Столлмана - выбор здоровых людей.
Чё там у тебя нет?
10 лет на Линуксе сижу, всё есть.
И даже игори Габен завез, играй-нехочу. Накатил Стим и погнали.
Жалею только что WoW работает только через Wine, а да и хрен с ним, давно пора отказаться от этой ммо наркомании.
Линукс - топовая платформа для программиста - моё личное мнение.
Т-с-с, тему разбудите! Она у нас такая, храпит-храпит, как вдруг ХУЯК 4 БАМПЛИМИТА!!!
Ну, в Си тоже есть касты, где приходится всю матрешку без имени описывать. И что? Абсолютно та же логика. Имя предполагается под первоприоритетным оператором.
(int (∗[])(char ∗, const char ∗))ptr
Интерпретировать ptr, как массив указателей на функцию, принимающую две строки и вовращающую целое число. Такое же "анонимное" обозначение типа применяется в шаблонах
std::vector<int (∗[])(char ∗, const char ∗)> v;
Вот и вектор таких массивов. В обоих случаях логика описания типа та же, что и при объявлении переменной
int (∗pfunc[])(char ∗, const char ∗)
Нельзя обсуждать совершенство, его надо познавать.
>std::vector<int (∗[])(char ∗, const char ∗)> v;
Думаю в 2019 году нормальный человек напишет
using proc = int(string, const string);
vector<vector<proc>> v; // опционально array
а не вот это легаси бяку
Перевод на русский какого года самый лучший?
Нормальному человеку вряд ли понадобится многомерный массив функций, но речь не об этом.
У которого обложка как на оп-пике. Он тоже не идеален, но ошибки там обычно очевидны. Можешь держать под рукой на всякий случай оригинальное издание.
Вот, блядь, не знаю, почему в Си не завезли двоичные литералы из ассемблера. Просто рофл какой-то. Они даже в Java есть, Карл!
Это всего лишь integer константы, которые, как и любые другие, превращаются в 010010110.
char 11110000 это 15
а unsigned char 11110000 это 240
хотя 00000001 и сигнед и унсигнед это 1?
Мне кажется (пусть аноны поправят, если что) что когда ты пишешь:
char c = 0xF0;
то происходит переполнение, так как char может принимать значения от 1111 1111 = -127 до 0111 1111 = +127 И из-за этого переполнения у тебя вместо 0xF0 в "c" оказывается 0x0F но почему это так происходит, вместо того чтобы в char оказалось число 1.111 0000 = -112, я не знаю.
char не может быть таким большим
но да я ошибся, то есть
char 11110000 это -16
а unsigned char 11110000 это 240
но например 00001111 и сигнед и унсигнед чар это 15
>char не может быть таким большим
Чего бля? чар 8 бит, один байт, открой калькулятор и посчитай
ну давай посчитай... ты не поситаешь, а я нарыл формулу уже посчитал
nk
где n количество состояний, k количество бит
кажется такая простая задача, посчитать сколько состояний может закодировать 8 последовательно расположеных бит, но вот хуй ты сможешь обьяснить как это сделать и посчитать.
Если сомневаешься, скажи мне слёту как посчитать сколько состояний может закодировать 2 байта
Как же я с вас хуею. Значит так, бля! Слушаем внимательно. Сначала был унцыгнед:
00000000 = 0
. . .
11111111 = 255 (= 256-1 = 2^8-1)
Потом появился цыгнед:
XXXXXXXX
цыгн подчеркнут. Если цыгн=0, то все как обычно, а если цыгн=1, то берется значение унцыгнед минус мощность типа 2^8. Таким образом, 11111111 из примера выше превращается в 0-1. И таким же образом мы по-христиански делим весь набор на негатительные и позитительные, при чем операции сложения и вычитания дрочат биты точно так же, выдавая корректный результат после всех переполнений.
Да нет, я умный. Честно-честно.
пфф взял программистский калькулятор. ну ты и даун
Типичное пердольное "нинужно". Сидят царьки и командуют. А как реализовывается власть? Конечно через угнетение: не даешь что плебсам надо и получаешь удовольствие от их мучений и беспомощности исправить положение.
>Почему длина везде одинаковая?
это длина указателей на строки, естественно она везде 32 битная
длину строк считает strlen
int z 00001000 00001001 00001011 00001111
получить 4 чара
char a 00001000, char b 00001001, char c 00001011, char d 00001111 ?
Спасибо, хотелось бы без дополнительных либ и на чистом C
char a 00001101 и char b 00001011
слепить
int c 00000000 00000000 00001101 00001011 (xxab)?
ну мам
лучше зделать and 0xff с этим интом чтобы получить последний байт присвоить его в чар. потом сдвигай вправо на 8 бит и опять делай этот and. получиш второй байт и так далее в цикле ебони 4 раза
да в цикле пиши байты в массив из чаров
после цикла присвоиш их в тдельные переменные если нужно
if (x >= 0)
for (Int32 i = 0; i <= x; i++) { u = u + 1; }
else
for (Int32 i = 0; i >= x; i--) { u = i - 1 }
Это копия, сохраненная 18 января 2020 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.