Это копия, сохраненная 27 апреля 2019 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
Пожалуйста, пользуйтесь 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 (драфт)
- 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 помогает читать сложные сишные декларации.
Прошлые треды:
- №40: https://arhivach.ng/thread/428550/
- №41: https://arhivach.ng/thread/434018/
- №42: https://arhivach.ng/thread/438066/
Первыйнах
Просто и без задней мысли.
> Все твои ошибки - от отвратительнейшего говнокода.
Что именно говнокод, помимо того что я вместо символьной переменной использую массив и все пихаю в нулевой же массив? По идее я дальше буду в этот массив уже нужный текст из файла пихать. Да и я только учусь + пишу на мобиле.
>В частности, от всех этих кучах лишних getc() и нечитаемых temp[0].
В чем проблема моих getc?
>В данном случае ты скорее всего проебываешь EOF еще выще, в строке 57, где ты его нихуя не проверяешь (или в других местах того цикла).
Я не могу ничего проебать до последнего цикла. Ведь он выводит текст с того момента где закончился прошлый цикл и до конца. Если бы EOF был раньше, то он бы текст из файла не выводил, не?
Вот код целиком. Где ошибка?
https://pastebin.com/cpCSDt2M
Если уж ты пишешь на мобиле, то скачай себе шланг. Он на любой дистрибутив ставится. Очевидно ещё понадобится эмулятор терминала.
А код твой просто бегиннер левел хуита, в очередной раз доказывающая, что учить программирование по хеловорлдам - мертвый номер. Почитай книги из шапки.
И да, код придется писать в одной области видимости.
> Что именно говнокод
Ну например, ты не можешь определиться, то ли тебе нравятся printf/scanf, то ли putchar/getchar. Например, тебе не рассказали про break в 51 строке.
> По идее я дальше буду в этот массив уже нужный текст из файла пихать
Ну вот когда будешь, тогда и будет повод притащить массив. А сейчас его нет.
> Вот код целиком. Где ошибка?
Если искомая строка встречается в файле, тогда все должно работать. Если не работает и тогда, попробуй в последнем printf() перед \n добавить в конце строки, т.е., "\n\nEnd\n". Если поможет - проблема вообще в твоем андроиде или IDE, которая не сбрасывает буфер stdout при закрытии.
А вот если строка не встречается в файле, происходит вот что. Если файл не заканчивается на \n, ты будешь получать EOF от getc() в строке 60 и никогда не дождешься \n в цикле в строке 59. Если файл заканчивается на \n, то сначала ты вроде бы из этого злополучного цикла выйдешь нормально, но тут getc() в строке 62 вернет тебе EOF, а так как ты из for не выходишь, то в следующей итерации все равно попадешь в цикл в строке 59, где и зависнешь нахуй.
> В чем проблема моих getc?
В предыдущем абзаце. В том, что после каждого getc() по-хорошему должно быть if (c != EOF) { сделать что-то вменяемое }. Вот если ты попробуешь расставить все эти ифы, ты поймешь, почему разбросанные везде getc() - это не очень хорошо.
Кстати, в 30 строке ты мог бы сделать char temp[200] = {0}, а не крутиться в цикле. Так быстрее и короче.
>>77677
> Сколько можно безопасно(преносимо) выделять место на стеке?
Ноль. Где-то всего пара сотен байт памяти, доступной под стек (бывает и меньше, но там на Си не пишут). Где-то мегабайты. Если пишешь либу под embedded, считается хорошим тоном посчитать и документировать требуемый размер стека, чтобы пользователи заранее знали, подойдет она им или нет. Если у тебя обычные компы и текстуры... ну, в винде линкеры по умолчанию резервируют метр, например (но можно указать хоть сто ключом линкеру).
На чем пишешь? Размер кучи может определяться как на стороне компилятора, так и на стороне ОС. В gcc например можно спокойно менять размер кучи, и получать и 244кб, и 1мб, и 50мб, поэтому эмбедщики его любят. Ну а виндоус студия это просто говно
Ты для начала научись стек с кучей не путать, а потом рассказывай, что и где говно.
В embedded есть некоторая (да и то, сейчас ртос везде), в "больших" компьютерах давно уже никакой взаимосвязи нет.
А чем кланг лучше? Вроде же гну коллекция топовые компиляторы.
Так что не так с кодом? Я и форматировать пытаюсь, насколько это можно с мобилы, и имена осмысленные давать.
Всмысле обучение по хэлоувордам ? Я в процессе чтения как раз, Керригана до функций дошел и уже парочку своих внедрил в свою другую программу. Пока вроде более-менее понятно. Но я параллельно нужные для работы программы делаю потихоньку на мобиле.
Критиковать стиль моего говнокода конечно весело, но все же почему мой код в конце не доходит до EOF и не выходит из цикла?
Текст файла:
01 101 201 301
02 203 101 111
03 934 110 234
04 049 110 136
05 213 101 137
Нисколько. На стеке нельзя ничего выделять кроме мелких локальных переменных, так же нельзя передавать в функции и возвращать большие вещи. То же касается рекурсий, это раковый говнокод, засирающий стек впустую, вдобавок непредсказуемо. Стек это не память для данных, а служебное системное средство для работы программы и его размер ограничен.
Я не он. Но зачем ты побайтово из файла читаешь? Почему бы в твой temp не считать сразу пачкой?
>мой код в конце не доходит до EOF и не выходит из цикла
Кто тебя знает. Твой код на gcc 7.3.1 отлично отработал.
"Not found!
Not found!
Not found!
Works!
04 049 110 136
05 213 101 137
End"
Не дорого, а дешево. А на стеке бесплатно. На бесплатном не живут, бесплатно это особый исключительный случай, которым пользоваться нужно только в особенных случаях, где ты точно знаешь что делаешь и совершенно необходим прирост скорости. То есть — никогда такого случая тебе не представится с вероятностью 99%.
> Ну например, ты не можешь определиться, то ли тебе нравятся printf/scanf, то ли putchar/getchar.
Так printf я использую для печати текста, а getchar в кусках где надо искать текст. Я же беру символ, сравниваю, потом беру ещё символ. а scanf я уже не помню нахуя я брал
> Например, тебе не рассказали про break в 51 строке.
Я до него в книге ещё не дошел, да. Не ебу что это, но полагаю выход из цикла.
> Ну вот когда будешь, тогда и будет повод притащить массив. А сейчас его нет.
Тут ок, согласен.
> Если искомая строка встречается в файле, тогда все должно работать.
Встречается. Я ищу 0 и 5 и в тексте это начала 5 строки. Программа же выводит весь текст после 05 как и положено.
>Если не работает и тогда, попробуй в последнем printf() перед \n добавить в конце строки, т.е., "\n\nEnd\n".
Не помогло.
> А вот если строка не встречается в файле, происходит вот что. Если файл не заканчивается на \n, ты будешь получать EOF от getc() в строке 60 и никогда не дождешься \n в цикле в строке 59.
Я же это предусмотрел. Цикл у меня же 31 раз пройдется и закончится. А нет, нихуя, действительно застревает. Не понял пока как исправить.
> В предыдущем абзаце. В том, что после каждого getc() по-хорошему должно быть if (c != EOF)
Чет не помогает расставленный if данном случае выходить из цикла. Сделал так, все равно не помогает. Что не так?
else
{
printf("Not found!\n");
while (temp[0] != '\n')
temp[0] = getc(fp);
if (temp[0] == EOF)
break;
temp[0] = getc(fp);
}
> Кстати, в 30 строке ты мог бы сделать char temp[200] = {0}, а не крутиться в цикле. Так быстрее и короче.
Не знал что так можно, пока в книге такого не было.
> Ну например, ты не можешь определиться, то ли тебе нравятся printf/scanf, то ли putchar/getchar.
Так printf я использую для печати текста, а getchar в кусках где надо искать текст. Я же беру символ, сравниваю, потом беру ещё символ. а scanf я уже не помню нахуя я брал
> Например, тебе не рассказали про break в 51 строке.
Я до него в книге ещё не дошел, да. Не ебу что это, но полагаю выход из цикла.
> Ну вот когда будешь, тогда и будет повод притащить массив. А сейчас его нет.
Тут ок, согласен.
> Если искомая строка встречается в файле, тогда все должно работать.
Встречается. Я ищу 0 и 5 и в тексте это начала 5 строки. Программа же выводит весь текст после 05 как и положено.
>Если не работает и тогда, попробуй в последнем printf() перед \n добавить в конце строки, т.е., "\n\nEnd\n".
Не помогло.
> А вот если строка не встречается в файле, происходит вот что. Если файл не заканчивается на \n, ты будешь получать EOF от getc() в строке 60 и никогда не дождешься \n в цикле в строке 59.
Я же это предусмотрел. Цикл у меня же 31 раз пройдется и закончится. А нет, нихуя, действительно застревает. Не понял пока как исправить.
> В предыдущем абзаце. В том, что после каждого getc() по-хорошему должно быть if (c != EOF)
Чет не помогает расставленный if данном случае выходить из цикла. Сделал так, все равно не помогает. Что не так?
else
{
printf("Not found!\n");
while (temp[0] != '\n')
temp[0] = getc(fp);
if (temp[0] == EOF)
break;
temp[0] = getc(fp);
}
> Кстати, в 30 строке ты мог бы сделать char temp[200] = {0}, а не крутиться в цикле. Так быстрее и короче.
Не знал что так можно, пока в книге такого не было.
Ты хочешь сказать, что я 2 года изучаю и практикую С, каждый день кайфую от того что пишу на нем свои проектики - все это пыль, потому что у меня нет математического образования?
И да, дай мне ссылочку на свой github, хочу взглянуть на код, опытного гуру с математическим образованием!
>25 лет опыта работы в сложных проектах и математическое образование.
и 90 на удаленке, все что удалось выбить
..
Времени мало свободного.
Я инвестирую только свое время, а инвистировать время в любимое дело, я люблю. То что я не сяду жопой на офисный стул с С, мне по барабану. Я смогу придумать, что-то свое, и на хлеб с маслом мне всегда хватит.
Что-то у меня идеи закончились. Хотя погоди... может у тебя в компиляторе char по умолчанию unsigned? Тогда EOF (-1) в temp[0] нихуя не влезает, получается 255, а 255 конечно же не равно -1 (c signed char оно тоже не особо влезает, но там после integer promotions сравнение прокатывает).
Нет. Линуксобляди не считаются.
а есть разница?
Да. А у тебя нет?
https://www.linux.org.ru/forum/talks/14635773?cid=14635913
>Для сишки мозги нужны
Зачем? Один из самых примитивных языков. Любой школьник в состоянии освоить.
Проверил код на ПК - все нормально работает. Потом сократил на Андроиде код только до вывода текста из файла и принтф и один хуй цикл до EOF не доходит. Походу на Андроиде реально EOF не работает.
> Походу на Андроиде реально EOF не работает.
Что за бред? Я тебе объяснил уже. Короткий фикс: signed int char temp[сколькотамнепомню]. Правильный фикс:
int c; while ((c = fgetc(fp)) != EOF) { putchar(c); }
>Сделал signed char
Опять на грабли наступаешь. Стандарт гарантирует int - не факт что вариант с signed char везде будет работать.
Ну я программирую для себя и вроде не припомню проблем с глоб. переменными.
Скорее всего компилятор их раскидает в разные сегменты, и вообще сомневаюсь, что ты программируешь на процессоре, который различает длинные и короткие указатели.
>если объявить глобальную переменную рядом с определением функции, то они скорее всего расположатся рядом в памяти и доступ к этой переменной из функции будет быстрее
лайфха~к
Почему бы вместо констант не использовать дефайны?
Например, вместо
const chat x = 100;
сделать
#define x 100
Ведь подстановка происходит в препроцессоре и не жрёт память.
Толсто.
https://ru.wikipedia.org/wiki/Си_(язык_программирования)#Высокий_порог_вхождения
Спецификация языка занимает более 500 страниц текста, которые необходимо прочесть, чтобы полностью овладеть языком и знать все его возможности. При этом на практике из этих возможностей ежедневно программистом будет использоваться лишь малая часть. Однако некоторые совсем не очевидные вещи требуется знать, чтобы писать безошибочный и качественный код.
Сам по себе язык является достаточно сложным, в связи с чем неопытным программистам будет достаточно сложно писать качественный код. В сочетании с тем, что язык даёт большую свободу действий и позволяет компилировать программы с ошибками, выдавая лишь предупреждения, сложность языка может приводить к появлению многочисленных ошибок и уязвимостей.
Уменьшает возможности отстрелить себе ногу.
Вообще читни что-нибудь типа Алена Голуба "Веревка достаточной длины, чтобы... выстрелить себе в ногу" . Там простые правила и советы почему так не стоит делать.
> Почему бы вместо констант не использовать дефайны?
Так и делают. В Си константы "ненастоящие", ты не можешь сделать, например: const size_t array_size = 100; static array[array_size]; Поэтому все используют дефайны. В крестах и других си-подобных языках это пофиксили.
>>78264
Это запрет брать адрес переменной. В остальном это ключевое слово игнорируется на абсолютном большинстве платформ абсолютным большинством компиляторов. Поэтому register в коде, написанном после 2000 - это признак либо микроконтроллера с собственным компилятором, либо ньюфага (обычно второе).
>>78263
> Спецификация языка занимает более 500 страниц текста, которые необходимо прочесть
На практике мало кто читал стандарт целиком. И вообще стандарт - для разработчиков компиляторов (одно описание restrict чего стоит). Программисту достаточно знать ключевые детали: какие есть фичи, и как делать нельзя/не стоит.
Твоя цитата никак не противоречит высказыванию анона >>77904. Си сам по себе - очень простой язык, его легко выучить, но писать качественный код (а особенно качественный, читаемый и производительный код) на нем гораздо сложнее, чем на других языках.
Переменные идут в d-cache, код в i-cache. По крайней мере на уровне L1 они различны, так что даже если они попадут в соседние виртуальные адреса тебе будет всё равно.
> так что даже если они попадут в соседние виртуальные адреса тебе будет всё равно
Не все равно. Можно выдумать ситуацию, когда будут проблемы с производительностью из-за того, что переменная и кусок кода попадают в один кэшлайн на многопроцессорной системе, где несколько ядер выполняют один и тот же кусок кода.
Кэши - это такой специальный сорт памяти в процессоре. А на пике скриншот из x64dbg, судя по уебищности интерфейса.
Выше читай. Анон спрашивал, не будет ли быстрее перемешивать переменные с кодом. А по умолчанию компиляторы и линкеры их разделяют, как у тебя на пике. Алсо, у тебя на пике хуевый линкер. Вполне достаточно трех секций (RX, RW, R).
Есть такой говнокод, но он не очень оптимальный.
int main(void)
{
float to2time = 58.566;
double milliseconds, intpart;
milliseconds = modf (to2time , &intpart);
int time = (int)to2time;
int seconds = time % 60;
int minutes = (time / 60) ;
printf( "LAP TIME: %02d:" "%d:""%3.f\n", minutes, seconds, milliseconds*1000 );
}
Нормальный код. Ну можешь div() притащить для секунд и минут, как сделал для миллисекунд, хотя особого смысла нет.
А никаких вариантов нет, чтоб повысить его универсальность? Так как у меня три переменные со временем и для каждой из них нужно плодить еще пять дополнительных переменных.
> три переменные со временем и для каждой из них нужно плодить еще пять дополнительных переменных
Функцию напиши, ну. Что-нибудь типа timestamp_split(float time, unsigned int ∗minutes, unsigned int ∗seconds, unsigned int ∗milliseconds); и заодно функцию, которая будет snprintf-ом форматировать время в строку, вызывая первую: timestamp_format(float time, char ∗buffer, size_t max_length).
Спасибо.
void fn(My_struct o) {
if (!o)
o = (My_struct)malloc(sizeof(My_struct));
}
My_struct *o;
o = NULL;
fn(&o);
Но в таком случае появляется ошибка "LNK2019: ссылка на неразрешенный внешний символ".
Вопрос, что можно сделать.
звездочки съели, но я думаю и так понятно.
Не понятно же на какой символ ругается
Это не имеет отношения к конкретной ошибке, но в строке 3 у тебя звездочка проебана. Надо ∗o = malloc(sizeof(My_struct)).
СерьезностьКодОписаниеПроектФайлСтрокаСостояние подавления
ОшибкаLNK2019ссылка на неразрешенный внешний символ "struct My_struct __cdecl fn(struct My_struct *)" (?fn@@YAPAUMy_struct@@PAPAU1@@Z) в функции _mainQueueD:\Labs\Queue\Queue\main.obj1
Да в том-то и дело, что никуда конкретно ошибка не отсылает.
>>78535
Забыл добавить, но не суть.
Если звёздочку в описании не съело, то ощущение что у тебя есть ещё вызов этой функции.
Оказывается такое происходит только когда я подключаю эту функцию с другого файла. Что к чему блядь?
Файл-то в проект добавил? Объявление в хедере (или где оно у тебя там) соответствует определению?
Ну вот простейший пример, при том если использовать функцию _fn, то все норм как бы. Я хуею в общем.
Я ебал эту хуйню, просто пиздец. Сидел 3 часа нахуй, щас просто создал другой проект и скопировал все туда – и все заебись. Спасибо вижла за приятное времяпрепровождение.
Статики в ебенях хранятся, и к ним ещё обращаться надо каждый раз:
https://godbolt.org/z/ps-gee (-x c включает режим чистого Си).
Да и присутствует вот такой перл:
mov eax, DWORD PTR i.1959[rip]
add eax, 1
mov DWORD PTR i.1959[rip], eax
И это ведь даже не потокобезопасно.
ладно бы adt на юнионах обсуждали или кодогенерацию на макросах
а то блядь, их года в год одно и тоже
студентики обоссаные
Мы знаем, что статики в ебенях хранятся. Мы говорили о том, что было бы, если бы статики НЕ хранились в ебенях, т.е., что-то типа:
func:
.some_loop:
mov rax,[var]
add rax,1
mov [var],rax
; some cond
jcc .some_loop
ret
align 8
var dq ?
> И это ведь даже не потокобезопасно.
А никто и не обещал, это не атомик. Ты хотел, чтобы тебе на ровном месте lock inc сделали, или что?
>>78783
> кодогенерацию на макросах
Как насчет кодогенерации на PHP?
Что функция не копирует к себе значение а, а работает с значением а. Указатели же вроде так работают.
Ещё вопрос. Как сделать чтобы тебе функция возвращала целый массив, а не отдельный элемент массива?
Синтаксис
int function(int *a) - принимает указатель на int
int function(int &a) - принимает ссылку
>Как сделать чтобы тебе функция возвращала целый массив, а не отдельный элемент массива?
Передавать указатель на массив в параметрах функции.
На твоём месте, я бы сначала прочитал про указатели, а не лез в сишные указатели со знанием о плюсовых ссылках.
Ты сейчас опять его спутаешь, в си нет ссылок, поэтому их можно было вообще не писать.
Так ему уже писали, что ссылок нет. Если он читать не умеет - то...
> Без setlocate и SetConsoleOutputCP это вообще возможно сделать?
Да, делается так: gcc -finput-charset=utf-8 -fexec-charset=cp866 file.c (ну и исходник в UTF-8 естественно). Но в серьезных программах лучше написать свою обертку для printf, которая в линуксе просто вызывает printf, а в Windows - vsnprintf в буфер, MultiByteToWideChar(CP_UTF8, ...) и потом WriteConsoleW. В десяточке консоль уже более-менее умеет работать с UTF-8 без странных спецэффектов, поэтому можно обойтись SetConsoleCP.
Еще хочу добавить, что все примеры, какие видел, были в UTF-8. И (судя по объяснению автора) компилируются без проблем. Буквально качаю тот же самый фаил, а у меня кракозябры
>>79037
>>79044
>>79046
Как это нету ссылок, если вон, есть указатель адреса и ссылка по указателю. хотя пока не понял в чем разница
В общем виде код, который возвращает массив через указатель должен так выглядеть? Компилятор чет залупается.
#include <stdio.h>
int function(char &temp[5]);
main()
{
char data[5];
function(data);
return 0;
}
int function(char &temp)
{
return temp;
}
Признайся, что ты троллишь.
В определении функции выполнять операцию взятия адреса параметра т.е. формального описания, а не значения - это так толсто.
Делать мне больше как в /pr толстить.
Убрал в определении функции &, но компилятор все равно ругается. В этот раз даже ссылку на номер строки не даёт так что я вообще не ебу что он хочет. В чем проблема?
Не обманывай, няш.
Ты описываешь компилятору, как
int function(char [5]); мол не ссыте, пацаны. Будет передаваться 5 символов и возвращаться int.
Дальше идет вызов, ожидающий того что ты наобещал.
А внизу внезапно int function(char &) реализовано.
Где линкеру искать реализацию обещанного.
> Писал мне что не может конвертировать из UTF-8
Может быть, у тебя исходник в Windows-1251? Или гцц какой-то кастрированный, хуй знает.
>>79105
> Буквально качаю тот же самый фаил, а у меня кракозябры
Может быть, автор запускает в консоли редактора (саблайма, например), или в линуксе, или делает chcp 65001 перед запуском.
>>79136
Ты реально необучаемый. Где на скриншоте ты убрал &, если вон оно в 14 строке торчит? Естественно, твой крестокомпилятор (выбери Си в настройках, блять, там оно есть!) создает функцию, принимающую ссылку, а ищет функцию, принимающую указатель.
>А с помощью одной лишь stdio нельзя это сделать?
Можешь убрать #include <stdlib.h>
и int argc, char argv.
А вместо return (EXIT_SUCCESS); return 0; сделай.
Так если у тебя все работает, чего ж ты выделываешься?
>>79153
> Как тогда должен выглядеть код, чтобы функция возвращала массив?
В Си не возвращают массивы. Если у тебя большой и непредсказуемый объем данных, ты выделяешь массив внутри функции, а возвращаешь указатель на первый элемет. Если ты знаешь, сколько тебе нужно "вернуть", ты передаешь в функцию указатель на первый элемент массива и максимальную длину, функция в этот массив срет, как ей нужно, а возвращает вообще void.
А что такое _arr в (char _arr[5]) ? И разве result может вернуть например абзац текста?
>>79179
> Так если у тебя все работает, чего ж ты выделываешься?
Это не я отвечал.
> ты выделяешь массив внутри функции, а возвращаешь указатель на первый элемет.
А разве содержимое функции не стирается к хуям когда функция завершает свою работу?
>Если ты знаешь, сколько тебе нужно "вернуть", ты передаешь в функцию указатель на первый элемент массива и максимальную длину, функция в этот массив срет, как ей нужно, а возвращает вообще void.
Можешь написать как это примерно будет выглядеть?
_arr имя переменной
> что такое _arr в (char _arr[5])
Указатель на char. 5 там для красоты и ни на что не влияет.
> А разве содержимое функции не стирается к хуям когда функция завершает свою работу?
Почему вдруг?
> Можешь написать как это примерно будет выглядеть?
https://ideone.com/sgqxcB
>Указатель на char.
Указывает не на переменную, а на ее тип что-ли? Это как и зачем?
А с помощью одной лишь stdio нельзя это сделать? Не хочу пока использовать код, смысла которого не понимаю и которого в книге пока нет.
Почему вот такой мой код не работает? В data[5] у меня какой-то текст, я его посылаю в функцию, функция должна записать по указателю в массив puthere[5] какой-то текст все. По идее puthere будет иметь то значение, что я ей в функции дал? Почему не работает?
Убери, блять, звездочку в 14 строке. [] и так интерпретируется как указатель на первый элемент массива.
Убрал и дописал принт puthere. Выводит каждый раз какую-то рандомную хуйню вместо 1. Из-за чего?
Читаю я K&R, пока до функций дошел.
Ты function для puthere не вызвал же.
puthere в main и puthere в function - 2 разных участка памяти. Область видимости.
Нет, это один и тот же массив, он же по указателю передаёт его.
Если он в функцию передаст puthere, а не дату, то распечатаются единички.
1. Нет это разные. Он передаст указатель на него и его перепишет функция.
2. Он не передает/вызывает в функцию puthere.
Вроде понял и сделал. Все правильно? Вроде работает так как надо.
Только у меня вопрос - как все же получилось что data поменялась, ведь я в функции ее без указателя передавал, должно же было только значение переменной скопироваться и все что внутри функции с переменной творится на функцию в мейне это не должно влиять.
Бля, строки в си нуль терминированы, нахуя у тебя function принимает именно char[5]? И всякие for ... i<5... это пиздец говнокод. Раз уж ты какого-то хуя юзаешь принтф для посимвольно вывода в цикле (о чем тебе уже с два треда говорят, но тебе похуй), просто создай переменную для считывания длины строки, допустим unsigned int len, которая пока выводит заодно посчитает strlen, и передавай в function(char _str и unsigned int len)
Ты не внимательно читаешь.
function(char []) - ты указываешь, что будешь передавать массив. Для оптимизации компилятор приводит этот параметр к указателю (копировать целый массив дорого). Т.е. ты в любом случае в функции при таком способе поменяешь значение исходной переменной.
Для защиты от невнимательности, если функция не должна менять данные, ты можешь объявить как function(const char[]), тогда компилятор выдаст ошибку в твоей функции, если там есть попытка изменить данные. Но в данной задаче - это не твой вариант.
> строки в си нуль терминированы
Это что значит?
>нахуя у тебя function принимает именно char[5]?
Я пока просто пишу заготовку функции, которую буду использовать в своей основной программе.
> И всякие for ... i<5... это пиздец говнокод.
А что с этим не так?
>Раз уж ты какого-то хуя юзаешь принтф для посимвольно вывода в цикле (о чем тебе уже с два треда говорят, но тебе похуй)
Что плохого в том, чтобы выводить принтф в цикле посимвольно текст? И что ты предлагаешь использовать вместо этого?
> просто создай переменную для считывания длины строки, допустим unsigned int len, которая пока выводит заодно посчитает strlen, и передавай в function(char _str и unsigned int len)
Вот это вроде неплохо, если я правильно понял как это должно работать.
>>79243
А есть разница между переменной что ты передаешь в функцию function(data) и названием переменной в самой функции int function (char data[5]) ? Если написать function (char blabla[5]) что-то поменяется?
>>79247
Разве в Си есть ООП?
>Ну давай поговорим. Как ты использовал X macros в последний раз?
я на cpp пишу, сюда захожу только чтобы пописать, как в макдональдс
>А есть разница между переменной что ты передаешь в функцию function(data) и названием переменной в самой функции
Да, огромная. Я же в примере специально назвал отлично от всех остальных _arr. Внутри функция ничего не знает об именах переменых в main, да и везде кроме себя. Когда ты вызываешь её, копируется или значение оргигинальных переменных или указытелей на них.
Т.е. если я в int function (char %хуимя%[5]) пишу название переменной из мейн - он оперирует этой переменной как будто функция с ней в мейне и работает. А если писать название, которое есть только внутри функции, то функция берет просто значение %хуимя% из function(%хуимя%) и не влияет на переменную в мейне?
Будет она называться также или нет - она не будет взаимодействовать с переменной из мейн. Просто при вызове твоей функции пихается не массив, а адрес памяти где твой массив из мейна начинается. Т.е. ты работаешь не с копией массива, а оригинала.
Понял. Будет ли менятся оригинальная переменная или нет зависит лишь от того будешь писать int function (const char data[5]) или нет?
>она не будет взаимодействовать с переменной из мейн. Просто при вызове твоей функции пихается не массив, а адрес памяти где твой массив из мейна начинается.
А разве работа с адресом памяти, где хранится переменная это и не есть работа с переменной?
Скажи, ты пробовал внимательно читать K&R, если уж ты вообще его читаешь? Там ответы на все твои вопросы написаны, но, тем не менее, ты не читаешь ответов даже итт.
Почему это разные массивы, он уже внутри функции просто ходит по указателю в свой исходный массив, который и переписывает.
Понял-принял.
Читал его несколько месяцев назад, и то только до функций, сейчас все вспоминаю.
>>79274
О, благодарю. Если подытожить - массивы всегда только через указатель передаются, остальные по значению, если не стоит . Но если ставишь const то и со передается только по значению, так?
Только я не понял глубинный смысл конструкции void function (const int *data). Если ты не хочешь чтобы data менялась, то зачем ставить звездочку?
(const оченьЖирнаяСтруктура *s), например. Суть в том, что const тебе не запрещает менять. Он заставляет компилятор постараться отследить попытки изменить такие переменные (с const) и ругнуться ошибкой.
Ну например оченьЖирнаяСтруктура копировать дорого, передаешь указатель. А функция не должна изменить. Добавляешь const. Какой-то долбоеб лезет менять функцию, начинает пытаться менять в ней поля оченьЖирнаяСтруктуры и получает ошибки. Своего рода контракт - функция обязуется не менять значения, вызывающий понимает, что его данные внезапно не похерят. в плюсах это проработано сильнее
Блядь боже, прочитай сначала про указатели, а потом используй их, ты для нас сейчас выглядишь, как человек, который пытается надеть свитер:
То есть если надеть его через голову, то будет тепло, а если через ноги, то можно спать не снимая свитер?
Пиздец блядь, как же все обленились, вместо того, чтобы прочитать и понять, как все работает, он задаёт тупые вопросы и ждёт на них ответ, который тоже не понимает.
Const это идентификатор такой, если ты пишешь const char arr[], это значит, что ты принимаешь указатель на const char, он не будет копироваться, const к этому вообще отношения не имеет, это лишь значит, что если ты попробуешь переписать значение, лежащее в твоём массиве у тебя все пизданётся нахуй.
Конст инт звезда по аналогии, ты можешь его прочитать, но не записать в него.
как же меня все бесит
Да меня самого скоро на сессии выебут, ещё и на работе завал, нихуя не успеваюзато время заходить сюда и отвечать на тупые вопросы нахожу, что за идиот
>ООП
А как его может не быть, если ООП это просто способ работы с данными?
Кладешь угазатель на функцию в типизированую структуру - и это уже не функция, а метод класса.
Вроде понял, спасибо.
>>79294
А ты знаешь такую вещь - если ты не можешь обьяснить вещь тому, кто в ней совсем не разбираешься, то ты и сам недостаточно хорошо в ней разбираешься. Незачем беситься.
Бтв книгу то я читаю, но получить ответ тут быстрее чем читать сходу 300 страниц и искать ответ.
>>79298
Читал что ООП в Си на костылях, а нормальный ООП это уже в С++.
>такую вещь
Эта вещь — полная хуйня
>читаю
>читал
Ну хоть читать умеешь. И да, возьми уже за привычку тип значения мейну указывать. Кстати, если тут не отвечают, можешь в крестотред идти и спрашивать там.
Ёбаная макака не даёт решать капчу на пеке.
А, да, последующие брейкпоинты игнорирует.
> Ну повреждаешь видимо, пишешь в text_to_byte() больше, чем выделяешь.
Не. С этим всё норм.
Самое интересное, что всё работало, пока я "типа интерфейс" консольный диалоговый не попытался написать. Но эти функции я не трогал.
Ну как норм-то, если у тебя при проверке кучи явная проблема. То, что "все работало" не означает, что ты раньше кучу не повреждал.
Потому что text_to_byte(text) работает без ошибок. А память я в нём выделяю.
> пишешь в text_to_byte() больше, чем выделяешь
Потому что повредить кучу ты можешь в одном месте, а проблема может возникнуть позже. Или не возникнуть вообще.
Твоя функция сломана в строке, которая пишет '\0' перед return. Допустим, strlen() вернула 5. Ты выделил strlen() ∗ 8 = 5 ∗ 8 = 40 байт, цикл прокрутился, i = 5, и ты пишешь в B_str[i 8], т.е., в B_str[40], т.е., выделив 40 байт, ты пишешь в 41-ый. Возможно, что это не единственная ошибка в твоем коде, возможно, не только* она вызывает проблему, но это ошибка.
>А разве содержимое функции не стирается к хуям когда функция завершает свою работу?
Под выделить в функции имелось ввиду не сам буфер разместить в стеке под этой функцией, а обращение к аллокатору.
Анончик, спасибо! Удивительно, что с фотографиями монитора нахуй не послали. Ты был прав, что не в одном месте такая фигня. Выделил во везде где нужно ещё по байту, и заработало как задумано. Вот тебе няша.
Пиздос. Вроде и не дорого, а вроде в кармане 35 рублей. Тоже такой хочу бля. Иногда книга удобнее электронного варианта
А по мне прикольно, невинная такая обычная провинциальная девочка, помацал бы, но явно не очень умная, не подойдёт для повседневного пользования
как ты ум по внешке определяешь? может она на хаскеле пишет
Какого хуя и как этот участок кода влияет на код из шага 2? Он же с ним никак не связан же кроме момента где я присваиваю send значение data2. Но саму же data2 я не трогаю. Так откуда тогда эти символы?
https://pastebin.com/HtJzKULv
В Си feof() служит не для того, чтобы определить, что файл кончился, а для того, чтобы отличить ошибку чтения от конца файла (возможно, название неудачное, но по-другому с потоками никак). Т.е., ты должен попробовать прочитать данные fread() или getchar(), чтобы они "споткнулись" об EOF, чтобы feof() начала возвращать 1. Т.е., на файле из одного байта 'x': fgetc() -> 'x', feof() -> 0, fgetc() -> EOF, feof() -> 1.
Поэтому, раз нам все равно проверять результат getchar() на EOF, чтобы не принять его случайно за букву, то и лишняя проверка из feof() нам не нужна.
>>79567
> Опять я со своим говнокодом
Верно подмечено. В строке 92 ты либо пишешь в массив элемент с индексом n, либо не пишешь, и там остается какое-то говно, которое было в стеке. Строчкой ниже ты его выводишь. Вероятно, ты хотел ввести вторую переменную - m, и писать в массив data2[m++] = date[n].
> pass 3
x = x + 3, выполненный 50 раз, явно вылезет за пределы массива send и распидорасит все вокруг.
> В строке 92 ты либо пишешь в массив элемент с индексом n, либо не пишешь, и там остается какое-то говно, которое было в стеке.
Как в data2 может быть говно, если без кода из шага3 все выводится без мусора?(первый скрин)
>Строчкой ниже ты его выводишь. Вероятно, ты хотел ввести вторую переменную - m, и писать в массив data2[m++] = date[n].
Нет, я хотел текст полученный в массив data скопировать в массив data2 без пробелов и запятых.
> x = x + 3, выполненный 50 раз, явно вылезет за пределы массива send и распидорасит все вокруг.
А как он в любом случае может влиять на массив data2, если send это совсем другой массив? К тому же массив выводится на печать до того как идёт шаг3, как он на уже выведенный на экран текст может влиять?
Чувак, возьми листочек и ручку.
printf("\n\npass 2:\n");
while (n != 50)
{
if (date[n] != ' ' & date[n] != ',' & date[n] != '\t')
date2[n] = date[n];
printf("%c", date2[n]);
n++;
}
n = 0; пусть попадает в if
date2[0] = date[0];
n = 1 //пусть попадает в if
date2[1] = date[1];
n = 2 //пусть НЕ попадает в if
date2[2]; - не записывается, но там остается мусор (ты же date2 не занулял)
n = 3 //пусть попадает в if
date2[3] = date[3];
В итоге
у тебя получется date2
[12][100][мусор][200]
> если без кода из шага3 все выводится без мусора
Да похуй. Читать неинициализированную память - это неопределенное поведение. Неопределенное - значит может произойти все, что угодно. Оно даже может вывести "мама, я все осознал, я больше никогда не буду программировать на Си", хотя вероятность этого события невелика.
> Нет, я хотел текст полученный в массив data скопировать в массив data2 без пробелов и запятых.
А я тебе что предложил? Вот так это и делается. Ну или указателями, суть не меняется - длина строки с выброшенными символами меньше длины оригинальной строки, поэтому старый индекс тебе не подходит.
> А как он в любом случае может влиять на массив data2
Да похуй, это баг, и ты прибежишь с ним в тред.
В общем, вопрос такой
объявление простого указателя и массива выглядит так(взял по int)
int ЗВЕЗДА p;
int a[5];
p=&a;
И через арифметику указателей мы можем в цикле или без него мы можем спокойно выводить значения массива а, я его не инициализировал и похуй.
А теперь такая хуйня
int a = 1;
int b = 2;
int c = 3;
int ЗВЕЗДА p[3] = {&a, &b, &3};
int ЗВЕЗДА ЗВЕЗДА ptr;
ptr = p;
И все бы ничего, но блядь, какого хуя, при работе с простым указателем и статическим массивом, я просто присваиваю указателю адрес первого элемента через &, а при работе с указателем на указатель и массивом указателей я просто делаю присваивание ptr = p без взятия адреса, ведь по сути p тоже массив, и его имя это адрес первого указателя, и я должен делать так ptr = &p, но это неправильно.
И еще такой вопрос, что значит объявление int (*ptr)[20]?
Указатель на массив? Если да, то нахуй он нужен, когда есть обычный указатель.
Вижуал студио)))))))))))
> присваиваю указателю адрес первого элемента через &
Ты можешь и так, и так:
int ∗foo; int bar[3]; foo = &bar[0];
int ∗foo; int bar[3]; foo = bar; // bar в большинстве случаев (кроме & и sizeof) автоматически преобразуется к &bar[0], т.е., к int ∗bar;
> а при работе с указателем на указатель и массивом указателей я просто делаю присваивание ptr = p без взятия адреса
А чем это отличается? Имя p неявно пребразуется к int ∗∗p (как выше c bar: скобки убрали, звездочку добавили), типы у ptr и p совпадают, все ок. Можешь и ptr = &p[0] делать, это абсолютно одно и то же.
>>79623
Да, указатель на массив. У него тип именно "указатель на массив", это важно. Нужен, чтобы обозначить намерения. Чтобы sizeof работал, чтобы индексирование работало у двумерных массивов, и можно было писать ptr[j] вместо ptr[i ∗ 20 + j]. Можешь вот с этим поиграться еще: https://ideone.com/huAMFl Это из прошлых тредов сохранилось.
У VS своя магия с конвертацией указателей из массивов. Кто шарит получше может и пояснит.
А чего тут объяснять? На скриншоте не то, что было в вопросе. На скриншоте есть амперсанд, т.е., берется указатель на массив. Указатель на массив численно равен указателю на первый элемент, но его тип - указатель на массив. Тип присваиваемого значения не совпадает с типом переменной, в которую присваиваем, и студия ругается, как ругался бы любой другой компилятор. Т.е., нужно либо так:
ptr = p;
либо так:
ptr = &p[0];
либо так:
ptr = ∗(&p);
либо так:
ptr = &(∗(&p))[0];
В VS я всегда вариант через &p[0] использовал.
А в gcc прокатывает и &p. Правда gcc я не давно использовать стал. как потребовалась кроссплатфорная адаптация существующего софта
> А в gcc прокатывает и &p
И не надейся. Ворнинги надо включать хоть иногда: https://ideone.com/5otK9Z
Попробовал, да ты прав.
Другой анон
Я не совсем понял, что ты имеешь в виду под указателем на массив, ведь *p[] это массив указателей
> ведь ∗p[] это массив указателей
int ∗p[]; // массив указателей.
int (∗p)[]; // указатель на массив.
int foo[3]; // Тип: массив из 3 int.
foo; // Тип: указатель на int (неявное преобразование).
&foo[0] // &(foo[0]); // Тип: указатель на int (явно взяли адрес).
&foo; // Тип: указатель на массив из 3 int (взяли адрес, но массива, а не элемента).
Жестко и круто, после того, как я со всей этой лабудой разберусь стану тру прогером?
Обычная переменная может хранить только свой адрес? Сам в си не шарю, просто, что первое в голову пришло
У микрософта всякие структуры любят через двойной указатель создавать. Пример:
https://docs.microsoft.com/en-us/windows/desktop/api/d3d9/nf-d3d9-idirect3d9-createdevice
HRESULT CreateDevice(
UINT Adapter,
D3DDEVTYPE DeviceType,
HWND hFocusWindow,
DWORD BehaviorFlags,
D3DPRESENT_PARAMETERS ☆pPresentationParameters,
IDirect3DDevice9 ☆☆ppReturnedDeviceInterface
);
Ты у себя в коде объявляешь пустой IDirect3DDevice 9 ☆foo = NULL;
И затем передаёшь &foo в функцию. Вуаля - у тебя есть экземпляр девайса.
Что ты потом с этим адресом в переменной делать будешь? Костыли городить?
Погугли ASM PTR - решение на уровне архитектуры.
Тупой долбоеб, ты же даже не знаешь что такое ООП, просто так словами ьросаешься, лишь бы чёто сказать.
Вот таких как ты и надо троллить, причем это было жирно, обезьянка
>чем отличается указатель от числа
Ничем. Адрес это просто число. Есть даже специальный тип - uintptr_t - целое, которое вмещает в себя указатель.
>int (∗p)[]; // указатель на массив.
Чем отличается указатель на массив от просто указателя на int?
>&foo; // Тип: указатель на массив из 3 int
>(взяли адрес, но массива, а не элемента).
Чем отличается указатель на массив от указателя на элемент (первый)?
> Адрес это просто число
Попробуй написать что-нибудь на Си под DOS, будет сюрприз. Хотя в целом, да, просто число.
>>79731
> Чем отличается указатель на массив от просто указателя на int?
В данном случае только типом. Для char (∗p)[3]; char ∗q; char ∗∗w, например, уже есть отличия: sizeof(∗p) != sizeof(∗q) != sizeof(∗w).
>>79735
Тип - это такие метаданные о переменной, которые определяют, что в ней может лежать, и что с этим можно делать. Внезапно, правда?
>Попробуй написать что-нибудь на Си под DOS, будет сюрприз.
Я под дос не писал, но far указатели вроде же как-то по особому выделялись, не?
> хотя в любом неговнокоде нужно держать размер отдельно в явном виде
Это вкусовщина. Я считаю, что размер, указанный явно, гораздо читаемее, чем неведомо зачем введенная константа, определенная где-то в жопе (например, uint32_t crc32_table[256] vs. uint32_t crc32_table[CRC32_TABLE_SIZE]). Разумеется, если у тебя множество определений подобных массивов, и нужно иметь возможность настраивать размеры у всех сразу, тогда без константы не обойтись (банальный пример - MAX_PATH в винде).
Ты думаешь слишком поверхностно, но в целом указатели на массив это бесполезная фича на мой взгляд.
Хотя возможно если писать какие-нибудь юзер-спейс приложухи, то где-нибудь и пригодится, для красоты так сказать.
> указатели на массив это бесполезная фича
Каждый раз, когда ты пишешь void func(int arg[10][20]), ты используешь указатель на массив, возможно, даже не подозревая об этом.
В том-то и дело, я так никогда не пишу, даже массивы на стеке я всегда передаю по обычному указателю.
Объясни, что такой указатель на массив тогда, с точки зрения, передаваемого аргумента в функцию как вдумерный массив
В вышеприведенном примере уже некрасиво. Нужно объявить массив с числом размера, а потом указатель на массив такого же размера. Дублирование числа явно напрашивается на ошибку несхождения этих чисел.
>>79891
+1, то же самое. Сейчас осенило что видел массивы в параметрах только в функции main, которую IDE автоматом генерит, лол.
А где ты там двумерный массив увидел, вкатывальщик ебучий? Там массив указателей на массивы. А n-мерный массив всегда передается как обычный массив.
> массив указателей на массивы
Там просто указатель на массив, а массив указателей на массивы - это int (∗array[10])[20]. Сишный синтаксис деклараций неустанно доставляет.
Лучше придумать невозможно. Только такой синтаксис позволяет объявлять сколь угодно многослойные конструкции, сохраняя ясность, как потом к этой хуерге обращаться.
Пожалуй, что таки да)
Нормально, под задачи. 70-х
Это так не работает. "Хуевый" понятие относительное, это значит должен быть лучше, иначе хуевого не существует. Показывай где синтаксис лучше. Не можешь? Значит сишный синтаксис - лучший. Понимаешь, так работает относительность, даже такой дебил как ты будет величайшим гением, если уничтожить всех умных людей на Земле.
x >= 'A' && x <= 'Z'
"Синтаксис Rust похож на Си и C++; язык регистро-зависимый, блоки кода ограничиваются фигурными скобками; используются стандартные наименования управляющих конструкций if, else, while, и for; комментарии также пишутся в С-формате; имена модулей разделяются двумя символами двоеточия (::). Идентификаторы могут содержать латинские буквы, цифры и знак подчёркивания."
Нууу, хуй его знает.
мимопроходил
> используются стандартные наименования управляющих конструкций if, else, while, и for
А есть где-то иначе? Ну кроме очевидных примитивных бейсиков и паскалей.
Анончи, что за форс Растопетушни ИТТ, зачем они сюда набигают?
Пар на 95% безопаснее...
Массив частный случай указателей. Например чтобы не передавать твою структуры на 2 мегабайт копированием, передаешь указатель на нее. про указатели на функции обработчики и тд не буду
> А есть где-то иначе?
Очевидный примитивный питон, примитивный лисп?
>>80270
1) В аргументах функции (и только в них) записи char s[] и char ∗s означают одно и то же. Т.е., ты на самом деле пользовался указателем, хоть аргумент и записывался как массив.
2) Смысл применения указателей - прочитать/записать что-то где-то, динамически задавая что именно. Т.е., если имя переменной на протяжении всей ее жизни всегда "связано" с одним конкретным объектом (областью памяти), то с указателями ты можешь ссылаться на разные области памяти. А уж как это применять, тебе будут рассказывать до конца книги.
Анон выше >>80304 тебя наебал. Массив в Си - это нормальный массив, как и везде - отдельный тип для объекта, состоящего из последовательности других объектов (примитивов или структур всяких, или других массивов - похуй). Никаких указателей там никто не хранит (если ты явно массив указателей не сделал). Т.е., если у тебя char array[] = {1, 2, 3, 4, 5}, то в памяти так и будут байты 1, 2, 3, 4, 5 последовательно. Но в отличие от некоторых других языков, в Си:
1) Имя массива (имя переменной) при его использовании в выражениях в большинстве случаев автоматически "преобразуется" к указателю на первый элемент. То же самое происходит и с именами функций, но тебе про это пока рано. Т.е., было int array[3]; array[2] += 1; стало int array[3]; (&array[0])[2] += 1; (тут &array[0] - указатель на первый элемент). Исключения - когда к массиву применяются операторы &, sizeof, alignof, они работают именно с самим массивом как с объектом.
2) Предыдущий трюк нужен затем, чтобы разрешить [] работать и с указателями, и с массивами. Квадратные скобки для индексирования массива в Си - это сахарок, они "заменяются" на сложение и дереференс: array[2] становится ∗((&array[0]) + 2), т.е., к указателю на первый элемент прибавляется индекс, и по получившемуся указателю читается/пишется значение (используется арифметика указателей, о ней в K&R прочитаешь).
3) Когда ты передаешь массив в функцию, правило (1) никуда, к сожалению, не девается, и ты передаешь указатель на первый элемент. somefunc(array) - это на самом деле somefunc(&array[0]).
4) Для того, чтобы не вызывать недоуменияохуевания у передающих "массивы" в функции, пришлось в аргументах самих функций объявления аргументов как массивов автоматически трактовать как указатели: void somefunc(int arr[]) на самом деле void somefunc(int ∗arr). В С11 все это еще больше запутали своими int arr[static 3], но лучше пока об этом не думать.
Вот как-то так. Попроще пусть кто-нибудь другой объясняет.
Ахуеть, вот бы в сипп треде были бы такие же ответы. А в чем конкретно приемущество arr[x*y], где все строки хранятся а одном массиве, перед массивом указателей arr[x][y]?
>Массив в Си - это нормальный массив, как и везде
Наоборот, сишный массив это лишь сырой буфер в памяти и указатель на него, аналог malloc. Ничего общего с нормальным массивом тут нет. А возможность к указателю подставить скобки это лишь вариант арифметики указателя.
> сишный массив это лишь сырой буфер в памяти и указатель на него
> аналог malloc
int ∗foo = malloc(3);
printf("%zu\n", sizeof(foo));
int bar[3];
printf("%zu\n", sizeof(bar));
Заблуждаешься сам - не путай других. Массив bar - это объект типа "массив из 3 int". foo - объект "указатель на int". Ничего общего.
> С++ бояр есть compile time xorstr, а нам что делать
Не страдать хуйней, ведь реверсера это остановит минуты на две максимум? Использовать нормальную коммерческую защиту с виртуальной машиной, если требуется повысить этот порог до вменяемых величин?
>>80336
Прибавляется именно индекс, потому что слева указатель, а вот под капотом результат сложения считается так, как ты сказал.
>>80346
> А в чем конкретно приемущество arr[x*y]
Не понял вопроса. Двумерный массив (массив массивов) всегда предпочтительнее, чем ручне вычисление индекса, потому что компилятор может лучше оптимизировать доступ, и код с [][] получается более читаемый. Одномерный массив вместо двумерного делают, если не известно последнее измерение, а без него компилятор не может самостоятельно вычислить адрес элемента. А массив указателей используют, например, когда размер элементов различен, как в argv.
>Двумерный массив (массив массивов) всегда предпочтительнее
Неправда. Он дольше инициализируется, дольше удалаяется, он недружественнен к кэшу, и так далее. Все матрицы имеют внутри себя один большой кусок памяти.
Что за нахуй?
while (end != 1)
{
puts("\nВведите номер:");
gets(input);
printing(input);
}
return 0;
}
> Он дольше инициализируется, дольше удалаяется, он недружественнен к кэшу
Каким местом? Мы точно об одной и той же вещи говорим? Точно не о массиве указателей на массивы?
> Все матрицы имеют внутри себя один большой кусок памяти
Двумерный массив - это массив массивов, точно такой же один большой, непрерывный кусок памяти.
Ты о статических массивах что ли? Ну это вообще сильно бесполезная йоба. Если в случае одномерного массива можно хотя бы выделить статический буфер побольше и работать в нем, то здесь та еще хуита уровня laba.cpp
Уже нашел косяк, отбой.
Ты тупая бестолочь, не знаешь что такое массив, а sizeof это незначительная мелочь, не имеющая значения в контексте сказанного.
Массив это высокоуровневый объект - набор значений по индексу. Это значит:
1. массив вовсе не обязан быть цельным блоком, точнее тебя это в принципе ебать не должно, если ты не хакер, ковыряющий бинарный код, но бинарный код это не язык программирования в котором написан массив, так что пролетаешь мимо темы.
2. массив, естественно, обязан проверять индекс и всё прочее, чтобы никаких выходов из него не было, потому что выход за пределы объекта это маразм ёбаный.
Поэтому, повторяю для тупорылых долбоёбов: В Си нет массивов, а так же нет строк и нет циклов for.
Сишные строки это те же сишные лже-массивы - сырые буфера - malloc. Возьми строку в языках где есть строки (или std::string) и попробуй взять букву по индексу. Естественно, там всё проверется и вылетит ошибка диапазона, но не в сырых буферах Си, которые не строки никакие.
Ну а циклов for нет и так понятно почему, сишный лже-for это просто ебанутый рескин while, куда еще и кода можно напихать, вообще охуеть. Даже близко ничего нет с циклом for.
Поэтому, повторяю для тупорылых долбоёбов: Си - это НИЗКОУРОВНЕВЫЙ язык, в нём в основном есть только БАЙТЫ, СЫРАЯ ПАМЯТЬ С СЫРЫМИ УКАЗАТЕЛЯМИ, просто они слезка примазаны сахарком "строк" и "массивов", чтобе не совсем голые байты были. Но это лишь как трусы на голом человеке, ничего толком не прикрывают и не одежда ни разу, как был голый так и остался, голые байты, голая память, ебешься со всем вручную.
Того, тупица. Цикл for перебирает числа с фиксированным шагом от первого до последнего значения. Никаких условий тут быть не может, никакого постороннего кода тоже, только size_t встроенное, которое перебирается до конца и всё. А цикл с условием это do/while, его для того и придумали.
Я к вам из ситреда в си-манямирок тебя и подобных недоучек. Потому что сидеть в сишном треде, не понимая что такое си, это не очень круто, не находишь? Я уже молчу про написание программ в таком состоянии. Не, всех этих "сделайте мне домашку" понять можно, им похуй, но я такое в расчет не беру.
>>80659
На самом деле он прав, а ты вот не понимаешь, о чем он говорит, нормальный фор это например фор из питона типо for item in container, или тот же range-based фор из плюсов, он, конечно, работает на итераторах и внутри всё те же сишные форы, но они хотя бы выглядят как настоящий фор.
А тот фор, что мы имеем в си это буквально просто while.
Да, только им должен быть тот фор, что мы имеем, а обычный фор вообще не нужен.
Нормальный for так и называется, пошел из бейсика и паскаля, в последнем даже шаг фиксированный - единица, и менять нельзя.
Проблема современных языков, их синтаксис пошел из си, который совсем не нормальный язык высокого уровня, а обертка для ассемблера, хотя на вид обманчиво похоже для удобства, но из за того что там ничего нет, на самом деле оно совсем не то как выглядит. В результате всякие клоуны привыкшие к джаваскрипту и подобному лезут в си с совершенно неправильным представлением куда они вляпались.
Вот тебе простой пример. В си числа есть, поэтому ты с ними работаешь почти как обычно, просто объявляешь переменную, присваиваешь математические выражения, всё работает, ололо простой язык.
А вот скажи, ты знаешь как устроен int? Чем отличается int от unsigned int? Я вот, честно скажу, не знаю, предполагаю там есть зарезервированные биты, которые указывают на различия, но по большому счету мне похуй, оно и так работает, ни о чем думать не надо.
А что со строками? Какие строки в ассемблере, аллё? ЦПУ работает с числами, вот и жри числа. Поэтому в си есть тип int, но типа string нет и быть не может. Ты не можешь объявить строку аналогично числу и работать с ней так же легко, ни о чем не думая, вместо этого ты, их самостоятельно программируешь, собирая по символам в соответствии с устным соглашением определенного формата, который обязан выучить, который ты, кстати, можешь нахуй послать и заебашить свои строки, например, оканчивающиеся не на 0, а на -1, или -66 потому что сатанист, и разницы никакой не будет.
Кстати, о символах. В си же есть char, да? А вот хуй! Как ты тогда объяснишь unsigned char, если у букв не может быть никаких знаков??? Понимаешь, что это маразм? А всё потому, что char это никакой не символ, а БАЙТ, восьмибитное число, такое же как int - 32-битное число. В процессоре не бывает никаких букав.
Зато в си есть, внимание, строковые константы! Строк нет, зато константы для них есть. Добро пожаловать в дурдом! Ты просто пишешь текст в кавычках и оно само напердолит памяти, поставит нолик в конце, и даже думать ни о чем не надо!? Ась? Но всё таки надо, ведь если ты не знаешь что оно там напердолело, что ты с этой НЁХ тогда делать будешь? А если строка не фиксированная?
Между прочим, такие же строковые константы есть и в ассемблере.
Ну и массивы туда же. Ололо, пишешь a[10], как же просто, вот тебе массив, как на матёше! Авотхуй. Вместо того, чтобы просто брать и пользоваться массивом, ты сидишь и изучаешь указатели, модели памяти, размеры элементов, формат хранения, иначе сосешь толстые хуи. Ну и где тут массив? Ты всё так же своими ручками пердолишь внутренние форматы всякой хуеты, будто реверсишь готовый экзешник, а не пишешь программу на языке. А потому, что это и есть ёбаный экзешник, низкоуровневый недоассемблер, а ни какой не ололо алгоритмический язык как все привыкли.
Нормальный for так и называется, пошел из бейсика и паскаля, в последнем даже шаг фиксированный - единица, и менять нельзя.
Проблема современных языков, их синтаксис пошел из си, который совсем не нормальный язык высокого уровня, а обертка для ассемблера, хотя на вид обманчиво похоже для удобства, но из за того что там ничего нет, на самом деле оно совсем не то как выглядит. В результате всякие клоуны привыкшие к джаваскрипту и подобному лезут в си с совершенно неправильным представлением куда они вляпались.
Вот тебе простой пример. В си числа есть, поэтому ты с ними работаешь почти как обычно, просто объявляешь переменную, присваиваешь математические выражения, всё работает, ололо простой язык.
А вот скажи, ты знаешь как устроен int? Чем отличается int от unsigned int? Я вот, честно скажу, не знаю, предполагаю там есть зарезервированные биты, которые указывают на различия, но по большому счету мне похуй, оно и так работает, ни о чем думать не надо.
А что со строками? Какие строки в ассемблере, аллё? ЦПУ работает с числами, вот и жри числа. Поэтому в си есть тип int, но типа string нет и быть не может. Ты не можешь объявить строку аналогично числу и работать с ней так же легко, ни о чем не думая, вместо этого ты, их самостоятельно программируешь, собирая по символам в соответствии с устным соглашением определенного формата, который обязан выучить, который ты, кстати, можешь нахуй послать и заебашить свои строки, например, оканчивающиеся не на 0, а на -1, или -66 потому что сатанист, и разницы никакой не будет.
Кстати, о символах. В си же есть char, да? А вот хуй! Как ты тогда объяснишь unsigned char, если у букв не может быть никаких знаков??? Понимаешь, что это маразм? А всё потому, что char это никакой не символ, а БАЙТ, восьмибитное число, такое же как int - 32-битное число. В процессоре не бывает никаких букав.
Зато в си есть, внимание, строковые константы! Строк нет, зато константы для них есть. Добро пожаловать в дурдом! Ты просто пишешь текст в кавычках и оно само напердолит памяти, поставит нолик в конце, и даже думать ни о чем не надо!? Ась? Но всё таки надо, ведь если ты не знаешь что оно там напердолело, что ты с этой НЁХ тогда делать будешь? А если строка не фиксированная?
Между прочим, такие же строковые константы есть и в ассемблере.
Ну и массивы туда же. Ололо, пишешь a[10], как же просто, вот тебе массив, как на матёше! Авотхуй. Вместо того, чтобы просто брать и пользоваться массивом, ты сидишь и изучаешь указатели, модели памяти, размеры элементов, формат хранения, иначе сосешь толстые хуи. Ну и где тут массив? Ты всё так же своими ручками пердолишь внутренние форматы всякой хуеты, будто реверсишь готовый экзешник, а не пишешь программу на языке. А потому, что это и есть ёбаный экзешник, низкоуровневый недоассемблер, а ни какой не ололо алгоритмический язык как все привыкли.
И в чем разница с++ фора от сишного?
>Так что есть истина, аноны?
Ты - обычный наследственный дебил.
Как и все здесь, тащемто.
Вот тебе истина.
> массив, естественно, обязан проверять индекс
Какие-то фантазии и вкусовщина, не имеющие отношения ни к Си, ни к массивам в целом. Дальше не читал.
Что и требовалось доказать. Ты уже давно дрищешь тут истеричными оскорблениями. При чем, хуй пойми, что именно ты пытаешься доказать. Донести, что в твоей системе взглядов отсутствие синтаксического сахарка для вызова функций без вызова функций является примитивным? Если по существу сказать нечего, пиздуй самоутверждаться в другой тред, где тебе будут больше рады.
// ну, типа...
#define mul(a,b) ((a)*(b))
#define ntimes(n,op,val,res) while(n--) res = op(res,val);
//и потом можно...
double val = 3, res = 0;
ntimes(7, mul, val, res);
// в итоге res == 3^7
Это ж гибкая такая хуйня получается, почти скриптопараша. Главное в рекурсию не пробовать, а то препроцессор подавится.
В смысле, начинал? Я после того длинного поста в тред не писал, лол. Открыл тред и проиграл с дауна, строчащего абзацы манядетектов. Воистину: "зачем учить си, я слишком туп для этого, лучше подетекчу семенов и обсужу их личностные качества". Прям как деревенские бабки на лавочке, мозгов нет, зато соседей всегда готовы обсуждать до усёру.
если не сомневаться в подозрениях, то ок...
Но если все еще предполагать, что ты нормальный чел, то неужели не видно, что с каждым словом все более похоже на толстоту становится?
А, понял. Я думал ты тот же анон, что отвечал на вопрос ньюфага про массивы и указатели. А теперь все сомнения отпали.
> Массив в Си - это нормальный массив, как и везде - отдельный тип для объекта
У тебя есть объяснение этому https://ideone.com/6T4U5I (в контексте "массивы в си это нормально")?
ну ок, контекст приводит имя массива к указателю на первый элемент, и потом задействует арифметику указателей, где в свою очередь "от перестановки слагаемых...". По идее, такую же хрень можно сделать с крестовыми векторами, если объявить что-то вроде template<T> vector<T>::iterator operator+(vector<T>& v, int i) { v.begin() + i; } и зеркальный вариант с другим порядком параметров для коммутативности, и вуаля. Есичесно, хуй знает что получится, и не буду ли я послан нахуй, рассчитывая, что i[v] развернется в *(i+v) и потом обработано моим оператором, но суть ясна. Если язык предполагает байтоебство минимальным количеством кода, без километровых кастов "отказов от претензий", то все неизбежно подвержено вот таким лаконичным фокусам.
Может я что-то упускаю, но если тебе нужен разный процессинг, то можно обычную функцию подавать как у тебя в последней строчке. На пике прототип принимающей (ntimes), которая внутри просто вызывает поданную.
Да, у меня есть объяснение. Последовательность однородных элементов есть - все, есть массив. Почему так работает [], я уже писал в >>80333 пункты 1 и 2. Не понимаю, что тебе не нравится? Ну да, возможны вот такие выверты синтаксиса - ну так это детали реализации, не нравится - не пользуйся, пиши в правильном порядке.
Это не массив и не детали, а банальный сахар для арифметики указателя. Ты можешь точно так же подставить [] к простому указателю и работать будет аналогично:
int i = 0xFFFF;
char ★p = &i;
p[1] = 0;
Ответил не читая? Да, это сахар. Да, [] всегда работает с указателями. Но массивы от этого никуда не делись.
и есть механизм неявных преобразований связанных с типом массив, зачастую это случается при передаче фактических параметров в функции
и есть механизм низведения типов в формальных параметрах функций, связанных в том числе и с массивами
отрой k&r, уебище, там все это есть
Об этом я не забыл подумать, но тогда выходит что-то слишком адекватное, и дженериковость функции-аргумента теряется, а так хоть int, хоть double
И признаком массива является.... отличие sizeof?
Браво, кретин, но sizeof никакого отношения к массивам не имеет.
Признаком массива является то, что тип переменной a в int a[10] - массив. Так написано в стандарте. Так же как признаком инта в int b тоже является тип. Если у тебя свой собственный язык, собственная терминология, или ты к нам просто из C# протек - это твои проблемы.
А, так ты про то, что любой указатель со скобками это массив? Ну, в сишной терминологии так, но сишка не нормальный язык, как уже было сказано. Если такое говорить ньюфагу, он не поймет, т.к. в нормальных языках массивы это не указатели.
>в нормальных языках массивы это не указатели
в джаваскрипте указатели, в питоне указатели...
какой язык - нормальный?
Упс, или не так? У тебя правда весь аргумент "массив потому что тип отличается от указателя"? Аргумент это отличие и всё? То есть "раз это НЕ сахар, значит говно"?. Ну это уже просто дно дна, убей себя прямо сейчас лучше. Как с настолько атрофированным мозгом возможно в принципе существовать, для меня загадка.
Если что, то "это не указатель" не означает, что это массив, а означает, что это лишь слегка другой указатель.
Я ни разу поддерживаю анона, у которого на почве депрессии сыпятся через слово выражения "ненормальный язык", "кретин" и тому подобное, но упоминанием скриптовых Питона и ЖС ты этого токсичного пидора только подкормил, ибо не в тему нихуя. В контексте обсуждения под указателями имеется ввиду адрес+оффсет и вот это все, а не какие-то там умные ссылки на объекты в куче.
>массив вовсе не обязан быть цельным блоком
Ты что-то путаешь. Это список не обязан быть цельным блоком. А вот массив - это вариант реализации списка тем самым цельным блоком.
Вовсе нет. Представь небайтоёбский язык без указателей. Массив может быть реализован как угодно, хоть оберткой для списка, ты попросту не узнаешь, потому что байтоёбство тебя не касается.
Чувак, от тебя дерьмом за километр несет. Да, я понимаю, что под ненормальностью языка ты имеешь ввиду чуждость низкоуровневой парадигмы для здешних ньюфагов, привыкших писать свои олимпиадные велосипеды, располагая нативными стрингами и вот этим всем... Но, несмотря на то, что знания у тебя, вроде, есть, ты в них, кажется, не слишком уверен, т.к. излагаешь позицию в максимально гнилых выражениях, чтоб собеседник подсознательно пригорел прежде, чем успеет добраться до пробелов в твоих знаниях, таким образом дав тебе основание объявить его "слив".
> Массив может быть реализован как угодно, хоть оберткой для списка
И в большинстве высокоуровневых языков это называется, сюрприз... list.
Ну и к чему ты выблевал этот поток эмоций? По делу есть что сказать? Или будем комментировать мои личностные качества как старухи на лавке обсуждают соседей? Тут си-тред, давай писать про язык, а своё гнилое социоблядское выяснение отношений оставь для дружков.
>Массив может быть реализован как угодно, хоть оберткой для списка
Но зачем бля? Как же мне бонбит от этого глупого ребенка, на Си пишутся с прототипов, чтобы было быстро и жрало мало памяти, тюнинг и оптимизашки, хочешь более обстрактного так вагон же напридумывали, ебись с Питухоном, ЖС, Растом, бля, не, сюда приперся, ирод.
Ну, в Java есть ArrayList, LinkedList, ZalupaList. Слово Array обозначает вполне определенный вариант реализации. В Python красота в квадратных скобках называется List. В Си-подобных языках, где имеют место объявления вроде int[10], можно на пальцах пересчитать, где как это реализовано. По, как ты любишь говорить, ПО-НОРМАЛЬНОМУ просто куча однотипных (или не однотипных) данных называется списком, а массив - это массив.
Ну, в Java есть ArrayList, LinkedList, ZalupaList. Слово Array обозначает вполне определенный вариант реализации. В Python красота в квадратных скобках называется List. В Си-подобных языках, где имеют место объявления вроде int[10], можно на пальцах пересчитать, где как это реализовано, и грамотно ли в том или ином случае называть это по-привычке массивом. Но, как ты любишь говорить, ПО-НОРМАЛЬНОМУ просто куча однотипных (или не однотипных) данных, которая "похуй как реализована", везде и всегда называлась списком, а массив - это массив.
Твоя манера общения имеет самое непосредственное отношение к конструктивности дискуссии.
>Но зачем бля?
Для понимания, что в си нет массивов, а лишь сахар арифметики указателей. Ты-то умный и уже не нуждаешься в пояснениях, а приходит ньюфаг и ты ему: "массив", а он думает совсем о другом, потому что массив это совсем не то, что в сишкомирке называют массивом. Ты понимаешь, что приходит ньюфаг и начинает работать с массивами, не зная об указателях и даже не зная что про них нужно знать? И не только об указателях, а и об памяти. Элементарная задача возврата массива из функции уже требует понимания указателей и разных моделей памяти, стека и кучи. Где тут массив, маня? Ты понимаешь , что несешь бред напрямую из своего манямирка? Другие люди не умеют читать мысли, нужно объяснять правильно, а не вешать лапшу на уши, предоставляя им самим набивать шишки. Может ты и набивал, но зачем повторять бессмысленное говно? Ты пидараха из этих "я страдал, и пусть другие страдают" или что?
>а приходит ньюфаг
Куда бля приходит? Зачем? Верстают там -> на ЖС, основы кодинга нужно на других языках проходить, Си и Асм это для тех кто знает что делать и зачем он это делает. Если мне нужна неебическая скорость и я буду разворачивать цикл, ты скажешь нахуй вот дублировать, зачем? Ты не в ту сторону воюешь короче.
В твоем маня мирке звучит логично. Но если сослаться на такой, должно быть, сомнительный для тебя источник, как ДЕЙСТВИТЕЛЬНОСТЬ, то логичная форма тонет под бредовым содержанием. Массив, блядь, обертка для списка. Охуеть. Каждый день такое вижу. У тебя, видать, каждый первый сосед хуй на лоб пришил и ходит так, а хули, в абстрактных понятиях, далеких от байтоебской медицины, похуй, как реализовано. Не мудрено в такой среде вырасти альтернативно сформированному анону, заебавшему всех адекватов в Си-треде.
>Для понимания, что в си нет массивов
в стандарте, блядь, языка прописан такой тип данных как "массив", включая и кучу срани типа правил его объявления и определения, объявлений неполного типа, правил неявных преобразований, так же правил низведения массивов
упоротый ты долбоеб
>Куда бля приходит?
"Поздравляю! У вас родился мальчик, си-программист!"
:3
К сожалению сишниками не рождаются и асм не преподают в обязательном порядке до си. Добро пожаловать в реальный мир, трезвей от своего манямирка. Приходят, сюда, в тред, люди, желающие, изучить, си, что, не ясно, у, меня, уже, безысходность, от, тупости, здешних, постеров.
Ну это понятно, массив не является полноценным объектом, с copy/move семантикой, т.к. подобные операции по технической сложности достойны отдельной функции, чтоб не дублировать много маш.кода. Копировать можно только структуры без ссылок на дополнительно выделенную память.
Any number of derived types can be constructed from the object, function, and
incomplete types, as follows:
— An array type describes a contiguously allocated nonempty set of objects with a
particular member object type, called the element type.36) Array types are
characterized by their element type and by the number of elements in the array. An
array type is said to be derived from its element type, and if its element type is T , the
array type is sometimes called ‘‘array of T ’’. The construction of an array type from
an element type is called ‘‘array type derivation’’.
я не он
почему бы и нет? ты же вовсю используешь скобочки при создании составных объявлений/определений
n1256 c draft
ты тоже мудак. Приебался к словам, уходя от первоначального тезиса. У ньюфага в голове не возникает вопрос "есть ли в Си массивы, про которые я читал в стандарте какого-то другого байтоебского языка вместо художки на досуге, попивая чай". Анону интересно, есть ли там такие волшебные списки, которые в языкнэйм так понравились ему возможностью взять и одних махом вбросить в функцию всю табличную инфу про себя, мамину подругу и дедушку Сталина, чтоб с ней можно было дрочиться внутри как угодно, не поломав ничего снаружи.
>Приходят, сюда, в тред, люди, желающие, изучить, си
Так, ты начинаешь изучать Си, тебе все сложна и нипанятна и нужно фсе переделать?
Не понял. Объявление функции - это одно, а int (t) - это что за лямбда?
Или что ты имеешь в виду?
кажется, даже в словаре человеческого английского языка в определении array присутствует слово contiguous
Это то же, что и просто int t, только со скобочками. Ничем не отличается, в таком виде никем не используется, нужно для более консистентного синтаксиса в сложных случаях.
Да я понимаю, что это не лямбда на самом деле. Я говорю о том, на что это формально похоже. Сам говорил про
> скобочки при создании составных объявлений/определений
Каких например? Какие сложные случаи? Функции традиционно мелкие, объявления переменных в начале.
> никем не используется
Да лучше бы я никогда этого не видел, но один раз встретил и теперь не сплю. Случай был тупой, канеш, ничего такого.
Как бы сказать. Программирование в главном широком смысле означает алгоритмирование. Соответственно, язык программирование является алгоритмическим языком, описывающим естественным образом алгоритм. Это справедливо для большинства языков и изучение программирование как такового начинается с алгоритмики. Это состояние в башке большинства вкатившихся в программирование.
Но си это совсем не то что выше, а машинный язык, язык железяки, процессора, узкоспециализированная херня, работающая по своим маня-законам, которые не очевидны без изучения мануалов этой железки.
И всё было бы хорошо, но проблема в том, что си имеет тот же синтаксис как и алгоритмические языки, знания о которых имеются по умолчанию, и использует те же термины "массив", "строка", как и алгоритмические языки. НО на самом деле это всё совсем не то и работает не так, потому что язык машинный, железячный, тут софтово не налеплено маня-парадигм и прочих объектов, всё близко к железу. И в такой нишевой язык не идут младенцы с полным отсутствием знаний, которые изучают всё с нуля чисто по сишке, а наоборот, люди обычно уже знакомы с программированием, и когда приходят в сишку, видят тот же синтаксис и те же термины, естественно начинают писать как они знают, А ЭТО НЕ РАБОТАЕТ. Они ебут мозги, хотя эти сишкопидарасы тупорылые могли бы сразу сказать: "забудьте, нет у нас никаких массивов, учите указатели, ебите память".
int (a); // int.
int (∗b); // Указатель на int.
int ∗(c)(void); // Функция, возвращающая указатель на int.
int (∗t)(void); // Указатель на функцию, возвращающую int.
Если в первых трех примерах скобочки как бы и не нужны, ты можешь их убрать, то в четвертом они меняют суть объявления, и без них ты указатель на функцию не объявишь (ну разве что с тайпдефом). Их притащили ради изменения приоритета вот этой звездочки, и они заодно протекают в три предыдущих примера, и много куда еще.
Воо, спасибки, дубоват стал...
>сишкопидарасы тупорылые могли бы сразу сказать
Зачем ты нас оскорбляешь? С тобой даже диалог пытались наладить, думаю аноны больше так не будут делать.
Любая характеристика, хоть положительная, хоть отрицательная, определяется характеризуемым объектом. Говоря по-простому, что заслужил, то и получил. Хорошее отношение это не привилегия. Хочешь хорошего отношения - совершенствуй себя и заслужи его, а пока ведешь себя как долбоеб, долбоебом и будешь назван. В этом преимущество анонимных борд, здоровое свободное общение без навязанной цензуры лицемерной вежливости как ирл.
Этот парень принципиально не сбавляет оборотов, ведь сейчас шаг навстречу за "сишкопидарасами", посмевшими неверно истолковать его слова сразу. Проблема лишь в том, что оскорбления пошли прежде, чем вообще кто-либо мог успеть прислушаться к нашему достопочтенному разрушителю парадигм.
Вот это удваиваю. Но ты, пожалуй, рановато вышел в боевой режим со словами "тупица". Надо было еще постик-другой потерпеть, глядишь и не довелось бы.
>Любая характеристика, хоть положительная, хоть отрицательная, определяется характеризуемым объектом.
Умопомрачительный долбоебизм.
Иди покушай говна - кому-то это нравится.
мимо
Сам сишкопидарас и по себе знаю, как иной раз вместо нужных для вката слов об неиллюзорных отличиях, не премину выговориться в защиту секты "да все тут нормально с массивами, все тут есть" что для ньюфага отнюдь не утешительно. Хуёво так делать...
Человеку свойственно ошибаться. Ты у мамы идеален? Видишь ошибку у ближнего и отвергаешь его полностью? Ну и дебил, и это не оскорбление. Потому что по сути, такое поведение - суждение не по смыслу сказанного, а по форме. Не читая книгу, сделал вывод по обложке. Это поведение дебилов, которым свойственно нежелание читать и думать, вот и скатываются на такие легкие суррогаты вместо настоящих выводов.
Когда первым языком учишь, мозг без ложной самоуверенности включается на полную, и происходит чудо, суммация усилий приводит к результату. А когда прихожане из скриптопараши небрежно листают "этого вашего" K&R, надеясь со своей гавнокодерской колокольни схватить все на лету, то велика вероятность, что наш глубокоуважаемый продвинутый молодой вайтишник вынесет вердикт "это какая-то старперская головоломка" и уйдет сосать хуй смотреть ютуб с печеньками.
Ты сейчас описал, как я другие языки пытался освоить. Руки сами пишут как на Си.
>как работают в Си массивы
берешь драфт последнего стандарта си
поиском вбиваешь array и читаешь че там и как
описание формальное, но одновременно со множеством примеров и объяснений
алсо, если тупенький, то следует помедитировать над приложением A в в К&R
Ну, твой вариант хотя бы работает, а не приводит в тред с проблемой "у меня массив сломался". Дело за малым: не полениться почитать, в какие плюшки умеет твой языкнэйм, и пользоваться в свое удовольствие. А вот обратное, то есть думать, что Си - это такой ретро Питон, который за чуть большее количестве буков наградит меня шармом 80-х и пропуском в ламповые тредики, как своего... непростительно
Уебану что-то пришло в голову на почве отека мозга от бензилового спирта из ларька, и он пол треда обосрал, а вы ещё уебаны кормите его? Пидорасы из школы 21 захватили нахуй весь тред, умрите нахуй.
Ну вот, уже кто-то, кроме меня, назвал меня дегенератом. Стало быть, неспроста тревожился. Пойду убьюсь, чтоли...
Ембед, серверы, базы данных, графон, геймдев, шейдеры, системные тулзы для ленупса, работа с волнами (в основном на BM)
JVM, многие скрипты, большинство БД сделаны на С, соответственно, требуют его для допила/мейнтейна
Для обсуждения в Си-треде
>Для чего сишка вообще применяется в 2019 году?
чтобы лабы студентам на "введение в программирование" на первом курсе было на чем делать! че ты как маленький
>JVM
там сделан на крестах маленький рантайм, все остальное сделано на самой явке, включая и сам компилер на явке бутстрапнут
На языке программирования вообще мало что написано, программы там какие-то, а все остальное, "Война и Мир" там и прочее... ну ты понял
блин, я какое-то хуевое сравнение привел. Короче, суть в том, что без сишки ничего бы не было, так он востребован и высокооплачиваем. Из нас мало кто устроится, но каждый из нас КОГДА-ТО станет круче всех Страуструпов и Кармаков, и вот тогда держись мой Мухосранск, все выкуплю. Эх... <звуки заводки будильника, чтоб не проспать, а то кассиров не щадят>
Это довольно голословное заявление. Значимость сишки не определяется самой сишкой. С таким же успехом можно сказать, что без бишки ничего бы не было.
"Массив это указатели" это только полуправда. На самом деле у них много отличий (но также и сходств). Завали ебало, если не знаешь нихуя.
>>81523
А почему и для чего ты спрашиваешь? Потому что вопрос не простой на самом деле, зависит от твоих намерений которые ты не озвучил по причине туповатости. или тролловатости, что впрочем одно и то же
Язык Си в буквальном смысле, как компилятор Си, разумеется давно неактуален. Я знаю только одно нормальное использование - это микроконтроллеры. И речь совсем не о нишевой производственной фигне, а о штуках для детей, наподобие "Ардуино". На западе очень популярно для всяких домашних проектов вроде светомузыки и т.п. Выпускается множество моделей и наборов, даже где паять провода не нужно. Программируется на Си.
Теперь в небуквальном смысле. Си абсолютно необходим потому что С++ актуален. Не спеши рваться, дебил, я еще не закончил. Дело в том, что С++ - язык мультипарадигменный. Посмотри на название: "С++", ты видишь две части - си и плюсики. Иными словами, С++ это и есть Си буквально, но не только, а есть еще плюсы. Таким образом, на С++ можно писать "как на си", можно "как на крестах", а можно с разной степенью смешения этих подходов. По этой причине созданы два треда, данный и крестотред, и они оба актуальны и необходимы.
Попытки же воевать, противопоставляя эти области, это простое сектобыдло, гопота с улицы, которая всё делит на "поцонов с нашего раёна" и "казлов с других раёнов". Биопроблемы тупых биопроблемников, к програмированию не относится.
>>80987
Массив одним куском плох для оптимизации из за фрагментации памяти. Лучше выделять произвольными кусками с возможностью фрагментации. Так работает файловая система на диске, вроде должно быть понятно по какой причине. Подобным образом работает любая надежная система. Почему сишкодебилы настолько зашоренные дауны, что не понимают очевидного, а только повторяют за бумажкой как безмозглые попугаи? Вот типичный пример такого идиотины >>81192 , увидел отличие от заученных определений и мирок с треском порвался, вызывая защитную реакцию: "врётиврётиврёти".
>>81523
А почему и для чего ты спрашиваешь? Потому что вопрос не простой на самом деле, зависит от твоих намерений которые ты не озвучил по причине туповатости. или тролловатости, что впрочем одно и то же
Язык Си в буквальном смысле, как компилятор Си, разумеется давно неактуален. Я знаю только одно нормальное использование - это микроконтроллеры. И речь совсем не о нишевой производственной фигне, а о штуках для детей, наподобие "Ардуино". На западе очень популярно для всяких домашних проектов вроде светомузыки и т.п. Выпускается множество моделей и наборов, даже где паять провода не нужно. Программируется на Си.
Теперь в небуквальном смысле. Си абсолютно необходим потому что С++ актуален. Не спеши рваться, дебил, я еще не закончил. Дело в том, что С++ - язык мультипарадигменный. Посмотри на название: "С++", ты видишь две части - си и плюсики. Иными словами, С++ это и есть Си буквально, но не только, а есть еще плюсы. Таким образом, на С++ можно писать "как на си", можно "как на крестах", а можно с разной степенью смешения этих подходов. По этой причине созданы два треда, данный и крестотред, и они оба актуальны и необходимы.
Попытки же воевать, противопоставляя эти области, это простое сектобыдло, гопота с улицы, которая всё делит на "поцонов с нашего раёна" и "казлов с других раёнов". Биопроблемы тупых биопроблемников, к програмированию не относится.
>>80987
Массив одним куском плох для оптимизации из за фрагментации памяти. Лучше выделять произвольными кусками с возможностью фрагментации. Так работает файловая система на диске, вроде должно быть понятно по какой причине. Подобным образом работает любая надежная система. Почему сишкодебилы настолько зашоренные дауны, что не понимают очевидного, а только повторяют за бумажкой как безмозглые попугаи? Вот типичный пример такого идиотины >>81192 , увидел отличие от заученных определений и мирок с треском порвался, вызывая защитную реакцию: "врётиврётиврёти".
>С++ это и есть Си буквально
Не совсем. Си не является подмножеством крестов.
Вот на такое крестовый компилятор будет ругаться, и сишный нет:
char ch = 7;
void звезда pv = &ch;
int звезда pi = pv;
мимокрестовик.
Ну да, кресты построже с типами, больше нужно приводить явно, но это косметика.
И как было сказано, чисто сишный компилятор уже неактуален. Кто работает в узких сферах его применения, сам разберется, а большинство людей сидят на крестовом компиляторе. Повторюсь, данный тред нужен в первую очередь для изучающих сишную часть крестов, а не чистую сишку, которая неактуальна.
Странно что ты не высрал кучу текста.
>Массив одним куском плох для оптимизации из за фрагментации памяти
шо? любая cpu оптимизация щас в итоге заканчивается тем что структура данных проектирутся в виде непрерывного куска памяти и чтобы еще обход последовательный был..
чтобы кеши гретые были, чтобы конвеер не слетал..
эдакий шаг назад, намеренный примитивизм..
структуры разбиваются на массивы в фортран стиле, алгоритм переделывается так чтобы последовательный обход данных был, один за другим..
Ещё раз ты, глупый неосилятор, заквотишь мой пост, и я уничтожу твое самомнение, заквотив твой в такой же стене текста. Съезди отсюда нахуй детей в питон треде впечатять.
> фрагментации памяти
2019 год, 64-битные процессоры повсюду, терабайты адресного пространства...
> фрагментации памяти
> фрагментации
> памяти
Как же я проиграл!
>64-битные процессоры повсюду, терабайты адресного пространства.
Нет бога, кроме Интел, и Майкрософт - пророк его!
Ало, долбоеб отбитый, давно из школы 21 своей выходил? Сейчас даже на чайниках эмулируют х86, блять
Быдлоадмину жопку продолжает рвать, лол
Утерянное знание, хранящееся только на скрижалях писателей BLAS-ов, которое они передают из поколения в поколение.
Пед-история:
Работаю на С уже 2 года (область криптографии). В основном это всякие ГОСТЫ, изредка AES и тд. В си-шке далек от идеала, но стараюсь писать аккуратный код.
Получил сопутствующий опыт во всяких утилитах (утечки памяти, чтение дампов, мейки) и тд. (по работе пришлось немного освоить Java/objective-c)
После работы учу : Проф. разработка под Unix (C. Раго) и Совершенный код (Макконел)
Проблема:
Есть подозрения, что я занимаюсь херней и учу то, что не поможет мне в будущем. То есть, я может и стану лучше в Си-шке, мне очень нравится именно Си,но поиск вакансий где необходим чистый Си, наводит на мысль, что потом буду никому не нужен.. Потому вопрос, какие пути развития подскажете, что необходимо доучить, что бы и дальше писать на Си, но при этом быть гибким при смене места работы (embedded? *nix?)
> что необходимо доучить
Очевидный вариант - дрочить ядро линукса. Ну и на embedded понемногу поглядывать.
>Потому вопрос, какие пути развития подскажете
Я бы на Java бы перекотился, а Си для вставок и библиотек оставил
Ну, не Сишка, так что-то другое. Имеется ввиду значимость байтоебского языка. А бишку с таким же успехом топили бы скриптомакаки, так что предмет споров аналогичен.
важность быстрофикс
Лол! Ты думаешь байты ебать в си начали или что? Си стал крут из-за ахуенной системы типов и из-за развития ООП и программ пишущихся в память, но никак не из-за байтоебства, которое в си весьма посредственное и упраздненное генерацией асембли кода
Именно необходимость накатывать asm при малейшей потребности в байтоебстве была той болью, от которой спасло появление Си. ящитаю
Проблема только в том, что си это слишком высокоуровневый язык, чтобы в него перенести байтоебские функции, потому-то байты в нем никто давно уже и не ебет, да и современные компиляторы асм уже игнорируют и лексику преобразуют напрямую в машинный.
> лексику преобразуют напрямую в машинный
Что, прямо совсем напрямую? А оптимизируют они в астрале что ли?
А как же битовые поля, а как же постоянные шифты с масками, все пакед структуры для работы с железом, или это уже не байтоёбство?
>си это слишком высокоуровневый язык, чтобы в него перенести байтоебские функции
А что такое указатели и sizeof, если не байты? И где тут высокоуровневость?
>указатели
В таком случае когда ты Эксель на уроке информатики запускаешь ты тоже байтоебишь, долбоеб
>sizeof
>байты
)))) и этот сброд заходит в си тред каждый день рассказывать свое мнение об индустрии
Дальше не читал. Съеби.
> и современные компиляторы асм уже игнорируют и лексику преобразуют напрямую в машинный.
насколько я понимаю, таки gcc на одной из стадий компиляции переводит в ассемблерные код целевой машины, а потом уже конкретный ассемблер транслирует эти коды в машкод
а clang вроде как работает в двух режимах - либо может из своего внутреннего представления напрямую в машкоды перегнать, либо сначала в ассемблер целевой машины
само собой, оба компилятора могут генерировать/оставлять ассемблерный код если пользователь указал соотв опцию, чтобы этот код можно было посмотреть
в отладчиках просмотр ассемблерного кода - одна из основных возможностей
как подступает комбилер майкрософт - напрямую генерит или через ассемблер, я совсем не знаю
поправте меня, если кто больше знает
вообще, ходит такая полушутка - типа что хороший программист может назвать 5 стадий компиляции сишного/крестового кода, а очень хороший - все 11
> очень хороший - все 11
Есть еще плагины с кастомными проходами, которых может быть сколько угодно.
> как подступает комбилер майкрософт
Подходы к компиляции везде одинаковые. Там бэкенд в виде дллки в отличие от отдельных программ у гцц, поэтому оно слегка под капотом, но насколько я знаю, C2 работает только с промежуточным представлением, а асм генерит, только если ты для себя попросишь листинг.
по-моему все компиляторы нынче работают в варианте
1. Фронтенд генерирует IR
2. Бэкенд генерирует из IR обьектиники
"Ассемблера" там нет нигде,
я те говорю: что для gcc вроде это не так до сих пор
они там таки генерят сначала в асм целевой платформы, а потом этот асм уже транлируется конкретным ассемблером в объектник целевой платформы
НО не уверен в этом на 100%
Но я, наверное, должен дополнить, что с -flto все интереснее. И тогда там еще .s от LTO будет с рандомным именем.
Пойди документацию почитай, объебос диванный. Коли есть время ночью хуйню писать, найдешь время поучиться чему-нибудь.
Но у меня какоенто, трабл. Все запускается, но не работает правильно. Вась глянь пж - https://pastebin.com/QKfnrr2x
Подумай, что делает твой код, попробуй сам поработать компьютером и выполнить свой код допустим для массива из 5 элементов, сразу поймёшь, где проблема.
1[foo]
Ну в принципе да, все остальные ошибки в логике работы.
А ЧТО ЕМЛИ ОН СПЕЦИАЛЬНО НЕ ИНИЦИАЛИЗИРОВАЛ МИН, ТОГДА ЕСЛИ СОБИРАТЬ КОД НА MSVC МИН БУДЕТ РАВЕН 0xCCCCCCCC это как раз достаточно большое по модулю отрицательное число, ммммм обожаю теории
Тупо АРГ чувак, реально. Твой номер готов - bip-bup-bap 2220000011 00220 000()l1za/
Пытаюсь создать файл на мак оси, пишут абсолютный путь, пытаюсь открыть как wb но всегда возвращает null. Вангую что проблемы с какими-то пермишенами, но не знаю что конкретно.
Спасибо, я только что-то не нахожу нужно ли ее обнулять перед каждым вызовом сомнительной функции? Т.е. не будет такого что если нет ошибки то функция просто ничего не присваивает в переменную, и если была какая-то ошибка до вызова, то я могут спутать ее?
Ты же после вызова проверяешь на NULL. Думаю нет смысла еще и errno обнулять.
>>82731
Лучше сразу perror(), чтобы никуда не ползать и не запоминать магические числа.
>>82762
> Какого хуя происходит?
Дай угадаю. Ты опять где-то повреждаешь стек, но из-за того уродского стиля, которым ты пишешь, а еще из-за неполных исходников нихрена не понятно, где именно.
Если бы у тебя был нормальный комп, я бы послал тебя собирать с -fsanitize=address, это решило бы проблему без кода и использования мозга секунд за пять, но ты не ищешь легких путей.
Хотя в твоем случае, скорее всего ничего особо страшного. Но считается плохим стилем.
Ты охуенен. А мы за весь тред так и не заметили.
У меня syntax error от твоего объяснения.
> указателя на массив ебучих указателей
int ∗(∗a)[]
> для двумерного массива используется указатель на указатель в виде указателя на массив указателей
Нет, простого int ∗∗a более чем достаточно. По a[m] у тебя указатель на строку, по a[m][n] элемент.
речь идет о "настоящем" двухмерном массиве, те массиве массивов?
тогда ты не сможешь целиком расположить их в динамической памяти, размерность первого массива должна быть определена, и он, как следствие, будет размещен на стеке либо глобально
в k&r, кстати, этот вопрос обсуждается
но мы же не в js-треде
Да, надо линукс. Или можешь сделать полезное миру и портировать уже нормально наконец.
>>82917
С помощью рантаймовых проверок доступа по указателю, особой области со статусом каждого ебаного байта памяти, особого расположения блоков памяти и переменных в стеке и особых реализаций функций, манипулирующих с памятью, код, скомпилированный с этим флагом детектит большинство попыток доступа за пределы массива и прочие релейтед проблемы (типа use-after-free). При этом скорость работы гораздо выше, чем у других подобных решений типа мемчеков в валгриндах, а количество false negative меньше (но они есть, и никуда от них полностью не денешься).
>>82942
Не только leak, и leak можно самому детектить всегда, обернув malloc()/free() и поддерживая какую-нибудь структурку со списком используемых блоков. А вот для других вещей уже нужна поддержка компилятором.
Передавать их в функции?
Городить любые структуры сложнее массива. Например... связный список?
И ещё, сцук, значения матриц в самой равке одинаковые и не зависят от выдержки. Казалось бы: больше света -> больше значения, но вот хуй.
Есть соображения?
>пурпурные и зелёные
Спасибо, док.
Про этот конкретный формат не знаю, но так судя по всему у тебя YUV а не RGB. У меня такие же цвета были, когда компоненты хромы (U и V) в экстремальные значения уходили. Обычно они кодируются как 0-255 -> -127-128. С Y обычно всё чуть сложнее и зависит от конечного стандарта.
блок один в другой засунь, чтобы у тебя s==3 не считалось лишний раз. Алсо, переделай на
count += (s % 3 == 0);
препод по головке погладит.
и перепиши всю хуйню на расте
Охх, даже не близко. Это 16-бит равка BGGR
со значениями от 0 до 1023. Мне нужно провести операцию над ней, а потом сделать дебайер, чтобы посмотреть, иначе оно не смотрится.
Можешь сам проверить: отрезаешь от dng файла снизу блок размером image.height x image.width двубайтовых слов, умножаешь/делишь, приделываешь обратно к заголовку.
Для релиза оно слишком медленное (в 2 с чем-то раза медленнее, если я правильно помню), и отладочные символы ей нужны для красивых сообщений, и память жрет.
Функция принимает прикрил2. Объект pFrame содержит пикрил3
uint8 ★const dst[]
dst - массив константных указателей на uint8, что, после array decay, получается как
uint8 ★const ★dst
В этом или прошлом треде обсуждали: положить в ресурсы манифест с Common Controls 6, дернуть из WinMain InitCommonControls(Ex), дергать theme api, если рисуешь какие-то кастомные контролы. Опционально дергать DWM на предмет всяких прозрачностей. Рисовать на GDI+, если нужно сглаживание (но можно притащить не родную либу для векторной графики или вообще взять OpenGL). По идее еще Direct2D можно, но я в него не играл.
Блокнот. А когда язык выучишь - сам ответишь на свой вопрос.
Oracle linux + gcc + emacs
https://pastebin.com/PVcPSZam
Хуета громоздкая, решение нжвыглядит как код джавы вне джавы, особенно этот мерзкий енам. Прием функцией указателя на функцию это ваще пиздец уровня laba.cpp, тоесть ну нахуя тут это? Почему нельзя линкануть просто два сишника в либу и процедурно вызывать? Короче прикольно но максимум на уровне чтоб все ахуели как я могу, граничащем с я долбоеб
>Прием функцией указателя на функцию это ваще пиздец
Интерфейс, идентичный qsort. А есть другие способы косплеить template?
C4droid
Для VisualStudio есть _CrtSetDbgFlag.
Зачем косплеить template, если есть специальный язык с template, и знаний С тебе хватит для вката в него?
мимопроходил
даже не template, а лямбды. На крестах точно так же надо передавать функцию сравнения, если сортируешь что-то не для решения олимпиады, а для реальной задачи со структурами и ключами, и T::operator< не подойдет.
спася
То есть сортировка существует только для того, что ее использовали со стандартным операторов сравнения?
Лямбда это не совсем оно, лямбда это функтор, который работает как функция и соотв. передаваться как указатель на функцию.
А не в обратном порядке.
Может передаваться*
Функтор это класс с перегруженным оператором круглые скобки, лямбда это просто анонимный функтордля тебя анонимный, компилятор все развернёт в итоге и у него будет название конечно
лямбды могут делать захват контекста, а в функторы его приходится передавать
поэтому по месту удобней использовать лямбды, а если нужно решение которое будет использоваться во многих местах кода, то лучше по старинке сделать функтор, а лучше обобщенный функтор, а про могут еще и иерархию функторов заебашить
вышка по специальности, +10 лет реального опыта кодинга, выйдешь на 2.5k долларов (может быть)
до этого 5 лет вуза будешь нищим студентом, жрать дошики в общаге
потом работа несколько лет, денег будет хватать только на съем + жратва, буквально
как то так
Ну, например qsort_r берет пятый аргумент, который потом передает третьим аргументом в функцию четвертый аргумент.
qsort_r(arr, n, sz, cmp, v);
и каждый вызов функции сравнения будет
cmp(p1, p2, v);
(в принципе, на крестах это так и работает, только cmp определяется шаблоном, а указатель v потом передается первым, как this)
например так
qsort_t(arr, n, sz, memcmp, sz-4);
чтоб отсортировать массив sz-байтовых элементов, лексикографически сравнивая все кроме последнего dword.
А вот в tsearch (дерево бинарного поиска, есть в glib) не предусмотрено, поэтому приходится пилить static переменную в своем компараторе и менять ее, стучась в функцию специальной парой значений void*, где первое говорит, что мы не сравниваем а меняем эту хуергу, а второе - собсно замена для хуерги. thread-safety в заднице...
ну да
подобные задачи делаются через замыкания в языках, которые это нативно поддерживают
в крестах же есть синтаксический сахарок щас - лямбды с захватами, этакие неполноценные замыкания, а раньше это через функторы можно было делать
а в сишке делают так как ты написал
> thread-safety в заднице
_Thread_local давно завезли. Ты так извращаешься, потому что ты хочешь извращаться, а не потому, что это реально необходимо.
Проблема со статическими/глобальными переменными только в реентерабельности. А эта проблема редко встает, а там где она возникает, о ней думают еще при дизайне апи.
> social skills
А почему в России таким мягким словом называют "social skills"? Когда ИРЛ в России это подразумевает умение заставить более низкоранговых самцов отжиматься и приседать с табуретками, а самому в это время бить их ногой в туловище, кулаком по почкам и требовать ночью сладости, деньги и гигиенические принадлежности?
Ты по жизни привык все буквально воспринимать, вот тебе и тяжело понять что имеется в виду. Для нормальных людей это "сошел скилс" трансформируется в два простых правила - уважать себя и других, и не быть вафлером. На этом стоит закончить, не надо тред скатывать в сипп тред.
>уважать себя и других, и не быть вафлером.
Иными словами это значит, что бей по почкам и в туловище, иначе бить будут тебя, а еще и вафлером назовут.
Почему у меня никогда не завершается нормально цикл:
while ( (c = getchar())!= EOF);
Притом замени eof на что угодно, хоть 1, хоть 0, всё-равно он не завершается и дальше принимает ввод
Есть код реализации стека, вроде как все понятно, но зачем тут указатель на указатель? Объясните поподробней, если можете, как он тут используется.
Функция возвращает указатель, извиняюсь, не заметил. А с остальным что? Почему оно работает?
Я уже допер. Я и забыл о том, что *(a+1) == a[1] и что все это можно сравнивать.
Тупил минут 15, насрал в тред и сразу на меня снизошло озарение. Двач творит чудеса
так хуле оно не завершается?
Может кто-то работающий код, принимающий на ввод символы через getchar запилить и сюда скинуть?
что угодно, короче мне протестировать, может это у меня clion потек, но я реально не понимаю
Тем что тебе надо терминировать ввод. В Linux ctrl+D. В Windows вроде ctrl+Z, но я не уверен
ctrl + D, как я и ожидал - в clion чет нашаманили, в итоге там это не работает лол, в онлайн компиляторе все работает
Чувак, int func(int &count) - ссылка на int. В чистом Си нет ссылок.
int func(int * count) - указатель на int, они есть и в Си и С++
В Си & - взятие адреса переменной.
Т.е. где-то в коде
int y = 12;
func(&y) - ты передаешь адрес переменной y. А адреса у нас хранятся в типе-указателе.
Расширение идеи указателей в С++. Похоже на указатели, но имеет ряд отличий.
Это копия, сохраненная 27 апреля 2019 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.