Это копия, сохраненная 5 декабря 2018 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
Пожалуйста, пользуйтесь https://ideone.com/ или http://pastebin.com/ для вставки кода, если он длиной больше нескольких строк или содержит [i] или ∗.
Что читать:
- Brian Kernighan, Dennis Ritchie "The C Programming Language": http://www.cypress.com/file/56651/download
- Stephen Prata "C Primer Plus, 6th Edition" (2014): относительно свежая, знает про C89/C99/C11, описывает различия, объемная (около тысячи страниц), годная, с вопросами, упражнениями и ответами. Читать после K&R или до.
- Zed A. Shaw "Learn C the Hard Way" (2015): годное пособие для гуманитариев для гуманитариев!
- Немного примеров хорошего стиля: http://www.oualline.com/books.free/style/index.html
- ООП, например: http://www.cs.rit.edu/~ats/books/ooc.pdf
- Стандарт ISO/IEC 9899:1999 (он же C99): http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf (драфт)
- Стандарт ISO/IEC 9899:2011 (он же C11): http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf (драфт)
- man/Dash/zealdocs
Чем конпелировать:
- Очевидный GCC.
- clang: оче годно, батя рекомендует.
- Intel C++ Compiler: оптимизации, тысячи их.
- Visual Studio 2017 Community Edition: внезапно этим стало можно пользоваться, особенно с тулсетом clang/C2. Поддержка C11 на уровне "есть все, что тебе понадобится в реальном проекте плюс кривая библиотека". Анализатор кода в комплекте.
- Pelles C (шиндоуз онли): поучиться, вкатиться в C11 (стандарт полностью реализован, имеются в том числе threads.h и прочие stdatomic.h), но количество багов в оптимизаторе и редкие апдейты напрочь отбивают желание собирать этим что-то сколько-нибудь серьезное.
- TCC: очень маленький компилятор с багами и поддержкой C99. С ключом -run умеет компилировать код в память и запускать его, что позволяет писать скрипты прямо на сишечке.
Что еще почитать:
http://c-faq.com/
FAQ из comp.lang.c. Древний, но все еще актуален.
Samuel P. Harbison, Guy L. Steele Jr. "C: A Reference Manual, 5th Edition" (2002)
Ебаный пересказ стандартов C89 и C99 (включая стандартную библиотеку). Для не осиливающих стандарт в оригинале. Читать в качестве подготовки к собеседованиям (есть задачник с ответами) и для ознакомления с масштабами пиздеца перед написанием своего парсера/компилера.
Peter Van Der Linden "Expert C Programming. Deep C Secrets" (1994)
"Си: грязные истории". Смехуечки, немного объяснений, чем обусловлены особенности языка, всем известные подводные камни кто там ругал косяки в JS? у нас в сишечке их гораздо больше, просто они лучше спрятаны, немного байтоебли и непонятно откуда взявшаяся глава про старинные плюсы. Читать в качестве сказки на ночь (на пару вечеров хватит).
Richard M. Reese "Understanding and Using C Pointers. Core Techniques for Memory Management" (2013) - почитать, вкатиться в указатели.
Ben Klemens "21st Century C: C Tips from the New School" (2012)
Paul Deitel, Harvey Deitel "C for Programmers with an Introduction to C11" (2013)
Stephen G. Koch@n "Programming in C (3rd Edition или 4th Edition, если найдется)" (2014)
MISRA Ltd. "Guidelines for the Use of the C Language in Critical Systems" (2013)
Набор рекомендаций по написанию надежного кода на C (промышленный стандарт). Читать - однозначно, следовать - вдумчиво и без фанатизма. Также можно посмотреть https://www.securecoding.cert.org/confluence/display/c/SEI+CERT+C+Coding+Standard
Еще более длинный список: http://www.iso-9899.info/wiki/Books#Learning_C
Онлайн-утилиты:
- https://godbolt.org/ - Compiler Explorer позволяет посмотреть выхлоп компиляторов для введенного куска кода (больше полусотни разных версий компиляторов).
- http://cdecl.org/ - С Gibberish ↔ English помогает читать сложные сишные декларации.
Прошлые треды:
- №31: https://arhivach.cf/thread/366210/
- №32: https://arhivach.cf/thread/375538/
- №33: https://arhivach.cf/thread/383767/
При этом я продолжаю колоться и есть кактус. Языки с виртуальной машиной как Джава и До-диез брать не хочется (До-диез вообще завязан на инфраструктуру мелкомягких), интерпретируемые языки тоже (не скрипт же я пишу), Голанг вроде бы фичастый, но сейчас они в очередной раз что-то меняют, вдпцг генерики появятся, Руст мутный и так толкался во все щели, что и знать не хочу, остаётся C++, в котором если без классов писать (строка там тоже класс, емнип), то на выходе тот же C.
Вопрос: что я тут делаю и почему оставаться тут - это неплохо? Мог бы в конце концов выучить уже C++ и ебашить код со скоростью света.
NON_TYPE = (uint8_t)0x0,
FIRST_TYPE = (uint8_t)0x1,
SECOND_TYPE = (uint8_t)0x2,
};
typedef struct __attribute__((__packed__)) _my {
enum types type;
} __attribute__((__packed__)) my;
printf("size: %u\n", sizeof(my));
Мне нужно чтоб enum весил 1 байт, т.к. у меня место сильно ограниченно, как запилить такое? Сейчас, результат кода выше, выдает size: 4, а нужно чтоб было size: 1
А все, уже сам нашел ответ
https://stackoverflow.com/questions/49723430/gcc-enum-is-not-packed-as-expected
Не знал что атрибут __attribute__((__packed__)) в структуре, не упаковывает enum, нужно юзать enum c упаковкой __attribute__((__packed__)) отдельно
> При этом я продолжаю колоться и есть кактус.
Ты прям моими словами разговариваешь, у меня точно такаяже проблема, и я точно также продолжаю жрать этот кактус
Можно.
>- Zed A. Shaw "Learn C the Hard Way" (2015): годное пособие для гуманитариев для гуманитариев!
А как определить ты гуманитарий или технарь?
Я сразу понял, что 50%.
Но потому , что я изучал теор.вер сам лично и знаю что 1 из 2 это фифтик шанс. Если бы мне дали эту задачу в 18 лет, может я бы ошибся, потому что всю школу я тупо игнорил математику и все что с ней связано. Ну то есть, я сейчас говорю о том что нужно иметь некий базис, как минимум хоть раз где-то пообщаться на тему соотношений, процентов и тд. Разве это показатель того логично устроен твой мозг или нет*?
>1 из 2 это фифтик шанс
1 из 1000 тоже 50% шанс, либо вытянешь, либо нет. Остальное матанопетушиное говно.
> Мне нужно чтоб enum весил 1 байт
И не надейся. Тебе в кресты, у них есть enum class, которому можно задать размер. Но никто тебя не заставляет в сях писать enum foo variable, пиши uint8_t variable и присваивай ей свои значения безо всякой типизации.
>>70169
> А как определить ты гуманитарий или технарь?
Если ничего другое не помогает, , читай хардвей. Если хоть как-то можешь читать Прату, даже если читается от силы страница в день, да и та с болью - лучше читай Прату.
>50% шанс, либо вытянешь, либо нет.
Ну окей, а то что вероятность 1\2 , в этом я прав?
А то там в треде такие беседы идут, что я начинаю сомневаться.
Алсо, там люди начинают писать проги с функцией rand()
даже не зная,что все компьютерные рандомы- это псевдослучайные числа, а не тру рандомы
Это с точки зрения теорвера имеющим место только в больном мозгу математика. В реальности только 50/50. Все эти математические подходы знатно сосут на примере покера ну иои прогнозов рынка.
>>70205
>Если ничего другое не помогает, , читай хардвей
Это утверждение логическая ошибка. Типо раз тебе не помогли другие книги , то ты гуманитарий. Во- первых они могли тебе не помочь лишь потому, что ты ленивый и мало практиковался. Во-вторых, книга еще может не помочь, если ты не понимаешь стиль текста его автора, либо язык автора в плохом переводе. В третьем у тебя могут быть другие парадигмы обучения и методы.
Поэтому я так и не получил точного определения как определить гуманитарий ли я, или нет.
> 50/50
Ну ты тоже щас не прав, мне кажеться.
Для ТЕБЯ ДА все что ты вытаскиваешь 1 раз - 50 на 50 шанс.
Но если бы ты вытаскивали не 1 раз, а несколько. То ты заметил, что найти шарик в двух ящиках намного быстрее, и шанс выше, чем найти шарик среди 1000 ящиков, и шанс что ты найдешь его с 1 попытки очень мал.
Потому что покер и рынок это частотная вероятность, а не теоретическая, если бы ты бесконечно играл в покер, то увидел бы ту самую вероятность.
>если бы ты бесконечно играл в покер, то увидел бы ту самую вероятность.
А если бы не увидел? Ты так говоришь, словно кто то бесконечно что то подсчитывал. Математика не имеет отношение к реальному миру, да же больше того, она вредна, ибо зашоривает мозг.
>ты вытаскивали не 1 раз, а несколько
Ах если бы да кабы. Даже без математики понятно, что чем меньше помех, тем больше шанс вытащить. Но вероятность 50/50. Даже если будет миллиард зеленых шариков и один белый, то ты его либо вытащишь либо нет, но шанс не большой, да.
Фигню несешь, какой-то полемикой или софистикой занимаешься. Конечно вероятность вытащить 1 шарик из 1000 коробок(не зная в какой он) явно не 50\50.
50 на 50 это именно для тебя иллюзия относительно слов "вытяну" или "не вытяну"
>Математика не имеет отношение к реальному миру, да же больше того, она вредна, ибо зашоривает мозг.
Если человек не долбаеб, то математика не зашорит его мозг. Ведь он будет понимать что это лишь инструмент для вычислейний\поисков чего-либо\измерений.
>инструмент для вычислейний\поисков чего-либо\измерений.
Математики здесь при чем? Инструмент создают те, кто им пользуется.
Нет, народом. Хотя есть искусственные языки которые придуманы лингвистами
>>1270213
>>1270215
О! Пасибки.
Если это всё, то это дожно работать правильно:
http://rextester.com/BAD13339
Может можно и короче как-то, но у меня так получилось, и вроде таки получилось.
Ты туповат, не так ли? Математика это фундаментальная наука. На ней основано всё. Весь мир ей подчиняется.
Помогите на Си, нихуя не понятно. Учитель не объясняет нихуя
Реши эту задачу на бумаге, потом поймёшь, как написать программу.
> И не надейся.
Чем плохо использование в enum __attribute__((__packed__)) ?
>пиши uint8_t variable и присваивай ей свои значения безо всякой типизации.
Не очень понял, это как? Просто объявить uint8_t types, и без всяких енумированных констант, просто юзать циферки (0x0 - 0x7)?? Ну этоже совсем говно код, неуправляемый, выйдет
> Рост цен ежемесячно увеличивает расходы на 3%.
> на 3%.
Очевидное занижение уровня инфляции и сокрытие реальной ситуации в экономике страны
блин, я прочитал как 3% в год, вообще инфляцию всегда в годах считают, и только иногда в кварталах
К примеру расходы равны 10 000\месяц.
Через месяц уже +3% , получается 10300. Через еще один месяц + еще 3%, получается 10609. Через еще один месяц +3% к сумме = 10 927.27. И так далее.
Получается все больше и больше, потому что мы прибавляем +3% к сумме предыдущего месяца.
> Чем плохо использование в enum __attribute__((__packed__)) ?
Тем, что это расширение гцц.
> Не очень понял, это как? Просто объявить uint8_t types, и без всяких енумированных констант
typedef enum MyEnum {
MY_FOO = 1, MY_BAR = 2,
} MyEnum;
Используешь uint8_t x = MY_FOO там, где размер важен, и MyEnum y = MY_BAR там, где ты можешь себе позволить использовать int. Неупакованный enum быстрее (особенно на архитектурах, отличных от x86) за счет отсутствия телодвижений по расширению байтов до полного слова. Дополнительной безопасности enum type сам по себе не дает твоему коду, MyEnum y = 100 - это полностью валидный код. Поэтому все, что ты теряешь, используя uint8_t - это хинт в виде имени типа, но это можно решить банальным typedef uint8_t MyEnumPacked, вот и все.
С него - с Си, не с веба блядь
это будет как отдельный диалект, параша ебаная
тебе нужен чистый си или залупа крокодила?
если первое, то нахуй VS
если второе (по-любому VS to est'), то тогда хуй его знает
там по идее какую-то строку в .cpp файле нужно дописать и будет как будто .с
Ты даже установить студию не можешь, ну или хотя бы погуглить.
давай скажи, что ничего не нашёл
Разработка классических приложений на C++. Создашь C++ проект, создашь файл, укажешь расширение .c, будешь писать на Си.
>>70715
Pelles C все. Несколько лет назад Pelle дропнул поддержку ARM в качестве таргета, теперь, после двухлетнего молчания он дропнул поддержку 32-битной версии компилятора, а когда он появится в следующий раз, он скажет, что его все заебало, и даже исходников после себя не оставит. Можешь скринить.
>>70725
У MS один и тот же компилятор для C и C++, называется cl.exe.
В чем я не прав
Там есть какая-то галочка типо си-проект, там в компилятора просто какие-нибудь флаги используются, хз.
Мимо та же ситуация.
Не помню галочек, язык детектится по расширению файла, ничего дополнительно делать не нужно. А вот если ты извращенец, и хочешь компилировать .cpp как .c или .c как .cpp, то есть /TC и /TP соответственно.
Новую конфу треда добавьте в шапку в некст треде @hcdev
Телеграмодебил, свали.
О, прямо сегодня думал не создать ли такую. А тут ты. Ща чекну
scanf ("%s", ch);
printf ("%s", ch);
Ананасы, обесните мне, куда строка попадает? Массив же не объявлен. Где эти байты?
Алсо gcc сожрал это без претензий и на рантайме все работало.
>я прост где то подобный пример видел, то ли в крестах такое было то ли ещё где.
В крестах можно в функцию отправить ссылку вместо указателя. Это когда ты можешь просто имя переменной отправить, а функция работает так же, как если бы ты отправил указатель в си.
>Алсо gcc сожрал это без претензий и на рантайме все работало.
Формально претензий нет, но у тебя указатель не инициализирован. То, что он не указал на мусор - повезло.
Собственно с чего бы? Он просто присваивает указателю какой-то адрес, и потом его распечатывает, пока он не обращается к памяти на которую указывает переменная, а она очевидно не выделена, все валидно работает.
А да, лол.
>вижуал залупио
Зачем тебе эта параша, очевидно тебя анально пытаются заманить в сисярп, и сломать тебе жизнь...
Есть же божественный CLion, больше ничего не нужно же.
хотя я сам обхожуть Vim`ом, Sublime`ом, и только если чтото замороченное то Clion запускаю, он сразу все подсказывает
>тормозящее платное джаваподелие
Может у того анона сервернвя стойка с блейдами специально да КЛиона выделенная.
пидоры какие-то с другого района - даже смотреть теперь не буду. почему не в дисе? - в него и с браузера заходить можно!
Поставь LLVM и хуячь через терминал
Есть переменная и массив:
DIR = ./test
TEST = test1 test2 test3 test4 test5
нужно получить массив TEST_DIRS вида:
./test/test1/test1 ./test/test2/test2 ./test/test3/test3 ./test/test4/test4 ./test/test5/test5
> тормозящее платное джаваподелие
У меня ноут i5, 16Гб рам, Ubuntu 16.04, все летает, вообще никаких тормозов.
> платное
КОМУНИТИ ЕДИТИОН
да и вообще какая проблема заплатить немножко денежек за ОЧЕНЬ годный продукт?
Неговоря уже про то что можно в докере поднять лиценз сервер и самостоятельно активировать если такой бомж...
Есть местный дис канал?
>ОЧЕНЬ годный продукт?
Который напоминает дауненку названия операторов? make уже прикрутили, лол?
> OpenGrok для навигации и поиска
В браузере, фу. Труъ посаны используют пикрелейтед, его так никто и не смог превзойти.
>В браузере, фу
А мне наоборот норм, можно сразу в инторнеты переходить, да и много чего у меня локально через браузер работает
Полгода назад попробовал в первый раз, неделю покодил, надоело, заб и так каждый месяц. Вот опять. Но на этот раз я точно, хех мде
У меня тоже так, 1 раз бросил спустя недели 2. А сейчас во второй раз , уже подсел походу _(идет 2 месяц)_.
Почему Си выбрал?)
Люблю структурное программирование. Ну и сишка это классика, это как латынь среди языков программирования, это знать надо. Еще у языка богатая история, он крепко занимает свою нишу, мне интересно железо, меня привлекает его строгость, простота и то, что он близок к корням программирования как промышленной отрасли, он очень портабельный и на нем можно запустить какую-нибудь крутую железяку. Люблю си. Кореш говорит, что я дебил и лучше бы за джаваскрипт скорее взялся, чтобы работать со смузи в коворкинге
Прав твой кореш, на сишке вероятность найти работу крайне мала
> лучше бы за джаваскрипт взялся
Не скажу конкретно за твоего друга, но обычно так говорят люди которых программирование это лишь профессия для заработка. Либо это люди которые себя считают умнее других, и им кажется что они очень хитрые, раз выбрали сразу самый модный и популярный язык и сэкономили время. Но это на самом деле смешно звучит, когда речь идет о программировании как о любимом деле.
Я с ассемблера на JavaScript перешёл. Нормально, считаю годится для изучения. Сейчас листаю свои бумажные книжки по программированию C++\C#\pascal всё стаёт понятно, раньше пытался учить и не понимал. Мне было сложно смотреть на код где столько писанины, с непривычки наверно.
С cmake не путаешь? Ололол
Я правильно понимаю, что мы передаем указатель(то есть адрес нашего массива mas) в нашу функцию, а там он печатает ее, Но! Возникает вопрос.
получается, что массив это соединенные блоки памяти и байты с этими данными:
H
E
L
L
O
идут друг за другом? Именно поэтому имея адресс 1 ячейки, а именно 'H' мы итерацией идем по массиву?
эй , куда мой ай(буква) делся
Ну, почти
Продолжаю. Сделал задание с учётом этой штуки на псевдокоде посредством рекурсивной функции. Круто, да?
>Для замены пробелов на табы математика не нужна.
Ну, понятно. Но как бы ты сделал? Смешно, но мне показалось, что это путь наименьшего сопротивления. Буду рад узнать более очевидные решения, потому что задачка (для меня) интересная.
> Но как бы ты сделал?
Да так же в общем-то. Просто описывается это простым человеческим языком, потому что само по себе простая и логичная вещь. Копируешь символы из входного потока в выходной. Если встретил пробел - не копируешь, а считаешь пробелы. Если дошел при подсчете пробелов до очередной позиции табуляции или встретил по пути таб - выводишь таб, если не дошел и не встретил - выводишь подсчитанное количество пробелов. Считать можешь внутренним циклом, можешь сделать флажок, с флажком меньше дублирующегося кода типа контроля границ.
Это ты, конечно, просто и логично придумал, но сложность этого задания в том, что позиция табуляции постоянно смещается туда-сюда, потому что таб может представляться от 1 до 8 пробелами включительно, т.е. от 1 до 8 элементов в массиве у тебя могут быть заменены на один элемент табуляции в хитровыебанных местах, и если ты заранее не знаешь ввод, то и индексы элементов, под которые подгоняется табуляция, так по-простецки выяснить не получится.
> т.е. от 1 до 8 элементов в массиве у тебя могут быть заменены на один элемент табуляции
Какие нахуй массивы, какие элементы и индексы? Ты читаешь посимвольно, можешь getchar() использовать (собственно, в K&R от тебя вроде бы getchar() и ждут).
> что позиция табуляции постоянно смещается туда-сюда
Позиция табуляции никуда не смещается, она фиксирована, она всегда кратна n (1n, 2n, 3n, 4n и т.д., для таба шириной 8 это будет 8, 16, 24, 32), в этом вся суть использования табов в тексте. Ты точно знаешь, сколько символов (похуй, каких) ты прочитал в текущей строке, оно равно количеству твоих getchar() забудем пока про табы во входной строке, пусть там только пробелы и не-пробелы, и поэтому ты точно знаешь, что после очередного символа ты оказался на позиции табуляции. И если ты оказался на позиции табуляции, а перед этим ты прочитал пробелы, ты выводишь сраный таб. Только в этом случае. И единственное, что тебе остается: считать ебаные пробелы и запоминать их количество вместо того, чтобы их выводить сразу.
Вот на входе у тебя "a......byyyy....z", точки - пробелы, а позиции табуляции я тебе жирным выделил. Вот ты прочитал a, вывел a, увидел пробелы и начал их считать (не выводя), насчитал 6 и прочитал b. Эта b не на позиции табуляции, поэтому ты вывел 6 пробелов, которые ты запоминал (только поэтому ты их и считал), вывел b, прочитал y. Ты на позиции табуляции, но пробелов перед y не было, поэтому ты вывел y, а потом прочитал и вывел еще три y. И опять начал считать пробелы. И прочитал 4 штуки, и такой - опа, z на позиции табуляции, и у тебя до нее было... абсолютно похуй, сколько, но у тебя БЫЛИ пробелы, поэтому ты высрал таб, высрал z и на этом закончил. И ничего хитровыебанного в этом нет. Конечно, тебе нужно бы обрабатывать концы строк и табы во входном потоке, тебе стоит попробовать не считать символы до бесконечности (а вдруг тебе 8 гигабайт скормят, а int 32-битный, а размер таба не кратен 2^32), но в целом это десять ебаных абсолютно очевидных строк.
> т.е. от 1 до 8 элементов в массиве у тебя могут быть заменены на один элемент табуляции
Какие нахуй массивы, какие элементы и индексы? Ты читаешь посимвольно, можешь getchar() использовать (собственно, в K&R от тебя вроде бы getchar() и ждут).
> что позиция табуляции постоянно смещается туда-сюда
Позиция табуляции никуда не смещается, она фиксирована, она всегда кратна n (1n, 2n, 3n, 4n и т.д., для таба шириной 8 это будет 8, 16, 24, 32), в этом вся суть использования табов в тексте. Ты точно знаешь, сколько символов (похуй, каких) ты прочитал в текущей строке, оно равно количеству твоих getchar() забудем пока про табы во входной строке, пусть там только пробелы и не-пробелы, и поэтому ты точно знаешь, что после очередного символа ты оказался на позиции табуляции. И если ты оказался на позиции табуляции, а перед этим ты прочитал пробелы, ты выводишь сраный таб. Только в этом случае. И единственное, что тебе остается: считать ебаные пробелы и запоминать их количество вместо того, чтобы их выводить сразу.
Вот на входе у тебя "a......byyyy....z", точки - пробелы, а позиции табуляции я тебе жирным выделил. Вот ты прочитал a, вывел a, увидел пробелы и начал их считать (не выводя), насчитал 6 и прочитал b. Эта b не на позиции табуляции, поэтому ты вывел 6 пробелов, которые ты запоминал (только поэтому ты их и считал), вывел b, прочитал y. Ты на позиции табуляции, но пробелов перед y не было, поэтому ты вывел y, а потом прочитал и вывел еще три y. И опять начал считать пробелы. И прочитал 4 штуки, и такой - опа, z на позиции табуляции, и у тебя до нее было... абсолютно похуй, сколько, но у тебя БЫЛИ пробелы, поэтому ты высрал таб, высрал z и на этом закончил. И ничего хитровыебанного в этом нет. Конечно, тебе нужно бы обрабатывать концы строк и табы во входном потоке, тебе стоит попробовать не считать символы до бесконечности (а вдруг тебе 8 гигабайт скормят, а int 32-битный, а размер таба не кратен 2^32), но в целом это десять ебаных абсолютно очевидных строк.
тогда уже Haskell
Не уходи, нас и так мало..
> А потом оказывается, что ой как нужна
А математика какого уровня нужна? Я знаю 9 классов тока
> в интерпритируемых языках
Ты просто думаешь об указателях, как о чем-то особенном. Представь, что адресное пространство - это огромный массив байтов, а указатель - это индекс в нем (так оно и есть в большинстве случаев), и все будет точно так же, как и в любом другом языке программирования. Хоть в питоне, хоть в жаваскрипте. Странно было бы, если было бы как-то по-другому.
> байты с этими данными: H E L L O идут друг за другом
Ячейки в массиве идут друг за другом, вот неожиданность! Алсо, можешь выделить в жс Uint8Array побольше и работать с ним, как с сырой памятью, можешь даже маллок написать, который будет оттуда байты куски выдавать и еще strcpy запилить заодно, чтобы все охуели, как ты можешь (так вм пишут на самом деле).
>Ты просто думаешь об указателях, как о чем-то особенном
Да, есть такое.. Ну яж ноВиЧоК.
А побайтовые сдвиги есть в других языках?
Побитовые? Да, как правило есть. Если нет, легко заменяются умножением и целочисленным делением на степени двойки (привет, Visual Basic).
while(условие первое)
{
while(условие второе)
{
Как отсюда выскочить наружу без goto?
}
}
Я знаю всякие штуки с exit(), abort() и return; Но теперь собственно вопрос. Можем ли мы как-либо задействовать сигналы, например запилить SIGALARM или что-то еще с таймером, чтобы внутренний цикл покрутился, но по происшествии времени процесс прервало по сигналу и поток передался в колбек-обработчик этого сигнала?
Я встряну, ибо вопрос немного больной для меня. Сам вот учил программирование с си чистого и теперь освоить плюсы могу без проблем (вообще с ними, но в целом норм), а вот в сторону джаваскрипта даже смотреть не могу. Ну нинраицца и всё тут. Синдром утёнка у меня? Чё делать?
А нахуя ты делаешь бесконечный цикл?
Ну ты можешь в оба условия добавить volatile-переменную (да, volatile плохо, я знаю), которую будешь ставить в обработчике сигнала. А в чем вопрос-то?
Чем тебе не нравится goto?
вскукареки аля это плохой стиль не принимаются, если использовать goto грамотно, то код не становится менее читабельным, один из таких примеров как раз у тебя, когда нужно из вложенного цикла уйти во вне внешнего цикла.
Он походу брут пишет и хочет выводить статистику периодически. Собственно, тоже классическая задача.
Так тогда в самом цикле можно сделать чтоб каждый 10к шаг выводил нужную статистику. В чем проблема?
Захотел
Бля, проиграл люто
Если он не нравится, но при этом есть необходимость учить.
То учи через силу. Во-первых если ты знаешь си, то тебе любой другой язык уже будет проще учить т.к суть везде одна, только "слова разные" и пару функций.. Во-вторых, чем больше учишь, тем потом легче учить дальше.
853x480, 5:10
Да.
assignment from incompatible pointer type (назначение из несовместимого типа указателя)
Не хочу постоянно юзать тип поинтера *void
должно же по идее работать, когда схожие типы.
mas уже указывает на первый элемент.
mas[0] это значение первого элемента.
&mas[0] это адрес первого элемента.
&mas[0] и mas это одно и то же.
А ты вместо этого делаешь &mas, что даёт тебе адрес, который указывает на адрес, который указывает на первый элемент.
>>74435
Вы оба не правы. В языке есть тип "указатель на массив". Указатель такого типа численно равен указателю на первый элемент, у него, но тип у него другой. И вообще, поведение языка чуть сложнее, чем "указатель на первый элемент". Вот вам: https://ideone.com/huAMFl
>Вы оба не правы.
Лол, ошибку я нашел сразу, а вот как попытался сам себе объяснить, так охуел, в пизду короче, я сегодня на такое не способен
Ты молодец
>Zed A. Shaw "Learn C the Hard Way
На русиш не переводили? А то тут братишке нужно помочь с С (не спрашивайте зачем), а у него настолько плохо с англицким, что он карту МТГ прочитать не может.
#include <stdio.h>
int main() {
int x = 4294956830;
while (x > 71585) {
printf("%d ", x);
x -= 71585;
}
printf("%d", x);
}
Самое интересное что он вроде работает, но не с этими числами
У тебя, как минимум, X принимает отрицательное значение, так как твоё числе в signed int не помещается.
Соответственно, он никогда не бывает больше 71585.
У тебя 32-битный знаковый int с диапазоном от -2147483648 до 2147483647 включительно. Очевидно, что (int) 4294956830 = -10466 никак не больше 71585.
В данном случае — да, так как в unsigned int он помещается. Но помещается еле-еле, так что если возьмёшь X побольше, то снова работать не будет.
Ты просто не знал, что искать.
в файле путь до папки с ромами, в пути есть кириллица, а файл в формате ютф-8 (сигнатура убрана). так вот, я не очень понимаю, почему это работает? виндовс 7.
причём кириллицей имя пользователя - я так понял какая-то специальная папка-сущность в винде. в плане, это либс подстраивается под кодировку и дёргает нужный винапи вызов (с юникодом или без), или имена файлов в семёрка в ютф8, или у таких папок много имён-линков в разных форматах?
static int f(параметры)
{}
int libname_f(параметры)
{return f(параметры)}
почему бы и нет. декларируешь внешнее имя, а дальше пишешь как хочешь. хочешь аргументам типы поменяй, хочешь раздели на две функции. мне так кажется.
> это либс подстраивается под кодировку
Нихуя не понял, что тебе не нравится. В винде путь хранится в UTF-16, неюникодных апи не существует (внутри -A функций просто MultiByteToWideChar с CP_ACP и обратно), получаешь и кодируешь куда тебе нужно. Каким местом тут кодировка самого файла - совсем непонятно.
>>74709
1) Долбоебы.
2) Долбоебы решили, что когда-нибудь захотят изменить реализацию, но на самом деле никогда этого не сделают.
>Каким местом тут кодировка самого файла - совсем непонятно.
так и пиши: мне не понятно. в приведённом скрипте из файла берётся путь, склеивается (как есть) с Gods.zip и передаётся в программу.
и разве в винде ютф16, там же нет парных кодов.
и ты говоришь пути, это значит и имена фалов? ну вообще логично, просто забыл немного. наверно цигвин свою либс подсовывает, которая ожидает ютф-8.
или если он компилируется мингв, то тот либс предполагает ютф-8 в fopen.
> Долбоебы
Вообще это кусок одного (относительно) известного гнушного проекта. Не знаю, уменьшает ли это вероятность долбоебизма, но изменения у них иногда происходят.
> и разве в винде ютф16, там же нет парных кодов.
Давно уже есть. В 2000 вроде еще UCS-2 был, но потом осилили полноценный UTF-16.
Я тут заметил у себя с недавних пор привычку, которая возможно вредная и вообще плохо, хочу спросить у вас, что скажете.
Привычка следующая, при работе со строками делать как-то так ( вместо звездочки):
char str; // строка полученная в аргументе, ее же, допустим, нужно вернуть, так что куда указатель показывал, там и останется
for(char i = str; i; ++i)
{
А тут всякие дела делаются. Смысл в том, что мы пользуемся свойствами си-строк, что они заканчиваются нулем, а указатель на нуль разыменовывается как 'ложь'.
Можно было сделать while и завести лишнюю переменную, но мне не хочется.
}
Итак, какие подводные камни? Я спрашиваю, т. к. нигде больше не встречал такой штуки. Может тут где-то нарушение нюансов стандарта или слишком неочевидный подход для того, кто будет это поддерживать?
Мумь пожрал и тот символ тоже.
char ^str; // строка, указатель не менять
for(char ^i = str; ^i; ++i)
{
Работа со строкой. Проходим по ней через временный указатель i.
}
Я бы настороженно относился к этому автору.
Я здесь вижу только все проблемы, связанные с тем, если нуль случайно проебётся.
Это нормальный подход. Особой разницы между for (size_t i = 0; str[i]; i++) и for (char ∗ptr = str; ∗ptr; ptr++) нет, пиши, как тебе нравится. Вариант с указателем может оказаться даже быстрее. Или тебя смущает, что в for что-то отличающееся от классического i = 0; i < n; i++? Ну так это тоже нормально, в for делают все сорта извращений вплоть до for (int c; (c = getchar()) != EOF; putchar(tolower(c)));
Если ты элементы массива явным перечислением задаёшь, то нулевой символ сам не ставится, кстати
sizeof(mas)/sizeof(int)
char - 1 байт, int - 4 байта это раз
Во вторых у тебя массив чисел, а не символов, у тебя число из массива может совпадать с кодом символа '\0' ты об этом не подумал а? а?
Ну так-то да.
Вообще, я читал где-то, что нуль-терминейшн строк это чисто конвенциональная херня, нужная потому, что некоторые функции стандартной библиотеки опираются на нулевой символ как конец строки
int ar[8] [8] [8]
и делаем, например в динамической памяти ещё один массив, но на базе указателей.
int *dinar // тут должно быть три звезды если макаба не сожрёт.
ну потом я короче как бы создаю массивы указателей на указатели потом ещё массивы указателей на массив и маллокаю всю эту порашу в динамической памяти.
Так вот вопрос, поскольку массив по сути указатель на первый элемент массива, то первый массив тоже тащщит на себе в нагрузку несколько комплектов массивов указателей.
Ты вопрос не задал.
В первом случае у тебя один указатель на массив.
А если у тебя 3 звезды, то у тебя не многомерные массив, а массив массивов массивов.
Что во многих случаях плохая идея.
Ты должен был прочитать введение в си массивы, организация памяти обязательно должна быть объяснена в любом учебном пособии.
> Как тогда перемотать его?
Это не файл, это поток, пайп не хранит данных ну почти, там есть небольшой буфер, и у FILE еще свой небольшой буфер есть, а лишь передает их от производителя к потребителю. Поэтому seek не имеет смысла - назад ты не можешь пойти, потому что данных уже нет, вперед не можешь, потому что ты еще текущие данные не доел, а rewind не имеет средств попросить производителя начать производить с начала, да и у производителя не всегда есть такая возможность в принципе.
Очевидно, что если тебе очень хочется взад, то ты можешь выделить память и хранить нужное количество прочитанных данных самостоятельно, а если хочется вперед, можно читать данные и выбрасывать их, пока не пропустишь нужное количество. Если все это слишком сложно, ты можешь банально писать из пайпа во временный файл, и поток сикать по нему сколько угодно, но такой подход уничтожает всю суть пайпов.
>>75409
> Так вот вопрос, поскольку массив по сути указатель на первый элемент массива, то первый массив тоже тащщит на себе в нагрузку несколько комплектов массивов указателей.
Массив - не только указатель, это тип. Обсуждали недавно, вот сюда глянь >>74469.
Допустим, у нас int arr[10][11][12] (чтобы не путать измерения). Этот массив ничего никуда не тащит, это непрерывный кусок памяти на 10 ∗ (11 ∗ (12 ∗ sizeof(int))) элементов. Когда ты индексируешь массив [], компилятор превращает твои arr[1][2][3] в арифметику указателей. Он точно знает тип (а значит и размеры) массива. Он делает ∗((int ∗) arr + ((11 ∗ 12 ∗ 1) + (12 ∗ 2) + (3))) (не забывай, что тут арифметика указателей и полученный офсет еще домножается на sizeof(int)). Все числа, кроме индексов, выделенных жирным - константы, поэтому они явно нигде не хранятся, а сворачиваются и попадают в виде непосредственных значений прямо в инструкции умножения. В самом массиве никакая размерность не хранится, она известна только на стадии компиляции. Это если не брать в расчет VLA, c VLA все сложнее.
Поэтому в случае нормального массива никакие промежуточные указатели не нужны. В случае с динамическим массивом int ∗ не несет никакой информации об измерениях, поэтому для доступа к элементам ты либо самостоятельно используешь формулу выше (например, классическое ptr[y ∗ width + x] для динамического двумерного массива), либо делаешь промежуточные указатели.
Алсо, если у тебя лишь первое измерение динамическое, например, массив из некоторого количества строк, состоящих из заранее известного количества (допустим, 11) столбцов, состоящих из заранее известного количества (допустим, 12) символов, ты можешь использовать указатель на массив char (∗arr)[][11][12] и заставить компилятор делать всю адресную арифметику (т.к., в таком виде компилятору известны все измерения, кроме первого, которое не нужно для вычисления офсета).
>>75417
> то у тебя не многомерные массив, а массив массивов массивов
Синонимы в Си и во многих других языках тоже.
> Как тогда перемотать его?
Это не файл, это поток, пайп не хранит данных ну почти, там есть небольшой буфер, и у FILE еще свой небольшой буфер есть, а лишь передает их от производителя к потребителю. Поэтому seek не имеет смысла - назад ты не можешь пойти, потому что данных уже нет, вперед не можешь, потому что ты еще текущие данные не доел, а rewind не имеет средств попросить производителя начать производить с начала, да и у производителя не всегда есть такая возможность в принципе.
Очевидно, что если тебе очень хочется взад, то ты можешь выделить память и хранить нужное количество прочитанных данных самостоятельно, а если хочется вперед, можно читать данные и выбрасывать их, пока не пропустишь нужное количество. Если все это слишком сложно, ты можешь банально писать из пайпа во временный файл, и поток сикать по нему сколько угодно, но такой подход уничтожает всю суть пайпов.
>>75409
> Так вот вопрос, поскольку массив по сути указатель на первый элемент массива, то первый массив тоже тащщит на себе в нагрузку несколько комплектов массивов указателей.
Массив - не только указатель, это тип. Обсуждали недавно, вот сюда глянь >>74469.
Допустим, у нас int arr[10][11][12] (чтобы не путать измерения). Этот массив ничего никуда не тащит, это непрерывный кусок памяти на 10 ∗ (11 ∗ (12 ∗ sizeof(int))) элементов. Когда ты индексируешь массив [], компилятор превращает твои arr[1][2][3] в арифметику указателей. Он точно знает тип (а значит и размеры) массива. Он делает ∗((int ∗) arr + ((11 ∗ 12 ∗ 1) + (12 ∗ 2) + (3))) (не забывай, что тут арифметика указателей и полученный офсет еще домножается на sizeof(int)). Все числа, кроме индексов, выделенных жирным - константы, поэтому они явно нигде не хранятся, а сворачиваются и попадают в виде непосредственных значений прямо в инструкции умножения. В самом массиве никакая размерность не хранится, она известна только на стадии компиляции. Это если не брать в расчет VLA, c VLA все сложнее.
Поэтому в случае нормального массива никакие промежуточные указатели не нужны. В случае с динамическим массивом int ∗ не несет никакой информации об измерениях, поэтому для доступа к элементам ты либо самостоятельно используешь формулу выше (например, классическое ptr[y ∗ width + x] для динамического двумерного массива), либо делаешь промежуточные указатели.
Алсо, если у тебя лишь первое измерение динамическое, например, массив из некоторого количества строк, состоящих из заранее известного количества (допустим, 11) столбцов, состоящих из заранее известного количества (допустим, 12) символов, ты можешь использовать указатель на массив char (∗arr)[][11][12] и заставить компилятор делать всю адресную арифметику (т.к., в таком виде компилятору известны все измерения, кроме первого, которое не нужно для вычисления офсета).
>>75417
> то у тебя не многомерные массив, а массив массивов массивов
Синонимы в Си и во многих других языках тоже.
>Синонимы в Си и во многих других языках тоже.
Внезапно, нет.
Сам же, пишешь
> Он точно знает тип (а значит и размеры) массива. Он делает ∗((int ∗) arr + ((11 ∗ 12 ∗ 1) + (12 ∗ 2) + (3)))
В случае же массива массива массивов, происходит вот что.
1. arr2 = (arr1 + index1)
2. arr3 = (arr2 + index2)
3. result = *(arr3 + index3)
>Актуально ли под x86 проверять указатели на NULL после malloc, calloc, realloc и т.д? Или это стереотип из времен когда 640кб должно было хватит ь всем?
Используй rust!
// arrptr - указатель на массив неопределенного количества int.
int (★arrptr)[] = &arr;
Какой-то извращенный способ написать две звездочки.
> Внезапно, нет.
Внезапно да. Есть два варианта: либо многомерные массивы поддерживаются как отдельная сущность, т.е., int foo[1,2,3], либо они конструируются из существующих, т.е., массив массивов int foo[1][2][3] - массив из 1 массива из 2 массивов из 3 int. Третий же вариант, когда у тебя массив указателей на массив указателей на int - это вообще строго говоря не массив.
>>75653
> int (★arrptr)[] = &arr;
> Какой-то извращенный способ написать две звездочки.
Две звездочки - это указатель на указатель на инт. Процитированный синтаксис - это указатель на массив интов. Это разные вещи: если посмотришь адреса в выхлопе программы, осознаешь, что во втором случае никаких промежуточных указателей нет.
я как-то задавал такой вопрос тут же, скинули код, когда осталась ещё память, но всё равно возвращался нулл и тогда писал в память с константами, поэтому я проверяю всегда, и тебе советую
// сильно ток не бейте
int print_bars(int len) {
for (int i=0; i < len; ++i)
printf("%c", 'X');
}
int main() {
int test_array[10];
for (int i=0; i < 10; ++i)
test_array;
print_bars(test_array[9]);
}
Если test_array[9] - куча иксов, если что-либо другое, то или ничего, или бесконечный луп.
Чому так?
Ой все, джва часа думал, а как только запостил, сразу все понял.
>test_array = i же
можете бить сильно
printf воспринимает нулевой символ, поэтому можно распечатывать его без функции print_bars, а просто вызвать массив как строковый: printf("%s", test_array); Ну это так
Алсо, for можно вот так вот задать вроде, олды, помохите, для краткости
например массив capitals типа bool хранит информацию о странах и столицах capitals[Russia][Moscow]==1, тогда москва-столица
> обратиться не по номеру элемента а по строке например
Нет, тебе придется реализовать ассоциативный массив или какое-нибудь дерево самостоятельно. Это несложно, простая реализация - буквально пара десятков строк.
> или символу
elem_type everychar[256];
> capitals[Russia][Moscow]==1
У одной страны может быть несколько столиц? Нахуй такое делать? Делаешь словарик страна -> столица (ассоциативный или даже обычный отсортированный массив, сложность лукапа от O(1) с удачной хэш-функцией до O(log2(n))). Но можешь и просто пронумеровать страны и столицы и сделать capitals[russia_index][moscow_index].
ну вот индексацией и решил воспользоваться, спасибо
Можно все, если реализуешь соответствующую структуру данных. Но не жди, что Си будет что-то делать за тебя, как компилятор паскалей.
- Я поехал в столицу, одна нога здесь, другая там, а третья...
Неспособность некоторых стран определиться, какой мухосранск лучше другого никак не влияет на то, что страна и столица - это 1:1 маппинг.
Ну хотят иметь три столицы, пусть имеют, места в базе полно.
Или, может, год лучше хранить в двух цифрах?
Проблема Y2K была по большей части надуманной, почти ничего нигде не сломалось. Ломаться начнет примерно лет через 40, а к тому времени дат из двух цифр уже в работающем коде уже точно нигде не останется.
>222ch.hk/pr/, 2058 год
>Проблема 32-битногг была по большей части надуманной, почти ничего нигде не сломалось.
> 2058
2038.
> была по большей части надуманной
Именно так. Еще почти 20 лет до переполнения 32-битного signed time_t и еще овер 80 лет до переполнения unsigned. 32-битные машины за это время спокойно вымрут сами, и насильно тащить в 32-битный код 64-битный time_t было совершенно незачем. Такие дела.
А где ты его запускать-то будешь, свое ПО? Вон дистры линукса один за другим дропают 32-битные ядра, скоро и о /lib32 позаботятся.
1)Поменять местами столбцы матрицы так, чтобы элементы первой строки оказались упорядоченными.
комментарии к заданию:
Массив создается динамический, работа с элементами массива происходит через указатели (т.е. в программе полностью отсутствуют квадратные скобочки). В главной функции (main) происходит только запрос размера массива (ввод пользователем с клавиатуры), задание элементов матрицы вручную или случайным образом (выбор пользователем), и вызов двух функций а)та, которая выполняет задачу; б)функция печати матрицы.
2) Дана строка. Если слова в ней упорядочены по алфавиту, то вывести 'yes', иначе вывести первое слово, нарушающее алфавитный порядок.
комментарии к заданию:
Строка записана в текстовый файл. Необходимо считать ее, после чего результат выполнения задания записать в другой текстовый файл. Слова могут быть разделены между собой пробелами, знаками препинания.
Да, они очень подробно расписаны, но я всё не могу взять в голову, с чего начать. Опытные аноны, помогите аутисту, натолкните на путь истинный.
Вторая задача: любой символ, представленный как int, имеет свою кодировку, при этом алфавит идёт в таблице кодов одной такой большой лепёхой подряд, в алфавитном порядке, т.е. ты можешь сравнивать их на порядок в алфавите через арифметические операторы сравнения. Сам алгоритм проверки я бы так сделал: первую букву слова можно находить по индексу табуляции, пробела и таба + 1, вторую -- то же самое, но + 2, и так далее. Сравниваешь первые буквы попарно, если первая буква как int меньше второй буквы (потому что код у более поздней буквы в алфавите больше, понятно да), то всё норм, потом вторые буквы, и так далее. Условие, при котором процесс останавливает работу и как он обрабатывает слова с разной длиной, придумай сам это легко
спасибо, стало чуточку яснее. Я правильно понимаю, что такие задания это ультраизи фигня, но не стоит отчаиваться, если они не получаются на начальном лвле или путь в прогеры уже закрыт? Ну и что можешь сказать по первой задаче?
1) В смысле, просто отсортировать по первой строке? Притащи что угодно, хоть selection sort, хоть пузырек и сортируй, там два с половиной вложенных for, но это медленно, потому что при сортировке столбцами ты будешь тратить время на перестановки второй и последующих строк в столбцах. Поэтому лучше сделай из первой строки матрицы пары массив пар (value, original_index), отсортируй его банальным библиотечным qsort-ом по value, а потом пройди по этому массиву и на основании original_index точно в таком же порядке переставь местами столбцы в матрице.
2) Наговнокодь динамический массив (или просто достаточно большой статический массив), разбей strtok-ом строку на слова и положи туда, пройди по массиву, сравнивая слова strcmp-ом. Если на каком-то шаге strcmp(item[-1], item) вернула 1 - массив не отсортирован.
Если анону помощь по-прежнему нужна, он и так в тред зайдет, а бампать этими хелловорлдами я не хочу.
Сагающий анон главный источник информации итт уже несколько лет, он отлично знает тонкости байтоебства, стандарты и их различия.
А ты петух залетный.
Кекнул
Тебе не жалко файл столько раз подряд насиловать своей amount? Она же там у тебя наверняка что-то читает внутри каждый раз?
>Write a program to print a histogram of the frequencies of different characters in its input.
Хуй с ним с хистограмом. Как тут по-нормальному сделать?
Думал так, но чот не выходит.
for character in stdin:
array[int(character)]++
for i in array:
print(char(i): array)
Да. Это псевдокод же.
> Чо не так?
Вот это:
> histogram[i] >= 'a'
Ты считаешь в массиве, индексируемом кодом символа количество символов, а сравниваешь количество с кодом символа. Не знаю, зачем ты вообще сравниваешь, но если уж хочешь ограничиться только буквами, сравнивай 'a' с i. Алсо, введя какой-нибудь UTF-8, ты попортишь память из-за размера массива в 128, а не 256 символов.
> Как тут по-нормальному сделать?
Что сделать? Что значит print(char(i): array)?
>Ты считаешь в массиве, индексируемом кодом символа количество символов, а сравниваешь количество с кодом символа.
Спасибо.
>Что сделать?
Там вакаба скушала.
Чтобы было:
с: 15
a: 27
b: 12
и т.д.
Чтобы вакаба не кушала, в оппосте есть магия. Чтобы получился такой выхлоп, исправь в printf %3d на %c.
Да, наверное это не очень рационально, ввел туда равную ему переменную, теперь компилятор segmentation core dumped выдает, пойду покопаюсь в указателях.
А тебя не смущает, что ты вот выделил массив указателей на double, выделил calloc-ом, они нули, а потом ты делаешь scanf("%lg", meas1[i]), т.е., scanf("%lg", NULL)? И чего ж оно сегфолтится? Тебе нужен простой массив даблов, т.е., double ∗meas1=calloc(...); и scanf("%lg", &meas1[i]...
Спасибо.
>Exercise 1-19. Write a function reverse(s) that reverses the character
string s. Use it to write a program that reverses its input a line at a time.
https://ideone.com/obvjq7
Вместо ожидаемого выплевывает пустоту. Защо?
Ну в который раз, только стоит запостить и сразу видишь свою ошибку.
Надо было return last_letter; сделать.
Тестируй тщательнее - ты наебался с индексами.
1) Строки из одного символа считаются за пустые, потому что return last_letter возвращает последний индекс, а последний индекс для строки из одной буквы - ноль.
2) Параметр у reverse называется len, а передаешь ты все тот же индекс. Но логика кривая, и поэтому оно работает. Вообще <= в цикле - это хороший признак, что у тебя либо 1-based индексы, либо ты где-то наебался на единицу.
3) Цикл заканчивается, когда i > len, т.е., указывает на следующий элемент после строки, но ты зачем то делаешь i + 1 при присваивании '\0', что приводит к test -> tsetx, где x - какой-то мусор из стека.
хелоу ворлд
Есть сборщик мусора = не может считаться ни системным языком, ни вообще упоминаться радом с Си.
Прожженные байтоебы могут убирать за собой мусор сами, за нормальных людей это делает уборщик.
> за нормальных людей это делает уборщик
Про этих нормальных людей целый тред есть >>1274731 (OP).
Напомню, что компилятор имеет право класть на этот атрибут любые свои части. Поэтому обычно делается зависимый от компилятора дефайн на __forceinline или __attribute__((always_inline)).
Clang тоже, разве нет?
Использую while(!kbhit()) для пауз в программе, но после нажатия любой клавиши соответсвующий символ печатется на экране, как этого избежать?
> после нажатия любой клавиши соответсвующий символ печатется на экране
Ты читай символ-то. Он же от _kbhit() никуда из буфера ввода не девается. Делай _getch() после цикла.
А зачем мне тогда вообще while(!kbhit()), ведь getch() далет то, что мне нужно и без while(!kbhit())? Почему тогда все советуют использовать while(!kbhit()), аргументируя тем, что getch() не всегда бывает надёжен?
Я не знаю, зачем тебе нужно while (!_kbhit()). Его сфера применения - когда тебе нужно делать в теле этого while, _getch() сам по себе в таких случаях не подходит, потому что блокирует поток, в котором вызван. Насчет надежности ничего не знаю, максимум там будет проблема с непустой очередью ввода, ну так она и _kbhit() тоже затронет.
Мне препод дал задачу "вывод чилса в двоичной\8чной\16чной системе"
Для 2чной написал цикл с выводом остатка деления на 2 и возвратом каретки
А эта ебучая каретка когда возвращается ,то заменяет все ,что было выведено до этого.Че за залупа блять?я быдлокодер с 10-ю минутами стажа в visualstudio
Ставь линукс.
Пользуюсь Emacs'ом, посмотрев это видео ужаснулся :')
Для cout конец строки std::endl
дерево* ф(строка){
дерево д;
д->val=символ_строка;
д->лево=ф(строка);
д->право=ф(строка);
return д;
}
ну вот для префикс а как изменить функция шоб можно было пост/ин фиксный порядок взять
просто считывая с конца не катит, строки не зеркальные ведь
3 строки это обзывательства одного и того же дерева, правила чтения ток разные, более подробно хз как
>>1>>79725
/ значит для обозначения листьев
> но инфиксная как тогда
А вот так. Обойди вот это дерево и сравни со своим обходом (кружочек - NULL). И что ты будешь делать c этим?
тупа char
>инфиксный порядок узлов дерева может быть несколько деревьев?
какой нах порядок? у тебя массив символ, если ты колдуешь со строками, то очень похоже, что велосипедишь trie
Давай ты уже сходишь и прочитаешь про обходы дерева?
https://en.wikipedia.org/wiki/Tree_traversal
дурик, я вопрос задал, а на вики тя другой челик отправил
> но адреса каждый раз меняются
ASLR
>Что мне нужно делать, в какую сторону копать?
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\MoveImages
>ASLR
Ой, блядь, там у него обычный динамический мемори-менеджмент, просто он ищет сами данные, а надо искать указатели на них.
не понятно(
> Читать на русском буду. Что лучше навернуть
Учебник английского. Если книгу по Си на русском ты еще найдешь, до всевозможную документацию, которая понадобится тебе, чтобы писать на Си, никто для тебя переводить не будет, а если и будут, то тебя ждут лабораторные занятия пикрилейтед.
В смысле, как сказку на ночь? Тогда надо бы Фленова, но он только про кресты писал. Возьми K&R, Фомина я сейчас поскроллил - там натуральный бред.
Просто хочу с низкоуровневым программированием познакомиться и решил что си идеален для этого.
Ок k&r так k&r. Прост в картинке закрепленного треда в списке рекомендуемой литры в разделе Си только эти две книги и я так и подумал что мало обучающей инфы по Си.
> Почему у меня по несколько раз выводится строка
Ну так ты сам написал: в цикле выводить сообщение и читать символ, пока он вне 'A'..'Z'. Ты вводишь 100\n (\n - это Enter), оно получает эти символы последовательно, ни один не подходит.
> Как пофиксить?
Выводи сообщение один раз до цикла, например.
Или читай строку fgets, а потом уже разбирайся с ней хоть вручную хоть посимвольно, хоть sscanf.
Или ты можешь очистить буфер ввода. Например, существует магия типа scanf("%*[^\n]");, она поглощает весь остаток строки вплоть до, но не включая \n, а уже следующий вызванный scanf("%c") сожрет, если есть, сначала все пробельные символы, включая \n, а потом уже получит первый встретившийся непробельный символ).
Или можешь делать ту же самую очистку буфера после неверного ввода, но руками: while ((c = getchar()) != EOF && c != '\n');
Спасибо.
Я не понял - а зачем он пишет do? Ведь можно и без него просто написать 2 строки с пинтф и сканф?
Ну do while гарантирует что то что находится в теле цикла выполнится хотя бы один раз...
Если бы там было не do while, а просто while, то при попытке использовать letter в логическом выражении поидее был бы вылет или вообще ничего бы не запустилось, ибо она изначально ничем не инициализирована, тогда надо инициализировать её до цикла, в этом конкретном случае с этим проблем нет, но даже тут это лишнее, если можно сократить через do while, при первом заходе в do while letter гарантированно получает значение и все работает.
Вообще do while редко когда нужен, это да. Но я обычно если какие-то данные введенные с клавиатуры нужно было проверить на корректность, и в случае чего попросить ввести данные заново, использовал его + bool переменную + if, который проверял данные, мне так нравилось, по крайней мере, и никто за это не ругал.
Может хуйню несу, не то чтобы прям силен в С.
мимо студент
Чтобы если ввели не букву, то повторится просьба со вводом заглавной буквы
и наверно, существует ситуация, когда достигается конец файла-стрима, но и происходит ошибка?
странная тогда функция clearerr. почему нельзя что-то одно сбросить тогда? и какой смысл вообще - ну понятно, мало ли.
всегда читал read'ом всё. щас подумал - нафиг я так привязываюсь к позиксу. а сами функции fread/fwrite почему-то считал только файловыми.
Анон, пожалуйста, не гони ссаными тряпками, помоги разобраться. Первый язык, как-никак.
Как начать писать на C в Visual Studio 2017 Community Edition? Скачал, добавил с вкладки "Отдельные компоненты" Clang/C2 (экспериментальный), установил. Открываю новый проект, Clang/C2, динамическая/статическая библиотека, что дальше? Куда [CODE]Hello, World![/CODE] пихать?
> и наверно, существует ситуация, когда достигается конец файла-стрима, но и происходит ошибка?
Нет. У тебя три стула: ты либо не смог ничего прочитать (ошибка), либо ты попал на EOF и прочитал 0 байт (EOF - не ошибка!), либо ты прочитал байт и более. Для отличия первой ситуации от второй придумали feof/ferror. Функций две, потому что ты мог использовать какой-нибудь fscanf, он возвращает количество присваиваний, не позволяя отличить неверный ввод от ошибки или EOF, поэтому, чтобы отличить эти три вещи, приходится действовать методом исключения, проверяя и EOF, и ошибку.
> странная тогда функция clearerr. почему нельзя что-то одно сбросить тогда?
Потому что можно. EOF сбрасывается через fsetpos/fseek. А при наличии ошибки нет смысла сбрасывать EOF и оставлять ошибку.
Стандартная библиотека в Си сломана, не пытайся найти в ней логику.
> добавил с вкладки "Отдельные компоненты" Clang/C2 (экспериментальный), установил
"Desktop development with C++"
> динамическая/статическая библиотека
Нет. Новый проект, Visual C++, Empty project, новый файл C++, в имени файла заменяешь расширение .cpp на .c. В этот файл пихаешь свои хелловорлды. Тулчейн clang можно выбрать в свойствах проекта.
У меня скриншоты валяются где-то. Если не разберешься, вечером вброшу.
Вроде бы работает. Огромнейшее спасибо и сотен нефти тебе.
А что тут критиковать? Типичный смари бля как я умею. Синтаксический сахар который заебешься разбирать.
> pastebin.com/0uNJgsLQ
Критикуем: использование Windows API ничем не оправдано, если использовать сишную CRT, кода будет строк десять, а если взять еще и какой-нибудь TCC, то еще и бинарник по размеру будет меньше твоего, причем безо всяких директив линкеру в коде. Ну и там всякие мелочи вроде ∗dest_ptr = NULL вместо ∗dest_ptr = '\0' выдают ньюфага, отключившего предупреждения у компилятора, с головой. Алсо, если используешь GlobalAlloc, делай это "правильно", с GlobalLock, каждую секунду думая о бессмысленности этой функции родом из 3.1 в современных ОС, а лучше осиль HeapAlloc уже. Но для начала норм.
Хорошая попытка, но нет. gcc выдаёт около 40 килобайт, вижла порядка 15 (без этих директив).
С ними 2560 байт.
гцц тоже линкуется. Попутно таская за собой статическую либу своих костылей. Это именно в сишке.
В случае плюсов туда линкуется (опять же статически) свой рантайм c++, несовместимый с msvcp вообще никак, отчего экзешник пухнет до ужасающих размеров.
Кроме костылей гцц еще срет своими символами и прочими строками, которые даже с -s до конца не стрипаются, в то время как tcc делает маленький няшный бинарник совершенно без говна. Но особого смысла в погоне за бинарниками в 4-8 КБ нет (ну демки, разве что), а в больших программах отличия не настолько значительны. Я посоветовал tcc лишь потому, что анон выше криво, без обработки ошибок писал на Windows API, вероятно, именно в попытке уменьшить размер бинарника.
> а пердолиться с созданием консольного окна в коде желания нет.
А что, так сложно собрать как GUI-приложение и дернуть AllocConsole?
А что тебе не нравится? 54.5999? Ну так флоаты же. Или то, что распидорасило порядо строк? А попробуй fflush(stdout) сделать перед выходом?
>А что тебе не нравится? 54.5999? Ну так флоаты же
Было бы странно, если бы я за полгода коддинга не знал, как флоаты хранятся в памяти
>Или то, что распидорасило порядо строк?
This
>А попробуй fflush(stdout) сделать перед выходом?
Только не stdout, а stdin. Не помогло. Да и разве не видно, что это не тот случай, когда \n остается в буфере ввода с предыдущего сканф? Тут какая-то иная хуйня - видно же, что переменная инициализируется правильно (как ввел пользователь), да и все последующие принтфы все корректно выводят. Но почему-то Program ended with exit code: 0 появляется сразу после ввода переменной (хотя отображается в аутпуте вообще раньше, чем 54.6). Да и так, думаю, очевидно, что это сообщение должно быть в самом конце аутпута, когда main завершил работу.
Еще баг(проблема): если сделать прогу типа
int a;
scanf("%d", &a);
printf("%d", a);
то при запуске (кнопка Run) аутпут окно вообще не появляется, хотя программа is Running и, очевидно, ждет ввода.
Похоже на какой-то баг/фичу Xcode, но в гугле ничего похожего не нашел. Может, я просто что-то упускаю/не включил какую-то опцию?
>>84094
Сам нашел ответ на свой вопрос. Хотя, как сказать. Нашел тред на форуме эпл, где у ОПа и комментаторов такая же проблема. Оказывается, это баг 10-й версии xcode (сообщение о завершении программы появляется посреди вывода). Фиксится сменой размера шрифта окна вывода. Но это такой себе фикс, ибо шрифт нужно менять вручную при каждом экзекуте - сам он его не сейвит. Собственно, вот тред, можете почитать, кому интересно https://discussions.apple.com/thread/8543709
Пиздец, у меня горит жопа с этого ебучего мак ос и ебучего баганного проприетарного эпловского софта, но зато своё!
Аноны, которые пишут на маке, предложите достойную альтернативу, пожалуйста. Visual Studio под Wine, например, нормально запустится?
>Пиздец, у меня горит жопа с этого ебучего мак ос и ебучего баганного проприетарного эпловского софта
Ну так собери себе нормальную пеку а не макоговно
С или С++?
Почему двачеры так радикально решают проблемы? Все же xcode - единственная возможность писать приложения для айос, эпл вотч, эпл тв.
При чем тут эти яп?
Юзай visual studio code и будет тебе счастье. Там и дебаггер есть.
>Почему двачеры так радикально решают проблемы?
Смотри, ты жрешь говно, сам это понимаешь, когда я тебе говорю прекратить жрать говно, ты говоришь мол зачем так радикально. Я делаю вывод: тебе нравится жрать говно. Ну окей, ебись с икскодом, а лучше компиль из под терминала.
> Только не stdout, а stdin
Не stdin, а stdout!
> то при запуске (кнопка Run) аутпут окно вообще не появляется
Что опять же намекает на то, что stdout почему-то не флашится (он line-buffered, а \n у тебя нет, поэтому строка остается в буфере FILE). В любом случае, это баг реализации.
Следующий scanf отлично пожрет все пробельные символы, в том числе и \n, а на отображение в консоли этот \n не влияет, потому что к тому времени, как scanf начал что-либо матчить, stdin уже прочитал к себе в буфер строку целиком, включая \n.
Ну так ты пробовал так или нет?
С хуя ли инструкция goto настолько презираема в Си?
У тебя блять в распоряжении есть огроменный елдак, которым ты можешь болтать во все стороны и способен отъебать кого угодно, но ты сука намеренно прячешь его в штаны и как ебучий куколд юзаешь покупной самотык. Че это блять за хуета?
Давай тоньше. У тебя получится.
>Че это блять за хуета?
Goto это охуенная тема, просто смузипидоры начили его лепить везде где не нужно и зашкварили саму идею
Ассемблеры гораздо проще любого более высокоуровневого языка. Си сам по себе несложный, но в нем есть множество тонкостей типа сахарка не совсем к месту и прочего undefined behavior, которые нужно знать и понимать. Зато, в отличие от ассемблеров, простые вещи не занимают два экрана кода.
>>84974
> С хуя ли инструкция goto настолько презираема в Си?
А ты меньше говностатей читай. goto CLEANUP и goto EXIT_LOOP - нормальные, часто используемые вещи. Остальное можно выразить с помощью других конструкций, и это будет более читаемо.
Двощую.
Я просто хочу понять во что проще вкатится, в с или в с с плюсиками.
Ибо про плючихи дохуя комиксов как выучить плючики за джве недели, а про с такого нету. Думаю что он проще и пытаюсь узнать так ли это.
> Ибо про плючихи дохуя комиксов как выучить плючики за джве недели
Лол. На самом деле Си за год и кресты (после Си) за три.
Почему так происходит? Что почитать по данной проблеме? Как ее избегать? Не всегда же можно округлить до целого.
Спасибо!
На пикрелах видно, справа, где дебаггинг, видно что i равняется тому-то тому-то, как я и описал
>Что почитать по данной проблеме?
Это не проблема, это операции с плавающей зяпятой, про низх и читай
> Что почитать по данной проблеме?
Уже рекламировал тут: https://randomascii.wordpress.com/category/floating-point/
> Не всегда же можно округлить до целого.
Можно округлять до нужного количества знаков после запятой после окончания вычислений.
Ну а что он не так сказал? Да, связано. Да, числа с плавающей точкой - тоже суммы степеней двойки. Только в отличие от целых чисел, не только положительных, но и отрицательных. Если дробь нельзя представить суммой степеней двойки, выбирается ближайшая, которую представить можно.
Бог Питона снизошел до челяди
Ебошу В Анаконде (numpy+ scipy). Хуярю в интерпретаторе double значения. Хоть в матрицах, хоть где еще. Никогда не жаловался
> Никогда не жаловался
a = pow(2.0, 53)
if a == a + 1: print('Шел бы ты отсюда, скриптоблядь!')
блять весь компьютер это мешанина из нулей и единиц
если не в двоичном формате то блять в чем? в виде псионической энергии?
> блять весь компьютер это мешанина из нулей и единиц
Ты теперь достаточно большой, чтобы узнать страшную правду о том, откуда берутся дети. Не весь. https://en.wikipedia.org/wiki/Three-state_logic
> если не в двоичном формате то блять в чем?
Есть овердохуя способов хранить дроби. Да, они все рано или поздно сводятся к битам. Но спецэффекты у этих способов разные.
>Не весь
>кидает ссыль на голимые буферы с 3мя состояниями, которые рассматривают на 2м курсе технической шараги
Ахуеть блять. Еще приведи мне в пример std_logic из VHDL. Информация хранится и передается в виде нулей и единиц, даже если разобьем сигнал на много логических уровней, компьютер все равно будет оперировать 0 и 1. Никаким Z и Х-состояниям там места нет
> передается в виде нулей и единиц,
Верно, поэтому современная информатика это ебаный каменный век
Ты не прав, есть разработкиещё советские, где есть реально три состояния на уровне железа именно.
АНАЛОГОВНЕТ в треде
33 остаток 1.
Дурачек, ты же поставил брейкпоинт, он останавливает программу до того как выполнен код в строчке, АЛЛО! Поставь его на следующую строчку и ты сильно удивишься. Либо если я не прав, то скрин в студию, я себе лицо обоссу без пруфов в таком случае, но не может быть такого, что в СИ внезапно для всех сломано умножение, блять, сам подумай.
То что у тебя с права, это просто фактическое значение в переменной на момент до выполнения кода в строке.
Алсо, никто не запрещает, но я бы на твоём месте не писал "i = i 100", а "i=100".
С клавиатуры вводятся два числа (n<=255). Если оба числа чётные, то выводится их сумма, если хотя бы одно число нечётное, то выводится 0. Запрещается использовать условный оператор.
Как это реализовать без if?
Оператор case, не? Проверяй остаток от деления
Чето пришло в голову:
int mul1 = 1 - a % 2;
int mul2 = 1 - b % 2;
printf("%d", (a + b) mul1 mul2);
--------------------
// 3 + 4
// mul1 = 0
// mul2 = 1
// prints 0
// 3 + 3
// mul1 = 0
// mul2 = 0
// prints 0
// 4 + 4
// mul1 = 1
// mul2 = 1
// prints 8
сука, куда оно звездочки девает, там короче умножить на mul1 умножить на mul2
Неплохо, но смотри, что делают дети в Украине в твоём возрасте.
printf("%d", (a+b)умножить(1xor a%2)(1xor b%2))
@
сидишь неделями, думаешь над простой обработкой строк.
Ну, вроде как ничто так хорошо не поможет понять массивы, как работа со строками. Можно же как-то так вообще сделать вроде
typedef string *char;
И особо не маяться. Только я не понимать, что эта строка делает.
Числа целые? Если да, то в двоичном представлении у чётных младший бит = 0, у нечётных младший бит = 1.
Дальше сам думай
А если у меня статическое количество элементов? А?
Ты предлагаешь вытаскивать младший бит за каким-то хуем, когда можно сделать в одну составную инструкцию используя лишь '%' и лог операторы?
>printf("%d", (a+b)умножить(1xor a%2)(1xor b%2))
Если заменить на :
printf("%d", (a+b)умножить(1 ^ (a & 1))(1 ^ (b &1))),
может быть быстрее.
Ну, это уже вообще прям уровень godlike казахов, которые вместо кофе потягивают кумыс.
Ну бле берешь находишь /0, берешь цикл до середины и свапишь первые элементы с последними, хулит там реверсить?
void reverse(char line[], int length)
{
//printf("%s", line);
int j=0, max=0;
char i;
for(max; line[max]!='\0'; max++);
for(j; j<=(max/2); j++)
{
i=line[j];
line[j]=line[max-j];
line[max-j]=i;
}
}
Вот со свопом тут дрисня немного. В итоге у меня всё исчезает из line.
питонопараша в другой стороне
https://ideone.com/tFr59S
Что делает код: берет все подряд параметры из терминала, и внутри каждого параметра сортирует символы по asc2 таблице.
например ./progname cba 231
Lолжен выдать: abc 123
Я предлагаю тебе использовать побитовые операции, вместо арифметики. И не вытаскивать младший бит, а фигачить xor с маской.
Такой говнокод используют по всяких там SIMD, чтобы избежать дорогих бранчей.
Бамп вопросу
Ну, вывод я у тебя переписал вот так. А то геморойно же по букве выводить.
while(j<argc)
{
printf("%s\n", argv[j]);
j++;
}
прокомментировав сортировку этот код отработал как надо. Значит трабла в сортиров_очке.
>прокомментировав сортировку этот код отработал как надо. Значит трабла в сортиров_очке.
Ну я не вижу где там косяк(
https://ru.wikipedia.org/wiki/Машинное_слово
скорее всего у тебя анон 64х архитектура, так что слово будет восьмибайтное. Хотя я помню из реестра виндоуз там словом обозначается два байта.
Хохол, плес. Выкатил тебе белый человек сразу на блюдечке кошерное решение. Своими мозгами научись думать. А то начитается как там в SIMD кто-то наговнокодил, а ты и рад в массы вытащить и выдать за оптимизированный код, а потом ну покажи как у тебя ну покажи, ну че ты, ну иди нахуй тогда. Тьфу на тебя попрашайка.
>найс маняоправдания во время обтекания
Проиграл с клоуна, который думает, что тут 1,5 анона сидят.
Ну, как бы по хорошему кодстайлу да не стоит менять формальные аргументы. Единственное что из иснтитута запомнил. Но я сейчас его запустил и нулевой аргумент у меня отсортировался. И точку вытолкнул в начало. Всё как положено. Второй аргумент просто написал и зациклился на третьем.
А через что ты прогоняешь, что бы видеть на какой ступеньке прога падает?
А все, понял
Да прям в терминале. Ещё printf() почаще вставляю, чтобы отслеживать состояния буфферов. Так например:
fprintf(stderr, "%d:%s", __LINE__, argv[1]); ну, и комментирую в коде, чтобы не удалять на всякий пожарный случай.
> >найс маняоправдания во время обтекания
> Проиграл с клоуна, который думает, что тут 1,5 анона сидят.
Какой SIMD, что ты несёшь.
Что тут, по-твоему, можно векторизовать? Задачка на уровне парочки побитовых инструкций и системного вызова для вывода, а ты тут пальцы гнёшь и изображаешь из себя не пойми что. Типичный малолетний дебил.
% это те же битовые операции, умник.
Только после того, как & отработает нужно отрицание.
По условию, если оба числа четные, то сумма, а у тебя получится 0, если оба четные.
А так хорошее решение, простое и понятное.
мимо-крокодил
Тернарный оператор, например.
Анон. Я тебе тут попрограммировать принёс. Всё программируют и ты попрограммируй. Ох и поломал я мозги. Добавил сортировку пузырьком. Только надо было назвать не args parsing а arg_values sorting. А теперь со спокойной душой можно и на боковую.
ну тоесть есть паттерн { f,f,f} и есть паттерн { [f;f],[f;f],[f;f] } , где f - float - как сделать чтоб первое вызывало функцию 1, а второе функцию 2 при этом любые другие паттерны вызывали ошибку( по типу {f,f} или { { [f;f],[f;f],[f;f] } или {char,f,f}. )
Напиши свой парсер на основе strtod или возьми prce какую-нибудь. scanf - глючное говно, которое нужно, чтобы по-быстрому прочитать числа и буковы из файла.
в задании настоятельно рекомендуют использовать scanf, так что простое решение должно быть. Окей, облегчу вопрос: как используя один scanf считать 1 или 2 переменных - подаю одну переменную - записывает её в А подаю две - запичвает их в B и C
> в задании настоятельно рекомендуют использовать scanf
Скажи им, что они пидарасы. Но ты можешь:
fgets(); if (sscanf(шаблон1)) { ... } else if (sscanf(шаблон2)) { ... } else { ошибка }
> как используя один scanf считать 1 или 2 переменных
Главный вопрос тут: откуда считать? Оно даже о понятии строки не знает. Ты можешь scanf("%f %f") и проверить, вернуло ли 2, или после первого присваивания сломало зубы о какой-то не-float и вернуло 1. Или не смогло распарсить вообще ничего и вернуло 0. Но более сложные (особенно вложенные как у тебя) паттерны этим не распарсишь.
>fgets
угу, в случае если данные, удовлетворяющие условию паттерна лежат каждый в новой строке
если же встроены в текст, то нужно чутка по другому сделать
>Но более сложные (особенно вложенные как у тебя) паттерны этим не распарсишь
ты шутишь? это на изичах делается через scanf семейство функций
Несколькими вызовами sscanf - да. Одним вызовом scanf - нет.
Драсьте, объясните пару вещей, код пижжен с другого сайта. Почему размер константы для буфера (SIZE 100) меньше unsigned char buf[SIZE] буферного массива символов?
Что такое sizeof(buf[0]) -- размер первого элемента? Не понимаю что за размерность у while (..)
#define SIZE 100
int main()
{
FILE in1 = fopen("cz.exe", "rb");
FILE out1 = fopen("cz.txt", "wb");
unsigned char buf[SIZE];
size_t count;
while (count = fread(buf, sizeof(buf[0]), SIZE, in1)) {
int i;
for (i = 0; i < count; ++i) {
printf(" %02X", buf);
fprintf(out1, " %02X", buf);
}
}
fclose(in1);
fclose(out1);
system("pause");
return 0;
}
>размерность у while (..)
а такая размерность, что while(!EOF);
пока fread работает по байту, а конкретнее по sizeof(buf[0]) и не получит конец файла, то будет продолжать работу. Хотя я не знаю что fread возвращает в конце, когда заканчивает работу. Но, видимо, нуль, или -1 для EOF.
sizeof(buf[0]) - размер не содержашийся в первом элементе, а вообще размер самого элемента массива, собственно можно написать в этом случае любой номер элемента, но размер у него в любом случае будет unsigned char1. Это делается для портируемости, а то вдруг кто-то в конпеляторе выделили несколько байт для char, хотя это что-то на уровне хтонического пиздеца.
А вот почему константный SIZE меньше массива буффера - я хз. Попробую предположить, что в винде выделяется в массивах char на символ больше, для знака перевода строки \r\n. Но скорей всего это неверное преположение. Вот моё объяснение. Но олды сишные меня могут засмеять, так что не сильно прислушивайся к моему посту.
> Почему размер константы для буфера (SIZE 100) меньше unsigned char buf[SIZE] буферного массива символов?
Вот это стоит перефразировать. Размер константы sizeof(100) 4 байта, потому что, если не указано иное (100ULL, например), то оно целочисленная константа считается signed int-ом (если влезает). Каким местом это относится к размеру, непонятно. Если ты почему-то решил, что у тебя sizeof(buf) != SIZE, то ты мерял как-то неправильно, потому что размер массива sizeof(buf) по определению равен sizeof(buf[0]) ∗ SIZE (т.е., размер одного элемента умноженный на их количество, т.е., в случае unsigned char, 1 ∗ SIZE, т.е., SIZE).
>>86425
> пока fread работает по байту
Не совсем. Он читает разом максимум SIZE элементов по sizeof(buf[0]) и возвращает количество прочитанных в штуках размером sizeof(buf[0]).
> Это делается для портируемости
Вот только упс, sizeof выдает размеры в символах, т.е., sizeof(char), даже если это 32-битный char, будет всегда равно 1. А делается это для единообразия, потому что если читать массив интов, это будет иметь смысл, так что лучше делать везде одинаково.
> что в винде выделяется в массивах char на символ больше
Конечно же нет. Все отличия винды заканчиваются на уровне стандартной библиотеки, а на сам язык это не влияет.
Языка мало. Например, я бы хотел увидеть знание посиха или винапи (на уровне "осилил apue/рихтера"), хотя бы что-нибудь про сети, хоть какой-нибудь опыт использования zlib/libjpeg/libusb/sdl/чегоугодно, просто чтобы чтение документации не было проблемой, а "уменянилинкуется" не вызывало панику. На джуна проще всего немного пороллить пикрилейтед в свой гитхаб. Но вообще, с наличием работы на сишке все очень непросто.
Почему некоторые пишут : charstr;
А некоторые char str;
разве 1 способ нельзя спутать с разименовыванием?
Ведь если есть указатель и мы потом пишем о нем так str = 5;
Мы меняем значением той переменной, на которую указывает str (хроня адрес)
Так вот пример:
charstr;
len = 0;
while (src[len])
len++;
str = (char)malloc(sizeof(str) (len + 1));
Вот тут я могу в 1 строчке написать char str; ?я правильно понял?
Спасибо, годнота, схоронил. А с эмбеддедом ты не сталкивался? Есть какие-то похожие советы ньюфагам на эту тему?
Дурацкая просто ситуация - меня взяли в связанную с автомобилями контору, при этом не кодером, но с условием разобраться с сишечкой и немножко кодить в свободное от основных обязанностей время. Вот я и в растерянности немного от того, куда дальше долбиться после основного синтаксиса и стандартной библиотеки.
мимо другой анон
>Например, я бы хотел увидеть знание посиха или винапи (на уровне "осилил apue/рихтера")
А, собственно, что предпочтительнее? Знание POSIX API или WinAPI?
>хотя бы что-нибудь про сети
Можно поточнее? В этом я вообще профан
>с наличием работы на сишке все очень непросто
Т.е. лучше перекатываться в плюсы? Или имелось в виду, что порог вхождения на работу, где пишут на Си-подобных языках высок?
>На джуна проще всего немного пороллить пикрилейтед в свой гитхаб
А какое количество проектов нужно иметь в своем портфолио с пикрила? Штук 10 было бы достаточно, да?
Платина. Да, разницы, с которой стороны ставить пробел, нет. Некоторые с обеих ставят. Более корректно ставить с правой, чтобы не напороться на char∗ foo, bar. Вторая причина - в Си объявление отражает использование, и если ты обращаешься к указателям так пробел после звездочки: ∗ foo = 1, смело пиши звездочку слева. Алсо, каст значения, которое вернул malloc() - признак крестобляди, в Си указатель на void стоит кастить только тогда, когда добавляешь/убираешь квалификаторы (volatile/restrict/const).
> разве 1 способ нельзя спутать с разименовыванием?
Разве int array[10] нельзя спутать с обращением по индексу 10?
>>86712
> с эмбеддедом
Покупаешь макетку и отладку на STMF1 или лучше сразу на STMF4 (чуть дороже) - это самые попсовые, удобные и дешевые варианты с кучей периферии, пишешь в гугле "проекты на STMxx", выбираешь вкусный, разбираешь. Будет сложно особенно сложно заставить себя продолжить разбираться, уже помигав светодиодом. Ну и Mastering STM можно почитать. Ардуины и прочие сорта AVR категорически не рекомендую, но сейчас кто-нибудь обязательно набежит и пояснит, что я ошибаюсь.
>>86739
> что предпочтительнее? Знание POSIX API или WinAPI?
Оба, но POSIX нужен сильно чаще.
> Можно поточнее?
Того же стивенса полистай. И я уже не помню, есть ли про сокеты в APUE, но по идее должно быть.
> А какое количество проектов нужно иметь в своем портфолио с пикрила?
С этим в перезвоним-тред.
> Или имелось в виду, что порог вхождения на работу
Именно.
> Более корректно ставить с правой
ставить пробел справа от типа, т.е., прилеплять звездочку к имени переменной без пробела.
Если он создает char массив 10 мегабайт, то как он потом заполняет его полностью цифрами?
Ведь в какой-то момент итерации i будет равна :10 000 к примеру, а char может уместить от 255 только же
>Более корректно ставить с правой, чтобы не напороться на char∗ foo, bar
В данном случае ведь не будет разницы, ставить звездочку у char или у переменной foo, т.к. эффект будет одинаковый - указателем на char будет только переменная foo. Так что не понял, о какой корректности идет речь
Дп
> char может уместить от 255 только же
-128..127, там signed. В компьютерах нет настоящей арифметики, используется арифметика с переполнением. Если что-то куда-то не влезает, просто берется остаток от деления на 2n. Не влезает 10485759 в char? Ок, 10485759 % 2 = 10485759 % 256 = 255 (на самом деле всего лишь 10485759 & 255, да и то неявно - фактически просто не учитываются все байты значения, кроме младшего), преобразуем в signed char, получаем -1, остальное обрезалось.
>>86762
> указателем на char будет только переменная foo
Именно поэтому справа и ставят: char ∗foo, bar; наглядно демонстрирует, что только одна переменная будет указателем, а char∗ foo, bar; гораздо проще случайно прочитать как "указатели foo и bar".
Чувак, ты охуенен. Все твои ответы однозначны, понятны и не оставляют вопросов. Если не секрет, сколько тебе лет? Сколько уже знаком с C?
То есть имеешь ввиду , что в тот момент когда i будет равна например 10 000, то она просто будет разделена на кусочки состящих по 255 ?
Или ты имеешь ввиду, что массив не имеет по сути типа, туда пихают любые значения под любые типы, лишь бы хватило памяти?
Возьму на себя ответственность ответить за того анона.
Допустим, нам надо поместить число 261 в unsigned char. 261 в двоичном виде представляется как 0000 0001 | 0000 0101. Т.е, чтобы записать 261 в двоичном представлении, нам, как минимум, нужно 2 байта памяти (16 бит). Для типа unsigned char выделяется 1 байт памяти, следовательно, максимум, что мы можем в него поместить - это число 255, т.к. 255 в двоичном виде = 1111 1111. Тогда, если написать unsigned char a = 261, происходит то, что описал анон выше, а именно: т.к. возникает переполнение, то в данном случае младший БАЙТ числа 261, а это 0101, побитово умножается на 255, т.е. на 1111 1111.
0000 0101&1111 1111= 0000 0101. Значит, переменная a инициализируется числом 5.
Если не понятно, почему в примере анона получилось -1, то почитай про дополнительный код (представление отрицательных чисел в двоичном виде).
В наше время получить ответ на интересующий вопрос, без иронии - дорогого стоит.
Ну может он и хотел мусор. Там будет 0, 1, 2, ... 254, 255, 0, 1, 2, ... 254, 255, 0... Например, давай просто будем считать, что он там картинку с градиентом генерит?
Нифига вы кодеры хитрые ребята. Даже такие аппаратные ограничения используете в свою выгоду
Записал не мусор, а вполне обычные числа. Только диапазон всех чисел, которые хранятся в массиве ограничен 0..255. Т.е., после 255 итерации, когда A[255] = 255, будет A[256] = 0, A[257] = 1, A[258] = 2 и т.д.
>Ну то есть там уже после 255-ой итерации все цифры искажатся?
Можно и так сказать. Хотя правильнее будет сказать, что массив инициализируется числами i%256 - остатком от деления на 256
Правда, в данном случае, у него массив не unsigned char, а char (signed char). Поэтому массив будет инициализирован числами из диапазона -128..127
Очевидно, имелся в виду остаток от деления. Не надо грубить. Все-таки 5 утра, могу и хуйню сказать
>>86794
Да я пошутил просто. Если у нас картинка в оттенках серого (8 бит на пиксел) шириной 256 пикселов, то цвет (яркость) очередного пиксела будет index % 256: самый темный 0 % 256 = 0 в начале строки, самый яркий 255 % 256 = 255 в конце строки, и следующий будет снова темным 256 % 256 = 0 в начале следующей строки и так далее. Если ширина картинки не 256, то переход к 0 случится не на правом краю, и картинку распидорасит. Естественно, никто так градиенты не рисует.
char a[10] = "Hello";
Почему это вообще работает?
Было бы логичнее и правильнее писать:
char a[10] = { 'H', 'e', 'l', 'l', 'o', '\0' };
Тут все понятно - указатель разыменовывается, нулевой элемент инициализируется 'h', указатель++, первый элемент инициализируется 'e', указатель++, 2-й элемент - 'l'... указатель = указатель на нулевой элемент. Как-то так ведь это работает "внутри"?
Однако, как я уже сказал, строка char a[10] = "Hello" вызывает у меня вопросы. Вообще, как я считаю, здесь нулевому элементу должен присваиваться адрес временного указателя на массив "Hello". Конечно, выходит нехорошая штука, что char = char *. Но я лишь пытаюсь следовать логике ЯП.
А еще, если сделать так:
char a[10];
a = "Hello";
И в этом случае я хочу не инициализировать массив a словом Hello, а присвоить указателю a на массив char'ов адрес временного указателя, который указывает на массив Hello.
Но тогда компиль ругается. По-моему, пишет что-то про то, что слева ожидался lvalue. А у меня что, не lvalue что ли? Я же объявлял массив как char a[10], а не const char a[10]. К сожалению, точной ошибки не помню, но вроде было именно про то, что ожидался lvalue слева от оператора присваивания. Сейчас чекнуть возможности нет, извините.
По поводу первого случая (char a[10] = "Hello") - может это специальное исключение?
Капец интеллектуально. Закодить-то несложно, но сама концепция сделать именно так - круто. Хочу тоже научиться такие прикольные и практические решения находить
Если не совсем понятно, о чем я вообще говорю, могу попытаться перефразировать и переформулировать. А сейчас пойду спать. Всем спокойной ночи
Что тебя смущает? Это такая же инициализация массива, просто строковым литералом. Синтаксический сахар.
>Вообще, как я считаю, здесь нулевому элементу должен присваиваться адрес временного указателя на массив "Hello". Конечно, выходит нехорошая штука, что char = char .
Это очевидно чушь. Подумай потом еще раз.
>char a[10];
>a = "Hello";
А это уже не инициализация, а присваивание, так нельзя.
> я хочу не инициализировать массив a словом Hello, а присвоить указателю a на массив char'ов
char a = ""
В этом случае строка будет храниться где-то в другом месте, а у тебя будет адрес.
>А у меня что, не lvalue что ли?
Нет, не lvalue. Массив. Это особый случай, для массивов свои правила.
двач зохавал звездочки, но должно быть и так понятно.
Если хочешь понять, как это работает внутри, читай, что генерирует компилятор (без оптимизаций):
https://gcc.godbolt.org/z/sfAyZ5
char a[] и char* a - очень разные вещи, хоть и массив неявно приводится к указателю. Массивы имеют свои специальные правила.
char a[10] = "Hello" честно конструирует строку-массив символов на стеке, никаких присваиваний указателей не происходит.
char a[10] = {'H', ..., '\0'} делает ровно то же самое, но побайтово.
>char a[10]
>a = "Hello"
>И в этом случае я хочу не инициализировать массив a словом Hello, а присвоить указателю a на массив char'ов адрес временного указателя, который указывает на массив Hello.
a - это не указатель на массив, а массив. Присваивание массивов друг другу не разрешено.
> нахуя это сделали?
Так получилось, что в этом языке все, что может влезть в int, стремится им стать. Если не нравится, касти к (signed char) явно, но это будет иметь значение только для sizeof. В любом арифметическом выражении оно превратится обратно как минимум в int. Алсо, 'FADE' - это расширение, которое может не поддерживаться (например, gcc 4 на винде точно не умел).
Да, только там не fade а fate, и видимо это просто для примера сделано
>255 ,преобразуем в signed char, получаем -1, остальное обрезалось.
Как этоп реоброзщоывывается? Есть формула?
>то в данном случае младший БАЙТ числа 261, а это 0101
А как узнать какой из двух байтов младший, а который старший?
Спасибо
Ты не всегда ищи логику в синтаксисе,
она иногда просто для удобства. Для твоих глаз.
За твоими глазмами, в компиляции и одно и второе представление массива будет создаваться в одинаковым способом. Это просто ты общаешься с компилятором, дня него
char a[10] = "Hello";
и это
char a[10] = { 'H', 'e', 'l', 'l', 'o', '\0' };
Одно и тоже
Никак, ничего не меняется на самом деле. Память не знает, что хранит: 255 = 11111111bin, хранятся биты. Процессор по большей части не знает, что обрабатывает (инструкции пересылки данных, сложение/вычитание, всякие побитовые операции не отличают signed/unsigned). В тех случаях, когда различие важно, компилятор генерирует соответствующие инструкции (например, div vs. idiv для unsigned/signed деления, которые по-разному интерпретируют биты). Интерпретировать unsigned как signed можно так: если старший бит (седьмой для char, пятнадцатый для short, тридцать первый для int и т. д.) не установлен, то это положительно значение, и оно равно тому же для unsigne. Например, (signed) 01111111 = +127. Если старший бит стоит, значение отрицательное и равно -(~n + 1). Например, (signed) 11111111 = -(~11111111 + 1) = -(00000000 + 1) = -1.
Вообще, есть книга Петцольда "Код. Тайный язык информатики", там все более чем подробно, и перевод есть. Почитай хотя бы главы про представление чисел в компьютерах.
>>87247
Точно так же как в десятичной системе счисления есть младшие и старшие разряды, младший байт содержит менее значимые биты (меньше влияет на значение). В 0x1234 младший байт 0x34.
биты имеют* поц с\с
Это значит пиши ((signed char) 'x'). Вот та хуйня в скобках слева от символа - оператор преобразования типа, тип выражения (во внешних скобках) становится signed char.
Нет. Типы должны быть совместимы. Например, ты не можешь скастить инт к структуре.
Это копия, сохраненная 5 декабря 2018 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.