Вы видите копию треда, сохраненную 2 марта 2019 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
Пожалуйста, пользуйтесь https://ideone.com/ или http://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 (драфт)
- 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://www.iso-9899.info/wiki/Books#Learning_C
Онлайн-утилиты:
- https://godbolt.org/ - Compiler Explorer позволяет посмотреть выхлоп компиляторов для введенного куска кода (больше полусотни разных версий компиляторов).
- http://cdecl.org/ - С Gibberish ↔ English помогает читать сложные сишные декларации.
Прошлые треды:
- №34: https://arhivach.tk/thread/398890/
- №35: https://arhivach.tk/thread/398891/
- №36: https://arhivach.tk/thread/407257/
ктбо-?
на самом деле лютый говнокод с хуевым стилем оформления, посмотри лекции по алгоритмам сортировки и ознакомся с конвенциями написания кода
Положено писать на US English, если ты норм чел, который увОжает гайды. А не макака из Говногермашки или Китая, которые ебашут переменные на своих нахрюках.
>И чё?
То, что переменные в идеале должны быть self-documenting, т.е. чтобы из названия можно было понять, что это за херь. Иначе как ты фрилансить-то собираешься? Чё за параша твой massiv?! Какой-нибудь myArray - это будущему заказчику понятно, а massiv - это что за поебень такая?
Эй, ананасы, кто там в прошлом треде за 8-битную разработку на Си и за компиляторы спрашивал? Помимо классического HiSoft C гляньте современный z88dk (z88dk.org) Алсо, рекомендую 8bitworkshop.com Там жаль, что не оффлайновая IDE-шечка и толковые книжки которые автор предлагает купить, но всё давно уже спижжено и в сети валяется.
Это полный пиздец, а не говнокод, такое только школьник или тупой студент в состоянии написать.
Как по-человечески установить mingw-64 и SDL на виндовс?
Вроде бы всё по гайду делаю, а зависимости не хочет подключать.
Спасибо, посмотрю.
for у вас там тоже запретили?
А, да, кстати! Спасибо, что напомнил!
Не инициализируется большая часть переменных, неочевидные имена, скобки с переносом строки (можешь погуглить пособие от гугла что ли, где они писали про правила хорошего тона в коде), нет разбиения на функции.
ну и сам код мне было впадлу читать. учил в этом семаке в вузике на не очень прогерском факе, мог спокойно проебать что-то важное
https://google.github.io/styleguide/cppguide.html#Scoping
Могу поклясться, что где-то в этом гайде видел мошну на скобки с переносом строки.
На мой взгляд тоже, но мне оба варианта глаза не режут, поэтому перешел на скобки без переноса.
Через пару месяцев пересмотри его код, если ничего не изменится в твоём мнении, то бросай обучение.
>Что с его кодом не так? С виду все нормально.
Все просто ужасно, абсолютно все. На ошибки я тебе указывать не буду.
Смотри свод правил в конце "C: Elements of style". Попробуй найти хоть одно, которое ты соблюдаешь.
>мимо только на днях дошел до функций.
Ну так иди и учи дальше. Пока что ты ничего не умеешь.
Другой анон
Спасибо
Ну в некоторых языках чаще встречаются скобки без переноса, но в си, да, вообще-то с переносом предпочтительнее
Так написать постараться надо, даже мне, ламеру, это видно. Ты троллишь?
А разве фигурные скобки не надо переносить? Так они визуально показывают блок кода.
>>18513
>>18514
Я не учусь на программиста и не работаю им. Мне просто бывает скучно и я читаю Кернигана. Иногда делаю сам для себя задачи, которые мне интересно на телефоне. Вот, например, из недавнего сделал программу которая вычисляет шанс что из 1-5 кубиков выпадет хотя бы на одном 5 или 1 (для игры в тысячу считал):
https://pastebin.com/M9bE5BUG
Насколько говнокод, если я к тому моменту даже до функций не дошел? Думаю учиться делать нормально лучше с начала обучения. На телефоне форматировать текст неудобно, но я старался.
В пpимеpах вижу int p, но мне кажется, что int p как-то лучше выглядит, ничего не смущает.
Дело вкуса, в Винде обычно ставят звезду у типа, на Линукс у названия переменной, на макоси вообще между, то есть тип пробел звезда пробел название переменной.
я сейчас про ядро говорю
Вообще единственный аргумент есть в пользу линукса такой, что:
int #p, k, если ты пишешь вот так, то у тебя p это указатель, а k int, поэтому так типо более читаемо и согласуется с тем как компилятор разбирает код на морфемы.
Например:
int# p, k
Тут неподготовленный читательчитай новичок может подумать, что и p и k указатели, что конечно же не так.
Для компилятора без разницы как ты ставишь звёздочки, это нужно для человека, которые йбудет читать твой код.
# это звездочка
В том, в чём ты, блядь, пишешь - это полный отстой.
Быстро переходи на emacs, и люби самого себя.
emacs-goddess
В vs code пробелы и табы лучше отображаются, у тебя они так в глаза бросаются, шо пиздец.
Аж глаза заболели от твоего скрина
Например?
Профиль на гитхабе скинешь?
или корпоративный софт онли, который на внутренних гитлабах всяких крутится?
>Насколько говнокод
На 5 балов.
(c==1) || (c==5) || (d==1) || (d==5) || (e==1) || (e==5)
i=e=sumx2=sumx3=sumx4=sumx5=total=0;
это пиздец
А что с ним? Я выше прочитал что перед +-= и так далее надо пробелы ставить. А больше не вижу косяков. Ну а про короткие имена переменных я в курсе, они такие потому что я на мобиле пишу, заебусь длинные имена писать раньше чем что-то рабочее сделаю.
Ну скобки нинужны, смотри приоритет операции, паровозное обнулении тоже дико смотрится и чет дохуя у тебя переменных
> 1-5 кубиков выпадет хотя бы на одном 5 или 1
А расскажи, что делает этот страшный код? Почему это не pow(2.0 / 6, 5)?
У меня как-то давно без скобок низуя не хотело работать и я с тех пор каждое выражение с && или || ебеню в скобки. Учту, что можно и без них.
А как без обнуления то? Иначе у переменных будут же рандомные значения, нет?
Так переменных дохуя потому что дохуя значений хранить надо:
- 5 разных кубиков
- количество нужных комбинаций и общее количество комбинаций для 2, 3, 4 и 5 кубиков.
>Так переменных дохуя потому что дохуя значений хранить надо:
И кокое значение хранит i? Крч, гугли теорвер у тебя проеб с алгоритмом, но для говнокода сойдет, можно отправлять на govnokod.ru
>А расскажи, что делает этот страшный код?
Я захотел узнать какой шанс что у тебя из 5(/4/3/2) кубиков хотя бы на одном выпадет 1 или 5. Ебаться с теорией вероятности я не хотел и поэтому написал программу.
>Почему это не pow(2.0 / 6, 5)?
потому что я еще не знаю что это такое.
>>18777
>И кокое значение хранит i?
Это счетчик, очевидно же.
>гугли теорвер у тебя проеб с алгоритмом
Схуяли? У меня правильно посчитаны все вероятности, но ты можешь попробовать доказать что это не так.
>Я не учусь на программиста и не работаю им. Мне просто бывает скучно и я читаю Кернигана. Иногда делаю сам для себя задачи, которые мне интересно на телефоне.
Тогда тебе не стоит писать на Си. Он достаточно сложный и заточен под низкоуровневую работу, а кодить нормально ты еще не умеешь. Сейчас лучше попробуй писать на питоне. Иначе читай SICP, начинай Кернигана с самого начала и прорешивай все подаваемые задачи.
>Вот, например, из недавнего сделал программу которая вычисляет шанс что из 1-5 кубиков выпадет хотя бы на одном 5 или 1 (для игры в тысячу считал):
Ну это хрень полная, ответ и без теорвера очевиден: 1 - (2/3)^5.
>Насколько говнокод, если я к тому моменту даже до функций не дошел?
До говнокода еще далеко (честно).
В этом итт господарьске треде попрошу рассказать C-бояр как работает функция system() и можно ли ее организовать своими силами в языке C. И если можно, то как? Хотя бы на приблизительном уровнe
Отдельно попрошу об отсылании к сорцам компиляторов не отсылать, ибо там хуй разберёшься
Glibc source:
https://code.woboq.org/userspace/glibc/sysdeps/posix/system.c.html
Секция с sigaction n1
1) sigprocmask SIGCHLD -> SIG_BLOCK
2) fork, restore signals, execve SHELL_PATH с новым argv
Секция с siagction n2
lock'и расставлены так, чтобы "подпроцессы" лишний раз не использовали sigaction на SIGIGN и SIGQUIT.
В этом всем нужно разбираться если хочешь написать полноценный аналог библиотечного system.
Если нет времени/лень то просто посмотри вызовы fork, execve в linux man. Там же отрывок про argv в execve.
Продолжение
Можешь взять strace и подглядеть строчку с execve (подглядывать нужно за ребенком-шеллом).
почему пpибавился ещё один world?
Удивительно, что она вообше что-то вменяемое выдает. Вроде бы у тебя тут выход за пределы массива
навеpное пpосто пpибавляет str1 пpи каждом вызове. понятно, я просто дурачок.
Но если поменять местами world и hello, то массив наложится на другой. Короче, не делайте так, ребята
Да я тупой, все просто:
strcat() стирает '\0', а strlen() читает до первого '\0' в следущем массиве
Порядок вычисления аргументов функции в Си неопределен. В printf аргументы часто передаются задом наперед, как в функции с неопределенным числом параметров. Сначала вычисляется первый strcat, потом strlen (10), потом еще один strcat.
Можно пустые квадратные скобки оставить, размер под строчку сам подберется.
strcat к тому же месту в памяти приклеивает еще одну строку (strlen + strcpy), а массивы столько не вмещают, делай их больше или используй динамическую память. Переполнениями массивов ты гарантированно испортил что-то, что лежит на стеке рядом с твоими строками. Попробуй использовать свой strcat раз 5-6 и из твоего main уже не получится сделать return :).
Под первым strcat я имел в виду strcat внутри strlen.
скомпилировать и в gdb disassemble посмотреть - понятнее будет код
> Тогда тебе не стоит писать на Си
А, быть может, как раз таки стоит. Зачем ориентироваться на современные технологии, если не стоит цель заработка? Почему бы не позволить себе окунуться в ламповое технарьское хобби по труъ-шному? Для общего развития даже полезнее. Если никуда не рваться, то сишечка и асм очень даже по кайфу, ведь ты реально в чем-то прошариваешься.
Да, всё правильно. Вот только у тебя сейчас не очень кодить получается, даже без привязки к какому-то языку. Я советую тебе сначала почитать какую-то теорию наподобие SICP или что-нибудь подобное.
Это писал не я собственно, но я с тем аноном согласен.
>Вот только у тебя сейчас не очень кодить получается
Это почему? Потому что какому-то стилю оформления не придерживаюсь?
>У человека же нет никакой нужды в этом плане, а вы так вот отговариваете.
Я не отговаривал, а предложил сначала просто в программировании немного освоиться.
>Тут кодеры старой школы тоскуют по счастливой юности и сишечке, вынуждены перекатываться.
Я юн перекатываться не вынужден.
Я наверно неправильно выразился, у тебя здесь просто o(n^2) сортировка, может быть она и рабочая, но сам код перепутанный и ужасный. Книжки типа SICP учат элегантному программированию, а не таким макаронам.
Макароны как я понимаю это когда код скажет туда-сюда всякими goto и подобным. У меня же такого нет, все по порядку идет. А вообще сперва надо хотя бы Кернигана прочитать целиком, а уже потом всякие SICP читать, не? А то я пробовал читать правила оформления и про половину вещей просто не ебу что это такое в принципе.
Нахуя мне LISP?
Я, конечно, ни разу не претендую на хороший стиль и прочее, но вот тебе сортировка по убыванию, все в пределах stdio.h. Вроде читабельно.
> сначала просто в программировании немного освоиться
Не могу знать, стоит или не стоит начинать с Си, педагогом не являюсь, а на собственном опыте подобные успехи не пришлись, сам сокровище K&R для себя открыл уже не девстенником в программизме. Тем не менее, ИМХО, советовать Python таки подстава. Тогда уж лучше "Accelerated C++" от Koenig и Moo, или Страструпа "Programming Principles and Practices using C++", вроде как годнота для вкатывальщиков. Но, в принципе, если анон мозговит, и K&R с кое-каким скрипом заходит, то можно и обойтись.
>Тогда уж лучше "Accelerated C++" от Koenig и Moo, или Страструпа "Programming Principles and Practices using C++", вроде как годнота для вкатывальщиков.
Еще лекции по Си от Праты.
>Но, в принципе, если анон мозговит, и K&R с кое-каким скрипом заходит, то можно и обойтись.
Про вероятности и кубики был код, анону явно нужно что-то до K&R.
Ты мой пост и процитировал. Почему мне стоит читать что-то до K&R?
Может не совсем тематика, но вы уж не пинайте.
Есть железяка ESP8266, кодится в Eclipse через MinGW + Espressif-ESP8266-DevKit-v2.0.9-x86.
Хочу подцепить к ней SD карту памяти по SPI, СИ-шная библиотека была бы очень полезна, но она не гуглится.
Хотя гугол пестрит библиотеками для ардуинки.
Куда копать?
Почему-то между первым и вторым узлом довольно большой промежуток в 428 байт, а между 2-3 3-4 14 байт. Каждый узел это структура с 3 int переменными и указателем типа структуры на следующую.
Я не очень представляю эту виртуальную адресацию.
тут вопрос сводится уже не к твоей конкретной структуре данных, а откуда маллок память берет, выделяешь память ты в разное время, поэтому врядли 2 узла обязаны рядом находиться в памяти
Разве malloc не из кучи выделяет память? И выделение памяти идет подряд для четырех узлов одно за другим.
ты можешь выделить 2 узла подряд, тогда да, должны быть подряд, потом например для другой дресни выделить, а потом опять со стеком хуярить, в итоге у тебя потеряется шаг тот.
Подряд все идет. Что интересно, до выделения памяти я поместил принтф хеллоуворлд и теперь абсолютно все адреса отличаются ровно на 20 байт.
У препода в примере просто между всеми узлами равное число, вот и я ищу объяснение моему результату. Когда я компилирую его код, то промежуток неравный тоже появляется и адреса ровно те же, что у меня.
Это зависит от системы/процессора/среды разработки?
#define WORD struct word_type
#include<stdio.h>
#include<stdlib.h>
WORD
{
int TAG;
int SUIT;
int RANK;
WORD NEXT;
};
void main()
{
int N;
WORD TOP, / указатель на верхний элемент стека /
NEWCARD, / указатель на новый элемент стека /
X; / указатель на текущий элемент стека /
TOP=NULL;
NEWCARD=(WORD )malloc(sizeof(WORD));
printf("NEWCARD=%p\n",NEWCARD);
/A1/ NEWCARD->NEXT=TOP;
/A2/ TOP=NEWCARD;
/A3/ TOP->TAG=1; TOP->SUIT=1; TOP->RANK=10;
NEWCARD=(WORD )malloc(sizeof(WORD));
printf("NEWCARD=%p\n",NEWCARD);
/A1/ NEWCARD->NEXT=TOP;
/A2/ TOP=NEWCARD;
/A3/ TOP->TAG=0; TOP->SUIT=4; TOP->RANK=3;
NEWCARD=(WORD )malloc(sizeof(WORD));
printf("NEWCARD=%p\n",NEWCARD);
/A1/ NEWCARD->NEXT=TOP;
/A2/ TOP=NEWCARD;
/A3*/ TOP->TAG=0; TOP->SUIT=2; TOP->RANK=2;
printf("TAG(TOP)=%d\n",TOP->TAG);
printf("SUIT(TOP)=%d\n",TOP->SUIT);
printf("RANK(NEXT(TOP))=%d\n",TOP->NEXT->RANK);
B1: N=0; X=TOP;
B2: if(X==NULL) goto end;
B3: N++; X=X->NEXT; goto B2;
end: printf("N=%d\n",N);
getchar();
}
Скомпилируй, если не трудно, и запость результат вывода. У меня после первого узла большой промежуток.
#define WORD struct word_type
#include<stdio.h>
#include<stdlib.h>
WORD
{
int TAG;
int SUIT;
int RANK;
WORD NEXT;
};
void main()
{
int N;
WORD TOP, / указатель на верхний элемент стека /
NEWCARD, / указатель на новый элемент стека /
X; / указатель на текущий элемент стека /
TOP=NULL;
NEWCARD=(WORD )malloc(sizeof(WORD));
printf("NEWCARD=%p\n",NEWCARD);
/A1/ NEWCARD->NEXT=TOP;
/A2/ TOP=NEWCARD;
/A3/ TOP->TAG=1; TOP->SUIT=1; TOP->RANK=10;
NEWCARD=(WORD )malloc(sizeof(WORD));
printf("NEWCARD=%p\n",NEWCARD);
/A1/ NEWCARD->NEXT=TOP;
/A2/ TOP=NEWCARD;
/A3/ TOP->TAG=0; TOP->SUIT=4; TOP->RANK=3;
NEWCARD=(WORD )malloc(sizeof(WORD));
printf("NEWCARD=%p\n",NEWCARD);
/A1/ NEWCARD->NEXT=TOP;
/A2/ TOP=NEWCARD;
/A3*/ TOP->TAG=0; TOP->SUIT=2; TOP->RANK=2;
printf("TAG(TOP)=%d\n",TOP->TAG);
printf("SUIT(TOP)=%d\n",TOP->SUIT);
printf("RANK(NEXT(TOP))=%d\n",TOP->NEXT->RANK);
B1: N=0; X=TOP;
B2: if(X==NULL) goto end;
B3: N++; X=X->NEXT; goto B2;
end: printf("N=%d\n",N);
getchar();
}
Скомпилируй, если не трудно, и запость результат вывода. У меня после первого узла большой промежуток.
Я скомпилил в двух средах, разница одинаковая 1AC(428 байт) после первого узла, остальные по 20.
Нашел на вики
>соседние элементы списка могут быть распределены в памяти нелокально, что снизит эффективность кэширования данных в процессоре
https://ru.wikipedia.org/wiki/Связный_список
По-моему, это как раз мой случай.
А в чем собственно проблема? gets конечно лучше не использовать, но для примера сойдет.
А, ну хоть gets_s есть. Он принимает указатель на начало строки и максимальный размер этой самой строки чтобы не случился гроб гроб SIGSEGV. Так что аргументом припиши к нему 255.
>Так что аргументом припиши к нему 255
Я не совсем понял что это значит. 255 вместо 0 или вместо 256?
Вот я попытался со scanf_s, открывается консоль, пишу что угодно и консоль закрывается без всякого ответа и вылезают ошибки.
scanf_s перед return чтобы консоль не закрывалась, если что.
Перевод строки добавь в printf, типа printf("%s\n", str);
Добавь fflush(stdin); перед вторым scanf.
Не та картинка.
Где бы я не читал, везде противопоказывается использовать gets. Как сделать то же самое со scanf?
Меняю gets_s (gets в VS в stdio.h нету) на fgets и функция не принимает 2 аргумента.
Нашёл char fgets(char str, int n, FILE* stream); но так и не понял синтаксиса. У меня работает с gets_s, какие могут быть подводные?
Погодите, так fgets это же gets для файлового ввода. Вы меня тут троллите, что ли?
Почему fgets без потока stdin не работает? Как определить для себя, в каких случаях для работы команды просто нужно дописать поток в аргументы?
Но почему в моём случае без потока fgets не работает? Есть ли случаи, когда fgets поток не нужен?
Нет, поскольку он работает именно с потоками. Все, что ты вводишь в консольном окне попадает в поток stdin.
fgets - функция.
У этой функции 3 параметра.
Тебе всегда нужно передавать ей 3 параметра.
>Но почему в моём случае без потока fgets не работает? Есть ли случаи, когда fgets поток не нужен?
Странный вопрос.
fgets — get a string from a stream
Тебе нужно явно указать поток, с которого эта функция прочитает твою строчку. Ввод с терминала - stdin.
> Ввод с терминала - stdin
stdin - это стрим, под которым лежит дескриптор STDIN_FILENO, то есть 0, и терминал там совершенно не обязательно. Ввод из терминала - это fdopen (open ("/dev/tty", O_RDONLY), "r");
забракованная gets лаконично берет один аргумент - указатель на буфер, и читает в него из stdin до первого \n, без проверки переполнения. Если лень писать
fgets (buf, sizeof (buf), stdin)
можно написать макрос
#define gets_(buf) fgets (buf, sizeof (buf), stdin)
но если buf - не имя локального или static массива, а просто указатель, то препроцессор подставит константу 4 или 8, в зависимости от архитектуры
Да, как угодно определяй дескрипторы и exec'ай бинарник? Я это прекрасно знаю. Ты иди объяснять это анону, который про обязательность 3его параметра fgets спрашивает.
Тоже вначале подумал что это Питухон
Ну, если забыть #include <stdio.h>, то компилятор с warning-ом проглотит вызов fgets с двумя параметрами, и что лежало в регистре RDX, то и станет индексом дескриптора)
Цитата из K&R:
Вы обнаружите, что многие существующие программы являются просто расширенными версиями обсуждаемых здесь прототипов.
Точнее и не скажешь, лол.
Дай пример пожалуйста, я запутался.
На какое место в памяти указывает fin в момент первой итерации? Куда будут записаны копии символов? Почему поинтеру на чар присваивают значение поинтера на конст чар?
А то, что указателю присваивается хуй пойми какое значение - это норма?
Вот будете смеяться, а я осилил только Си, и очень маленько ассемблеры x86 и avr. Даже Питон не могу освоить.
Нет, уважаемый, Вы.
Ты в массив констант(через неконстантный указатель)(это UB),
копируешь байты из невыделенной тебе памяти(UB). Вроде так.
Во первых после совпадения надо выйти из двух циклов.
Во вторых циклы у тебя выходят за концы введённых строк
и случайно в мусоре попадаются одинаковы чары. Должно быть
как-то так:
#define MaxLen 256
char sa[MaxLen], sb[MaxLen];
int a;
gets(sa);
gets(sb);
for(int i=0; i<strlen(sa); i++)
for(int j=0; j<strlen(sb); j++)
if(sa==sb[j]) { a=1; goto BREAK; }
else a=0;
BREAK:
printf("\n%d",a);
И ещё бы хорошо сразу int a= нулём проинициализировать.
Число показывает, что все символы второй строки включаются во вторую беспрерывно. Иначе 0. Почему здесь вот так?
А, всё, я понял. Но теперь всплыла другая проблема. Почему i-- в else так влияет на результат при том, что else здесь явно не должен вообще включаться? Как тогда уменьшать счётчик i при ложном ответе if?
>>22971
А что ты там хочешь? Равенство строк проверить что ли? На развлекайся:
char s1 = "abc";
char s2 = "cde";
int l1= strlen(s1);
int l2= strlen(s2);
int equal= 0;
while(s1 && s2 && s1++ == s2++) equal++;
s1-=l1;
s2-=l2;
printf( "\nequal= %d, %s", equal, ((equal==l1) && (equal==l2))? "PABHbI" : "HEPABHbI" );
Э-э, звёзы пропали.
char(ЗВЕЗД) s1="abc";
char(ЗВЕЗД) s2="abc";
while((ЗВЕЗД)s1 && (ЗВЕЗД)s2 && (ЗВЕЗД)s1++ == (ЗВЕЗД)s2++) equal++;
Очередной фикс while(s1 && s2 && s1 == s2) equal++, s1++, s2++;
>>22971
А, ты проверяешь вхождение второй строки в первую, тогда попробуй так:
char s1 = "b abcd abcd e";
char s2 = "abc";
int l1= strlen(s1);
int l2= strlen(s2);
int equal= 0;
int posicion= 0;
for(int i=0; i<l2; i++)
for(int j=0; j<l1; j++)
if(s2==s1[j])
{
equal++;
i++;
if(equal==l2)
goto BREAK;
}
else equal=0;
BREAK:
printf( "\n%s", equal==l2? "BXODNT" : "HEBXODNT" );
по идее, в условие задачи входит не использование строчных функций из стандартной библиотеки (#include <string.h>), в т.ч. strlen...
Яростно плюсую. Паттернодрочерам в великих и могучих Сях не место. При желании, несамодокумментированный гавнокод можно и написать и с соблюдением всех rule-of-thumb и прочих недоконвенций.
тогда
for(int len=0; s1!='\0'; len++); //извлекаешь len после цикла в другую переменную, чтобы вторую строку прогнать
int strequal (char #s1, char #s2) {
while (#s1 && #s2 && #s1++ == #s2++);
return #s1 == #s2;
}
зачем вообще len?
> ссылка на другую ещё не объявленную структуру
struct foo { struct bar ∗barptr; }
// и когда-то потом:
struct bar { ... };
Или с тайпдефами:
typedef struct bar bar;
typedef struct {
bar ∗barptr;
} foo;
// и когда-то потом:
struct bar { ... };
Incomplete-структуры это норм, бояться их не нужно, используются очень часто.
>>23460
А еще можно выкинуть еще ∗s2 из условия, его неплохо == поймает. А потом осознать, что коротко - это не всегда красиво.
> его неплохо == поймает
Таки да. Ну, а краткость вполне оправдана, если функция используется чаще, чем переписывается, особенно когда это в разы ускоряет работу алгоритма. Однако, это меня не больше всего волнует... ТЫ КАК ЗВЕЗДОЧКУ ПОСТАВИЛ, ДЕМОН?
> ТЫ КАК ЗВЕЗДОЧКУ ПОСТАВИЛ, ДЕМОН?
Звездочка из шапки, она нестандартная, компилятор поперхнется. Иногда тут еще ★ вот такую используют.
В общем, нужно сформировать двумерный массив самым простым способом.
12345
51234
45123
34512
23451
for (x=0;x<25;x++)array[x]=((x+5-i/5)%5)+1
или длиннее:
for(x=0;x<5;x++)for(y=0;y<5;y++)array[y][x]=((x+5-y)%5)+1;
Ахуеть, спасибо. Я бы сам до этого точно не додумался.
Проиграл.
ну так иди читать как разные буковки, как представляются в кудахтере, почитай там про тип char, про ASCII, про юникод, хоть что-нибудь.
Ты strq не обнулил, там мусор (точнее, у тебя отладочный билд, и студия для упрощения отладки вот такой хуйни забила стек байтами CC, это -52, да еще ты 1 прибавил). Алсо, не сравнивай символы с NULL. NULL - это нулевой указатель, и только указатель, а не нулевой символ в конце строки. Пиши либо просто for (int i = 0; stra[i]; i++) ... либо сравнивай с нулем: stra[i] == 0, либо с нулевым символом, если хочешь сделать на этом акцент: stra[i] == '\0'.
В спойлере должно было != быть, ну ты понял.
Как лучше, так первая картинка или так вторая картинка?
Стилем отступов.
И то и то пиздец.
Это настолько ужасно, что выбирать тут не из чего. Когда продвинешься чуть дальше, уже будешь думуть про стиль. Но в целом, несколько выражений на одной строке (вот эти твои if ... for ... printf, да ещё и с фигрными скобками) - это 100% говнокод. Разве что иногда можно задуматься о if (expr) do_smth(); (просто выражение, нет фигурных скобок!), но даже это лучше писать на двух строках.
Подрочи, и поймёшь какой си кхм говновый язык
Проблема в том, что char* string, которую я передаю функции words_in_string, не пустая, но происходит такое колдунство. Кстати, адрес не меняется. Что я не понимаю?
Выкладывай полный исходник или бинарь. Или довольствуйся пояснением, что либо ты портишь стек еще до вызова функции, либо у отладчика сносит крышу по причине билда с оптимизациями или еще чего-то подобного. Пробовал до 171 строке на втором скрине доходить? Ничего не меняется?
Всё, что относится только к ответу "истина" от if лучше писать в одной строке, и относящееся к ответу "ложь" на последующей от if строке в одной строке. Также одна операция — одна строка, например: в 11 и 12 строках у меня ищутся размер введённых пользователем строк в двух массивах, найти размер 1-ой строки — первое действие, найти размер 2-ой строки — второе действие, по своей строке на каждое действие.
Ага, начнёшь писать что-то серьёзное или может даже на работу устроишься, тогда научишься хорошему код-стайлуили нет.
\n
Надо же, сработало. Как называются такие хреновины? По каким ключевым словам искать? Как называются и для чего нужны хрени, которые можно ставить, а можно и не ставить между % и типом переменной в scanf и printf?
>Как называются такие хреновины
escape symbols
>Как называются и для чего нужны хрени, которые можно ставить, а можно и не ставить между % и типом переменной в scanf и printf?
format strings
> И как заставить rand() каждый раз выводить разные числа?
srand(time(NULL))
Нет. Управляющие символы не видны, в \t вполне виден, это escape symbol, который превратится в соответствующий control где-то во время компиляции.
\t в этой статье под заголовком "Управляющие символы".
https://ru.wikipedia.org/wiki/Управляющие_символы
Они используют escape sequence вместо escape symbol, что правильно, так как escape symbol это сам бэкслеш. Похуй.
Я делал акцент на том, что \t и символ с ASCII-кодом 09 - разные вещи. Это не \t заставляет терминал печатать табуляцию, а символ с кодом 09, который сам по себе не виден.
Есть у Си спека или что то такое, где можно узнать все возможности?
>У Си вообще есть документация?
Описание стандарта C11, например.
>Там есть про системные вызовы?
Системные вызовы привязаны к самой ОС. Для linux есть manpages и утилита man, там подробно задокументированы вызовы (man 2 write, например) и сам язык.
Позязюсьта
Недавно вызубрил синтаксис си, пару стд биболиотек.
Может тут кому-то нужна помошь с проэктом?
Готов гитануть ваш проэкт и покапаться в нем
а зачем тебе деревьями эту задачу решать? требуется усредненное время как на вставку так и на поиск что ли?
Бамп реквесту
>Недавно вызубрил синтаксис си, пару стд биболиотек.
>За что я могу взяться?
Пока только за SICP, очевидно же.
Есть понятие concurrency, - конкурентный код. Я понимаю, что Си может юзать процессы и потоки ОС. Но кроме того на нем можно писать конкуретный код?
Что угодно, пиши плеер/фм/игру/небо/аллаха. Да хоть построй велосипед и изобрести заново какие нибудь функции из стандартной библиотеки.
Тебе корутины нужны. Это реализуется на setjmp, как тебе уже сказали. В винде оно есть готовое прямо в API в виде фиберов. Алсо: https://en.wikipedia.org/wiki/Coroutine#Implementations_for_C
Только начал вкатываться.
>Как можно научиться правильному синтаксису на примере другого языкА?
Как можно узнав синтаксис стать программистом? Как можно выучив как ходят шахматы стать шахматистом? Как можно выучив цифры стать математиком?
Систаксис задает только правила написания букв. Суть программирования в смысле этих букв, а не правилах их написания. Программирование не про языки, а про вычисления, алгоритмы, логику, архитектуру. Язык только инструмент.
Есть большое количество хешей, выгрузка из кеша (несколько гигабайт), выгрузка обновляется не чаще чем раз в сутки. Нужно в реалтайме сравнивать хеши из кеша на совпадение с вновь генерируемыми хешами, которые потоком в очереди приходят, делать это нужно максимально быстро
>а зачем тебе деревьями эту задачу решать?
самый быстрый алгоритм, который пришел ко мне в голову, для решения моей задачи
Я имел ввиду libuv, libevent, etc. Они для чего используются? Их вообще юзают для написания программ, или только для рантаймов?
не проще ли взять субд под эту задачу? заведешь табличку, будешь туда складывать что тебе надо и доставать
вариантов масса, от классики до неряционки
это всего лишь библиотеки дающие более удобную работу с асинхронкой, что предоставляется целевыми ос
дополнительный плюс, что благодаря им обеспечивается кроссплатформенность
асинхронка же в 90% случаев, наверное, используется для одной задачи - написания серверов что пережевывают сетевые пакеты какого-нибудь протокола
>не проще ли взять субд под эту задачу?
проще, но мне надо не проще, а максимально быстро.
У субд в любом случае еще будет накладные расходы, хотябы на парсинг запроса
еслиб мне надо было проще, яб вообще бы, не на Си все это писал, а например на томже PHP+redis|mongo за пару часов накаталбы уже давно
Сисюны, джва вопроса.
1. Всегда ли в inline __attribute__((always_inline)) нудно определять тело или можно разнести на прототип в хедер и реализацию в другой файл?
2. Такое выдает варнинги, не нравится тип:
static const unsigned char charmap[] = {
'0x00', '0x01', '0x02', '0x03', ....
а такое нет:
static const unsigned char charmap[] = {
'\000', '\001', '\002', '\003', ....
чому, что за сорт октала и чем он лучше хекса?
Молодец.
че, правда думаешь что твой велописед будет быстрее индексов в бд, которые как раз работают на деревьях, которые пилят чуваки с 30ти летним опытом?
давай
> че, правда думаешь что твой велописед будет быстрее индексов в бд
да, потомучто я пилю только тот код который нужен для моей задачи, небудет ничего лишнего, никакого парсинга запросов, только чистое обращение по адресам в памяти, да и опыта у меня (в программировании вообще, но не в Си конкретно) не сильно меньше, уже за 20 лет будет.
Щас пилю чисто на AVL деревьях, никаких субд, юзаю libavl+gmplib
Внутри СУБД будет какое-нибудь B+ tree. Зачем городить слои и лагать на взаимодействии с БД, если можно реализовать то же самое напрямую?
>>26473
Если у тебя реализация инлайна в другом файле, то при сборке модуля компилятор реализацию не увидит, а значит и инлайнить ему будет нечего. Поэтому да, реализация инлайна должна быть либо в начале .c (если используешь только в одном модуле), либо в хедере. Правда, есть такая штука, как link-time optimization, когда кодогенерация откладывается до этапа линковки, но в этом случае всякая мелочь из других модулей будет инлайниться автоматически (если линкер сочтет нужным), без этих твоих атрибутов.
>>26591
Потому что ты заебал. Прочитай что-нибудь про сишные строки наконец уже. strlen() выдает длину строки, не считая '\0' на конце, и в результате ты не копируешь '\0' в strx, оставляя строку нетерминированной.
Не заметил сообщения. Если ты проверяешь раз в сутки, подумай о том, чтобы во время проверки срать в дерево как придется, а балансировать, когда проверка закончится. Можешь на этом выиграть время при проверке (а может и нет).
Обязанности:
разработка встроенного ПО для Linux (C, C++) и Windows (Visual C++, MFC) на платформе Intel x86, Freescale, сетевое взаимодействие по Ethernet;
сопровождение на объектах заказчика;
оформление документации;
возможны командировки.
---
Сопровождения на обьектах заказчика , как это понять? Яж вроде программист, нах мне ехать туда? Инет подключать?
> сопровождения на обьектах заказчика , как это понять
Приезжать с программатором и ноутбуком, чтобы накатывать апдейты прошивок, отвечать на вопросы, почему ваш продукт такое кривое говно и отлаживать на местах то, что не получается отловить на стенде.
Благодарю за поддержку. Надеюсь до кого-нибудь дойдет сея мысль.
>несколько гигабайт
Делол подобное на бинарном дереве, но быстро закончилась память. Посчитай примерно сколько оперативы нужно иначе или хэдуп или бд.
Иногда да, мы так ходили по администрации президента и ещё на н-ном количестве мест, которых даже на карте нет.
>выгрузка обновляется не чаще чем раз в сутки
Ну так отсортируй и ищи бинарным поиском, нахуя тут дерево городить.
А как сделать указатель сразу на весь массив, а не только на одну его ячейку?
> Посчитай примерно сколько оперативы нужно
В идеале памяти же нужно даже меньше чем сам размер выгрузки хешей, чтоб всё дерево в памяти постоянно держать, поэтому думаю что проблемы не будет, но в любом случае под это дело есть сервак с 64Гб оперативы который добивается при необходимости до 128Гб
> хэдуп
ох незнаю, помоему уж слишком тежеловесное решения для моей задачи, если юзать чтото готовое, то я бы выбрал redis
>>26937
> нахуя тут дерево городить.
по дереву можно просто рекурсией ходить, а значит уменьшается количество операций для поиска конкретного значения, т.е. быстрее будет работать, особенно если дерево балансированное
спасибо за ссылкую, надо подумать над этим алгоритмом
>64Гб оперативы который добивается при необходимости до 128Гб
чувак, возьми in-memory субд и перестань уже себе ебать мозг
мы понимаем что тебе очень хочется сделать свой велосипед, но повзрослей уже
Для работы с хэшами лучше всего подходит хэш-таблица.
А вообще попробуй sqlite перед тем как писать велосипед
>А как сделать указатель сразу на весь массив, а не только на одну его ячейку?
#include <stdio.h>
#include <stdint.h>
int main(int argc, char const argv[])
{
uint8_t a[256] = {};
uint8_t ptr;
size_t n = 128;
ptr = a;
a[n] = 16;
for (int i = 0; i < sizeof(a)/sizeof(a[0]); ++i) {
if ( i == n )
printf("a[%lu] = %u", n, *ptr);
ptr++;
}
return 0;
}
> чувак, возьми in-memory субд и перестань уже себе ебать мозг
Мне хочется ебать себе мозг, можно я еще чутку поебу? Если мне вдруг надоест я в курсе готовых in-memory решений, но я хочу свой велосипед, т.к. уверен что это будет быстрее.
> но повзрослей уже
тяночку завести?
>>26969
>Для работы с хэшами лучше всего подходит хэш-таблица.
ну выше над тобой уже посмеялись, ты толи задачу не понял, толи просто у тебя базворд сработал, услышал хеш, в голове щелкнуло hash table
ладно тебе, почти все такимы были, особенно те кто с PHP на Си переходил
>чем сам размер выгрузки хешей
Ссылка на хэш и джва узла = 64 * 3 = 24 байта на одну запись как минимум
чтоб прям охватывал?)
ну, можешь написать
#define UKAZATEL_SRAZU_NA_VES_MASSIV(ptr) ptr
и потом возвращать
return UKAZATEL_SRAZU_NA_VES_MASSIV(arr)
если тебе так будет спокойнее...
Очень смешно, лучше бы объяснил ему, что такое указатель и массив в принципе.
Но тебе насамом деле нужно сначало понять, что такое указатели и как с ними работать, а потом понять что возвращать массив (или указатель на массив), в нормальной ситуации нет необходимости, и лучше все делать через структуры
У меня на строку uint8_t a = malloc(size); жалуется
невозможно преобразовать "void " в "uint8_t *"
чем компилиш?
цэпэпэшным компилером компилиш чтоли?
А если у меня в функции над массивами происходят некоторые манипуляции, будет ли целесообразно прокручивать функцию в цикле дохуялион раз только чтобы вывести из функции в маин массив?
> будет ли целесообразно прокручивать функцию в цикле дохуялион раз только чтобы вывести из функции в маин массив?
расскажи лучше о себе, сколько тебе лет, в каком классе, каким компилером компилиш, какой осью пользуешся, в каком редакторе пишеш? Нам так будет проще понять твои проблемы и навести тебя на правильный путь
>не буду учить питон
я и не настаивал, но думаю тебе лучше начать с чегото другого, например с Go, там хотябы компиляторы не перепутаеш
Но как он на нём дошёл до указателей и массивов, или это версия K&R для особенных?
А что такого? В плюсах нет указателей и массивов?
Вероятно он смотрит в книгу по системе, а компилит в студии плюсовый код, можно и так, конечно, но вот некоторые фичи все таки есть.
K&R описывает С89, который полностью совместим с С++, за исключением вот этого случая. Поэтому лучше кастить, чтобы таких недоразумений не возникало.
В системе кастить не нужно, покрайней в мере если ты при объявлении переменной сразу ее инициализируешь.
Если ты инициализируешь ее дальше по коду, то кастить нужно только для увеличения читаемости.
Чтобы человек сразу понимал по касту какой тип у переменной.
А есть ли в С аналог partial?
Типа функцию можно раскидать по файлам? Например часть генерируется автоматически, а часть руками дописывается, и хочется в разных файлах это хранить. Но чтобы компилилось как будто писанное в одном файле.
>Richard M. Reese "Understanding and Using C Pointers. Core Techniques for Memory Management" (2013) - почитать, вкатиться в указатели.
>Еще более длинный список: http://www.iso-9899.info/wiki/Books#Learning_C:
>Understanding and Using C Pointers by Richard M. Reese: Horribly written, conflates language specification and implementation, and describes concepts confusingly and/or wrongly in many cases.
ВТФ анон? Почему советуешь говно?
(1) a function on page 87 uses pointers to memory that has already been deallocated, which is undefined behavior. The same function has redundant variables "length" and "currentPosition" -- one of the two would have been sufficient to accomplish the task.
(2) Elsewhere, Reese defines a linked list header structure with pointers to the head node, the tail node, and the current node. This structure is used at several later points in the book, but the reason for including a pointer to the current node is never made clear; none of the code in the book ever uses it, and indeed, it's difficult to see why it would be useful.
(3) While Reese explains the difference between the value 0 and the NUL character, in several places his code elides the difference, using the former where the latter would be more strictly appropriate (e.g., page 131 has `while (string != 0)` when `while (string != '\0')` or preferably `while (*string)` would be better style.
(4) Throughout, the book provides examples of infinite loops with break statements instead of using good structured style and having the break condition be the loop conditional.
(5) Surprisingly for a book that mentions the C99 and C11 standards often, there are a lot of references to using Microsoft Visual C++ as a compiler. Microsoft does not, and by all accounts never will, support C standards past C89. It is a C++ compiler, not a current C compiler. It mandates practices that are not C like in their philosophy, and Reese's code succumbs. For instance, he explicitly casts the return values from malloc and realloc to pointers of the appropriate type, which is not considered good C style. Good C code should be written in compliance to the C standard, not in conformance with the requirements imposed by a compiler geared to a different language.
Оператор k = k | 040000000; добавляет 1, которая не хранится в числе для экономии разрядов
Ебать, пикча откуда то взялась
Книжки в шапку предлагали все кому не лень. Анону понравилась эта. В шапке еще и хардвей есть, на который говна гораздо больше лилось.
>>27395
> difference between the value 0 and the NUL character
Придирки, там в обзоре каждой книги десятки подобных мелких придирок, которые ни на что не влияют.
> infinite loops with break statements
Не читал, как там конкретно, но часто такое имеет смысл и бывает более читаемо.
> Microsoft does not, and by all accounts never will, support C standards past C89
Хуйня, в студии давно можно писать на C11 (по большей части).
>>27406
Нихуя непонятно, что тут имеется в виду. Больше контекста есть?
040000000 - восьмиричное число (обрати внимание на ноль в начале), работает как любые манимуляции с битами
Не очень понятно, что ты подразумеваешь под partial.
>Например часть генерируется автоматически, а часть руками дописывается
void yoba(int i, int j) {
if (i == j) {
#include "generiruetsa_avtomaticheski.inc"
}
}
Это простейшим момент. Дальше в мейкфайле прописываешь вызов скрипта, который генерирует "generiruetsa_avtomaticheski.inc". При этом снаружи от инклуда ты можешь дефайнить что-то, например, типы данных:
//main.cpp
#define DATATYPE float
#include "yoba_file.h"
#undef DATATYPE
//yoba_file.h
typedef struct {
} yoba_ ## DATATYPE;
сгенерирует тебе yoba_float
Вот реальный код, который это использует
https://github.com/ampl/gsl/blob/master/cblas/ccopy.c
Но ведь partial - это всего лишь аргументы по умолчанию.
#define open_binary_read(filename) fopen(filename, "rb")
>Не очень понятно, что ты подразумеваешь под partial.
Ну вот это например:
http://www.tutorialsteacher.com/csharp/csharp-partial-class
>>27429
Спасибо!
Двощик, не могу сконверить wchar_t в UTF-8. Конверчу через iconv, возвращает всегда 0 (типа, 0 байт сконвертировано).
Кот: https://ideone.com/nxH64Z
Где я долбоёб?
Почитай, что именно возвращает iconv.
> Где я долбоёб?
iconv модифицирует указатель output таким образом, чтобы он указывал на оставшуюся часть буфера (после сконвертированного текста) таким образом, чтобы было удобно дописывать в него последующими iconv. Решение спорное, но у тебя ничего не работает именно потому, что ты возрващаешь указатель не на начало буфера.
Решительно не понимаю и, при всем желании, не могу быть толерантен к тем, для кого существует понятие "вкат в указатели". Во что там вкатываться? Это каким надо быть ...?? Можно любую книжку по ассемблеру взять и теоретическое введение сказочкой на ночь почитать, потом в процессе K&R указатели сами собой мысленно изобретутся еще до главы про них.
>при всем желании, не могу быть толерантен
Держи нас в курсе.
Как же заебали эти токсичные пидоры с даннингом-крюгером.
Я, конечно, всегда сдержанно объясню, когда кто спросит, но внутри подгорает каждый раз. Это ж какой-то мазохизм непоследовательного изучения. Быть может, романтику находят в волшебном мире программирования из частных случаев и тупых вопросов, но это ни разу не проще, чем недельку-другую правильную теорию покурить.
Нет, в дереве O(log N), где N - количество объектов в дереве, в хэштаблице при правильно подобранной хэш-функции почти всегда если коллизий нет O(1).
>O(1)
>O(log N)
Мохнатое О для пидоров, ты же знаешь
>если коллизий нет
>если кэш не прогрет
>если Луна в зените
>по дереву можно просто рекурсией ходить, а значит уменьшается количество операций для поиска конкретного значени
По сравнению с бинарным поиском? Ты бредишь, число операций будет одинаковым.
Почему не имеет?
Например с теми же сортировками ты можешь сравнить какой-нибудь пузырёк с пирамидальной на одном и том же наборе данных и объяснить почему пирамидальная будет быстрее.
Вполне себе вариант, как по-твоему алгоритмы вообще оцениваются, и по каким требованиям ты выбираешь один из них, если не смотришь на оценки?
Заранее знаешь какой из них подойдёт лучше в твоём случаеопять же исходя из математики лол?
Для бинарного поиска нужен отсортированный массив, вставка в дерево стоит намного меньше по времени, чем вставка в массивне в конец, даже если ты будет использовать подобие deque дерево все равно будет быстрее на вставке.и соответственно удалении
Нахуя тебе вставлять в массив? Берешь 2 структуры данных, массив и хэш, массив размером в гигабайты, в хэш вставляешь текущую инфу. Ищешь и там и там. Раз в сутки их сливаешь, скидывая из оперативки на жесткий диск, и читая обратно.
А бинарное дерево размером в несколько гигабайт из которых две трети это указатели на ноды дерева, это так себе хуитка для этой задачи.
>и по каким требованиям ты выбираешь один из них, если не смотришь на оценки
Пишу оба и замеряю скорость, реализации невозможно оценить.
Мне 30 лет, а вот ты скорее всего учишься со своим "маам ну че он так говорит".
> Почему не имеет?
Потому что, сравнивая пузырек или selection sort со сложной сортировкой на практике, ты обнаружишь, что на в массивах с небольшим количеством элементов (меньше 10) пузырек заметно быстрее (посмотри реализацию qsort в glibc, они там до insertion sort деградируют в конце концов как раз по этой причине). Потому что кроме количества операций, есть еще разная цена операций, spatial locality, вот это все. И все это никак не отражается в O-большом, которое оценивает сферический алгоритм в вакууме, а не поведение реального кода на реальной машине. Поэтому да, как написали выше, это всего лишь оценка роста сложности, не более.
О большое оценивает алгоритмы при росте нагрузки, твой Кеп, да и на 10 элементах по факту вообще без разницы какой алгоритм юзать, meh
Я не вникал глубоко в вопрос. Мне кажется ты ошибаешься. Маршрутизацию сетевых запросов реализуют исключительно на деревьях.
> Маршрутизацию сетевых запросов реализуют исключительно на деревьях.
Делается аппаратно, внутри ассоциативная память. https://en.wikipedia.org/wiki/Content-addressable_memory#Example_applications
Есть что-то а примете?
в сферическом C11 в вакууме потоки есть, но glibc как-то не парится, ибо кому они нужны, когда есть POSIX...
А зачем glibc париться, если в линуксе код с C11-потоками уже давно отлично собирается с -lpthread?
То есть, таки приствуют соответствующие стандарту C11 обертки вызовов pthread_create и т.д., как это сделано в std::thread для C++? Что-то у меня получалось инклудить <thread.h>...
Какая разница аппаратно или программно? Если поиск в хэш-таблице настолько быстрый, то зачем деревья? Роутинг в веб-фреймворках тоже реализуют с помощью деревьев. Почему так?
Ээээ, а с чего ты взял, что хэш быстрей? Хэш вычисляет и находит боженька за тебя?
>-lpthread
нужно юзать просто -pthread (без -l), так gcc принудительно собирает все зависимости с подержкой мультитредовости с тред-сайфовым подходом
Поиск в хэш-таблице в среднем проходит за O(1), в худшем случае конечно за O(n), а в дереве за O(log n).
Подсчет хэша - алгоритм, который тоже имеет длительность работы, вот о чем тебе говорят.
Для упаковки данных. Например заголовки различных протоколов упаковывают в структуры. Это только первое, что в голову пришло. Ну, или чтобы образовать осмысленные связи между данными. ООП начался со структур. От классов отличаются тем, что поля структур видны отовсюду и могут быть изменены в рантайме без методов-акцессоров, а у классов по инкапсуляции недоступны и нужны методы-акцессоры для их изменения.
подожди-подожди
какой то дебил, который даже не удосужился загуглить, задает тупейший вопрос и ты сразу же бросился отвечать?
если я тя в офисе попрошу за сигами сбегать, тоже метнешся?
Эххх, ну придётся. Тебе какие? Себе ведь тоже тогда возьму.
Не душни, анон. Мне просто не с кем пообщаться.
Мне тоже пожалуйста. LD красные, не ебет если в ближайшем не будет
Не агрись. Тред для тех кто учится, а не для гуру.
>поля структур видны отовсюду и могут быть изменены в рантайме
Это весьма хуево. Как с этим бороться?
ДВАЧУЮ
пиздовать к крестоблядям.
А если серьёзно, то не менять их и всё. Тыж программист или кто? Вот и не трогай то, что трогать не нужно. Ну, или можешь приделать выбрасывание ошибок, как только поля структур будут меняться без твоего ведома(неявно), либо сделать эти поля константными, чтобы совсем их не менять. Это в теории всё. Я не знаю зачем вообще с этим бороться. Это как бороться со сладкими конфетами и выбрасывать их в мусорку вместо того, чтобы их есть.
Но подожди, это получается любой хацкер сделав дамп оперативы, получает полный доступ к архитектуре?
Попробуй libatspi чёт такое.
Продолжать писать простые, напиши несколько простых, объедини их в более сложную.вообще это странно, возможно ты не умеешь разделять задачу на более мелкие?
Память это набор нулей и единиц, не знаю, что он там делать будет.
все сломает, особенно лаба1.с
> поля структур видны отовсюду
> Это весьма хуево. Как с этим бороться?
Есть идиоматичный код (который, кстати, невозможно повторить на крестах с этими ихними классами):
foo.h:
typedef struct foo foo;
foo ∗foo_create(void);
void foo_destroy(foo ∗);
void foo_do_smth_useful(foo ∗);
и другие методы...
foo.c:
#include "foo.h"
struct foo { int private_data; };
foo ∗foo_create(void) { foo ∗obj = malloc(sizeof(∗obj)); obj->private_data = 0; return obj; }
void foo_do_smth_useful(foo ∗obj) { obj->private_data = 42; }
и другие методы...
Алсо, есть такая штука, называется документация, там можно описать, что в структуре разрешено менять напрямую и как именно. Можно написать, что ничего нельзя, это хороший подход.
не думал, что один и тот же человек. А толстота про хакера. Каким образом инкапсуляция (политика компилятора с private модификаторами доступа) остановит хакера, способного "словить дамп оперативы"? Вот и подумал, что рофл. Уж больно умный термин присутствует в перемешку с откровенной ерундой, вроде этого >>1314292 . Впрочем, "толстота" - не вполне уместная оценка, такое даже забавно читать)
большие слова обычно выравнены под 8-байтовую сетку, можно за что-то похожее на указатели зацепиться
Ну это да, но это слишком нужно дрочиться.
да и все равно ось тебя не пустит по чужой памяти ползать, даже если ты на уровне ядра что-то поменяешь можно просто панику словить
> да и все равно ось тебя не пустит по чужой памяти ползать
Иногда есть /dev/mem из юзермода. Из ядра есть все, что угодно. А еще ниже есть дамп через DMA.
Так что вы мне голову морочите. Я же изначально говорил, что деревья используют для таких задач. Но какой-то анон сказал, что хэш-таблицы быстрее.
а junior hacker вакансии и не предлагаются)
а свет - это волны (частицы). Что шпион будет делать с биноклем? Средства интерпретации сигналов (аналоговых/дискретных) существуют. Естественно, несанкционированное пользование на порядок сложнее. Это не новость, тупых хакеров не бывает.
У человека в кратковременной памяти помещается примерно 7 объектов, без структур ты быстро утонешь в сложности и ничего писать не сможешь
Для человеков с кратковременной памятью придумали IDE, в которые такой хуйней не страдают.
printf("%c = %d\n", "A", "A"); //{ = 1073646356
printf("%c = %d\n", "a", "a"); //$ = 1073646372
Как пофиксить чтобы char кодировался в ASCII?
Ты хотел одинарные кавычки вокруг символов. Сейчас ты выводишь адреса (или части адресов) строк, а не численные значения символов.
Пиздец ты тупой
Лол. Он получит маш. код, переведет в Асм (не в ручную конечно) и сделает все необходимое.
В теории нет (undefined behavior), на практике можешь. Чего конкретно ты хочешь добиться?
Посмотреть, каким образом запушивается все в стек
Ну короче программирую Си с асм вставками, довольно интересно
> Посмотреть, каким образом запушивается все в стек
Ну есть же отладчики. Но если очень хочется, то примерно так (тут повсюду UB, поэтому в продакшене использовать не стоит, собирать как-либо кроме -O0 не стоит тем более). Чуть правильнее было бы переписать на va_list/va_arg, но оно не перестанет быть UB.
void foo(int arg, ...)
{
uintptr_t ∗stackptr = (uintptr_t ∗) &arg;
for (size_t n = 0; n < 10; n++, stackptr++) printf("%p: %lx\n", stackptr, ∗stackptr);
}
int main(void)
{
foo(0); // Аргумент нужен как точка отсчета, сам по себе не используется.
}
Ну это был не я, собственно, я и не написал, что нужно использовать хэш для его задачи.
А то. Это называется format string attack
не все в стек пушится. Например, на Linux под x86_64 сначала выбираются RDI, RSI, RDX, RCX... для float свои регистры есть тоже
С вертухи тебе бы въебал, чмоха малолетняя
>очевидно же
что такое "O" так и не понял, ну да ладно, видимо это какието секреты математиков
>Обозначение «„O“ большое» введено немецким математиком Паулем Бахманом во втором томе его книги «Analytische Zahlentheorie» (Аналитическая теория чисел), вышедшем в 1894 году. Обозначение «„о“ малое» впервые использовано другим немецким математиком, Эдмундом Ландау в 1909 году; с работами последнего связана и популяризация обоих обозначений, в связи с чем их также называют символами Ландау. Обозначение пошло от немецкого слова «Ordnung» (порядок).
И меня этот процесс настолько затянул и воодушевил, что я захотел повысить собственное ЧСВ и научиться писать велосипеды для операционок, чтобы их можно было установить на любом компе, ну и конпилировать, конпилировать и еще раз конпилировать. А еще я думаю, что это будет плюсом, когда я пойду перекатываться в офис и черкану строчку об опыте на чем-то, кроме пхп.
Так вот, что мне для этого выбрать: каконичный С или же С++? Вроде как С++ мое чсв раздует до предела, но вдруг я его не осилю, а мне еще работать нужно будет.
ну да, стек растет сверху вниз, виртуальные адреса 0x7fffffffffff-0x7fffff000000, а пушится все в обратном порядке, чтоб потом выбиралось в прямом, иначе бы не понять было, с какого адреса начинается argv, например, а так посмотрел argc, что лежит по адресу RSP, и дальше за ним уже собираешь все до NULL...
судя по всему, тебе хочется именно того, что даст чистый Си. Начав с крестов и уснешь скоро (там инфы как воду из ведра пить), и пробелы в low-level знаниях останутся. Вообще, прелесть C++ доступна сишникам, девственные же джависты и прочие макаки, как ты себя обозвал, вряд ли извлекут пользу из кажущейся бессмысленной запутанности.
O(1) означает, что процессору нужно сделать одно и то же количество операций для поиска по коллекции из 100, 1000 и 1000000 элементов. O(n) значит, что количество операций растет пропорционально размеру коллекции.
маняматика и жидовские выдумки ненужны
Я думаю O(1) одна операция. Постоянное время имеется ввиду сколько времени нужно конкретному процессору для выполнения 1 операции.
O(n) умножаем это постоянно время, допустим 0,001 секунды на n. Где n это обычно количество лупов в цикле, обычно соответствующая количеству элементов в массиве.
Но возможно манятеория.
Понял, спасибо, осяду тут у вас тогда.
Программа на си компилируется в байт-код. Как можно скомпилировать байт код обратно в программу на си?
Использовать декомпилятор или же продизассемблировать и восстановить исходный код.
си в байт код ??? не, не слышал. Жава была замечена, а си нет.
https://youtu.be/guinn2k1PGE?t=340
Нужно быть ебанутым, чтобы снимать видео по программированию и совсем ебнутой макакой, чтобы их смотреть. Пошёл нахуй отсюда, пидор грязный.
Я не телепат, чтобы видеть то, что у тебя там. Ты не можешь присвоить одну сишную строку другой с помощью =, нужно использоваться strcpy.
Прочитай Кернигана и Ричи про строки и после этого вторую главу вот здесь faqs.org.ru/progr/c_cpp/cfaqrus.htm , может начнешь понимать, что ты делаешь.
>в 2018
2019.
>Пидор грязный-то ты
Нет ты. Видео-дауны самые поехавшие дауны, с таким же успехом можешь Сю по шебм объяснятьб прямо сразу в фап-треде.
Вот реально поддвачну этого >>29226
А от себя добавлю:
Я начал с C#, у них в шапке очень хорошая книга. Дошел до 2/3 книги. В какой-то момент появляется ощущение, что вроде все ясно, но чего-то не догоняешь, как-будто обладаешь разнозненными фактами а не знанием.
Я реально жалею о потраченном времени, надо было начинать с сишечки.
>Нет ты. Видео-дауны самые поехавшие дауны, с таким же успехом можешь Сю по шебм объяснятьб прямо сразу в фап-треде.
Самые поехавшие дауны - это вот эта ебанутая публика, которая заходит в тред чисто чтобы похамить и самоутвердиться. Гуглишь что-нибудь, и знаешь, что если гугл дал тебе лор или какую-то еще рашкопомойку, то можно не кликать, потому что ответ на вопрос будет в лучшем случае на второй странице - до этого такие уникальные мамкины специалисты будут нести хуйню, о том, какой задавший вопрос мудак. Хотя ты и есть тот самый гнойный пидор, которому лучше бы заткнуться и убить себя.
Что касается видео, ничего плохого в них нет, если само видео пилит профессионал. Это, конечно, не случай того, что он принес, но ты-то не об этом сказал.
>каконичный С или же С++? Вроде как С++ мое чсв раздует до предела, но вдруг я его не осилю, а мне еще работать нужно будет.
Си, потом вдумчиво читать Дизайн и эволюцию, потом книги Мейерса и Саттера.
Тогда С++ вообще не будет казаться сложным. Потому что он и не сложный особо, здесь даже не нужно знать, что такое ковариантность.
Я захожу в тред так как мне Ся нужна для низкоуровневой логики и апать скиллы. Читаю сам и учусь, вопросов не возникает, читаю вопросы тех кто изучает и решаю их для себя, это достаточно полезно. Ни разу за свою жизнь не видел хоть одного человека научившемуся чему-либо по видео. Впрочем, мне похуй, если тебе нравится плодить этот рак здесь. Но всё-таки я не пидор, и даже на трапов ни разу не дрочил.
Самая важная книжка Страуструпа
mingw через msys2, tcc, pelles c 8
>Впрочем, мне похуй, если тебе нравится плодить этот рак здесь
Мне тоже не нравится плодить рак, но рак - это ты. Из вопросов ньюфагов рождаются обсуждения так или иначе. Из "ололо ты мудак" не рождается нихуя, кроме вот этой уебанской атмосферы рашкофорумной дедовщины. У меня от нее бомбит, да.
А видео - это старый добрый известный со средневековья формат лекций, а так же мастерклассов и прочей хуйни, но переведенный в цифру. Если чел никогда не видел как программируют, почему не посмотреть это на видео?
Литерал массива символов и присваивание его указателю такого же типа (char).
Предположим, что поиск из 10 элементов занимает 1 секунду. Значит, если n = 10, значит поиск будет занимать 1 секунду, если n = 1 000, поиск будет 100 секунд.
Это обозначение временной сложности алгоритмов. Бывает сложность: O(1), O(n), O(log n), O в степени n.
Не в байт-код, а в ассемблерный может, и может в машинный. Байт-код это машинно-независимый код, который исполняют не процессоры, а виртуальные машины, например: JVM, CLR, BEAM, Dalvik, etc.
>В какой-то момент появляется ощущение, что вроде все ясно, но чего-то не догоняешь, как-будто обладаешь разнозненными фактами а не знанием
Видимо ты просто читал, но не практиковал. Обычно это происходит из-за этого. Тут дело не в языке.
Ещё LLVM, который с собой clang таскает, тоже популярная штука, JIT вроде ещё есть, если я ничего не путаю.
сам пользуюсь онли gcc
Еще раз. O-большое ничего не говорит о конкретном числе операций или секундах. Оно говорит о том, по какой функции будет увеличиваться количество операций при росте n. Это позволяет приблизительно сравнивать разные алгоритмы.
>>29666
> Байт-код это машинно-независимый код
И это как-то мешает тебе компилировать Си в байткод любой из перечисленных вм? С точки зрения компилятора разницы между байткодом и машинным кодом нет. К тому же, если вспомнить, что внутри x86 фактически RISC-based интерпретатор, то возникает вопрос, чем вообще "машинный" код x86 отличается от байткода.
>Еще раз. O-большое ничего не говорит о конкретном числе операций или секундах.
Еще как говорит. O большое говорит о времени выполнения алгоритма. Не о секундах, не о конкретном времени, а об отношении времени к длине коллекции. O(1) означает, что операция поиска в коллекции будет всегда проходить за одинаковое количество времени, то есть за константное время, независимо от длины коллекции.
>>29675
>Оно говорит о том, по какой функции будет увеличиваться количество операций при росте n.
Какой еще функции?
>>29675
>чем вообще "машинный" код x86 отличается от байткода.
Тем, что машинный исполняет конкретный процессор, а байт-код виртуальная машина.
>>29675
>И это как-то мешает тебе компилировать Си в байткод любой из перечисленных вм?
Не мешает, но обычно такое не делают. То кто задавал вопрос просто ошибся, назвав машинный код байт-кодом.
> Тем, что машинный исполняет конкретный процессор, а байт-код виртуальная машина.
Исполняет виртуальная машина в процессоре.
> Не мешает, но обычно такое не делают
Правда? А я вот помню, как в свое время массово компилировали Си в AVM (Flash) и еще в JS с помощью Emscripten (тут немного не то, потому что вм у браузеров разные, и опкоды напрямую не доступны).
> Какой еще функции?
Той, которую ты пишешь в скобочках у O.
> об отношении времени к длине коллекции
Только когда n достаточно большое, причем где именно находится это "достаточно" не оговаривается. Например, обрабатывая массив данных на HDD, ты можешь написать алгоритм c O(n), который обгонит O(log n). Но с ростом количества жестких дисков, все детали реализации перестанут иметь значение, и рано или поздно O(n) обязательно станет медленнее O(log n).
>Той, которую ты пишешь в скобочках у O.
Такая терминология не используется. Это ты от себя придумал.
>Например, обрабатывая массив данных на HDD, ты можешь написать алгоритм c O(n), который обгонит O(log n). Но с ростом количества жестких дисков, все детали реализации перестанут иметь значение, и рано или поздно O(n) обязательно станет медленнее O(log n).
Ну ка расскажи как? Ты не понимаешь алгоритмическую сложность. Она не зависит от железа. O(n) всегда дольше чем O(log n), на малых величинах оно еще будет рядом, но не быстрее как ты говоришь, а на больших разница будет в тысячи раз. Увеличение коллекции в 100 раз, увеличивает время поиска по O(log n) всего в 2 раза. А в случае O(n) время увеличиться в 100 раз.
> Ну ка расскажи как?
Ну например, если у тебя почти полностью заполненный SSD, ты упираешься в стирание блоков, и алгоритм, который экономит записи, может очень много выиграть у алгоритма, который о них не беспокоится. В случае HDD алгоритм, читающий последовательно, выиграет у random seek.
> а на больших разница будет в тысячи раз
Да. Никто и не спорит.
Причем здесь диски? Алгоритм не зависит от железа. O(n) означает, что поиск будет проходить по всем элементам, там нет никакой экономии, экономия как раз при O(log n).
Уроки-то сделал?
> Программа находится в оперативной памяти
А еще она может быть в кэше, а еще она может выполняться из ROM или какого-то вида EPROM напрямую. Но это не так важно, потому что данные тоже могут лежать где угодно, и время выполнения алгоритма будет зависеть от его реализации и характеристик устройства, хранящего данные. С ростом n шанс, что реализация алгоритма с O(n) обгонит реализацию c O(log n) быстро уменьшается до нуля, но и говорить, что O(n) всегда медленнее O(log n) неправильно.
Ты понимаешь, что ты сейчас разговариваешь с образованным, взрослым человеком, который зарабатывает на жизнь своим трудом? Ты мне советы даешь, как учиться?
Что значит не практиковал, уёбище?
Примеры и задачи решал, какая ещё практика в учебнике, придурок?
Тебе башку прострелить?
Открой книгу "Построение и анализ вычислительных алгоритмов" авторов Альфред В. Ахо, Джон Э. Хопкрофт, Джеффри Д. Ульман. И прочти главу про сложность алгоритмов. В ней ясно дано понять, что увеличение производительности железа, почти не дает увеличения производительности программ. Потому что это мизерные цифры, по сравнению с потенциалом ускорения от использования оптимальных алгоритмов.
Правильный алгоритм может давать ускорение в тысячи раз. Увеличение мощности железа в тысячи раз, может уже не произойти никогда. Так как закон Мура уже не работает.
Программа не может выполняться из ROM, она должна быть загружена в RAM.
Твои посты состоят из набора не связанных ключевых слов.
> Открой книгу "Построение и анализ вычислительных алгоритмов"
Я же говорю, что теоретик.
> Программа не может выполняться из ROM, она должна быть загружена в RAM.
А тебе никогда не рассказывали, что для того, чтобы воспользоваться DRAM после подачи питания, ее нужно инициализировать, причем относительно длинным кодом: зависит от контроллера памяти, но обычно это несколько килобайт? Памяти нет, но код нужно выполнить. Или даже хуй с ним, у нас SRAM. Но кто же скопирует код из ROM в SRAM? Как быть? Правильно! Нужно оторваться от книжек про алгоритмы и начать писать код почитать что-нибудь про архитектуру компьютера.
>А тебе никогда не рассказывали, что для того, чтобы воспользоваться DRAM после подачи питания, ее нужно инициализировать, причем относительно длинным кодом: зависит от контроллера памяти, но обычно это несколько килобайт? Памяти нет, но код нужно выполнить. Или даже хуй с ним, у нас SRAM. Но кто же скопирует код из ROM в SRAM? Как быть? Правильно! Нужно оторваться от книжек про алгоритмы и начать писать код почитать что-нибудь про архитектуру компьютера.
Это ты теоретик. Пишешь непонятно о чем вообще. Во-первых, это не имеет ничего общего с языками высокого уровня. Во-вторых, мы обсуждали задачу поиска в огромной коллекции. При чем тут инициализация памяти вообще? Вот сядь и попиши код. Реши наконец хоть одну задачу. Ты только и делаешь, что кидаешься ключевыми словами, которые вообще не имеют ничего общего с обсуждением.
Он заморочился, поэкспериментировал, оказалось что если в массиве до 1000 элементов, линейный поиск быстрее.
Коллизии всегда будут, если у тебя не perfect hashing. Поэтому таблицу делают размером +10-30% от требуемого.
Вы видите копию треда, сохраненную 2 марта 2019 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.