24 декабря Архивач восстановлен после серьёзной аварии. К сожалению, значительная часть сохранённых изображений и видео была потеряна. Подробности случившегося. Мы призываем всех неравнодушных помочь нам с восстановлением утраченного контента!
Тред, посвященный прародителю всех С-подобных языков и по совместительству единственному идеальному и всесторонне годному средству программирования как на системном, так и на прикладном уровне.
- Очевидный GCC. - clang: оче годно, батя рекомендует. - Intel C++ Compiler: оптимизации, тысячи их. - Visual Studio 2015 Community Edition: внезапно этим стало можно пользоваться, особенно с тулсетом clang/C2. Поддержка C11 на уровне "есть все, что тебе понадобится в реальном проекте плюс кривая библиотека". Анализатор кода в комплекте. - Pelles C (шиндоуз онли): поучиться, вкатиться в C11 (стандарт полностью реализован, имеются в том числе threads.h и прочие stdatomic.h), но количество багов в оптимизаторе и редкие апдейты напрочь отбивают желание собирать этим что-то сколько-нибудь серьезное. - TCC: очень маленький компилятор с багами и неполной поддержкой C99. С ключом -run умеет компилировать код в память и запускать его, что позволяет писать скрипты прямо на сишечке.
Stephen Prata "C Primer Plus, 6th Edition" (2014) Свежая знает про C89, C99, C11, описывает различия, объемная около тысячи страниц, годная хотя есть некоторые шероховатости, с вопросами, упражнениями и ответами. Читать после K&R или до.
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? у нас в сишечке их гораздо больше, просто они лучше спрятаны, немного байтоебли и непонятно откуда взявшаяся глава про старинные плюсы. Читать в качестве сказки на ночь (на пару вечеров хватит).
Ben Klemens "21st Century C: C Tips from the New School" (2012)
Stephen G. Kochan "Programming in C (3rd Edition или 4th Edition, если найдется)" (2014)
>>780665 Для понимания того откуда есть пошла Сишечка. Без этого понимания в их картине мира будет неверное представление об уместности применения этого, с позволения сказать, языка для решения тех или иных задач в тех или иных условиях.
>>780743 Читал, там же полный пиздеж, и вообще вроде этот текст первоапрельская шутка. Например, в большинстве реализаций Паскаля были модули. И что мешало создать свою реализацию со всем необходимым вроде адресной арифметики и областям видимости? Вот Хейлсберг например создал Turbo Pascal с ООП и низкоуровневыми средствами. Не вижу ни одной причины, чем Паскаль не подходил для UNIX.
>>780746 >Читал, там же полный пиздеж, и вообще вроде этот текст первоапрельская шутка. Ты, наверное, путаешь с этим http://www.stokely.com/lighter.side/unix.prank.html >Не вижу ни одной причины, чем Паскаль не подходил для UNIX. Мне было бы достаточно только этого >C and Ratfor programmers find 'begin' and 'end' bulky compared to { and }.
>>780754 Я осознаю, что существуют безмозглые пидоры, у которых в список значимых критериев может входить, к примеру, синтаксис языка. Hу так накласть мне на них. Меня интересуют объективные критерии, а не цацки всякие.
>>780797 Там целая статья объективных критериев. Распиши конкретно, что из него не является правдой и почему. >>780746 >Например, в большинстве реализаций Паскаля были модули. При чём здесь моудли. В статье ни слова про модули.
>>780941 > При чём здесь моудли. В статье ни слова про модули.
Жопой читал, хуесос?
> 2.4. There is no separate compilation > The ``official'' Pascal language does not provide separate compilation, and so each implementation decides on its own what to do. Some (the Berkeley interpreter, for instance) disallow it entirely; this is closest to the spirit of the language and matches the letter exactly. Many others provide a declaration that specifies that the body of a function is externally defined. In any case, all such mechanisms are non-standard, and thus done differently by different systems.
>>781218 А, ты про раздельную компиляцию. Ну так, ты сам же цитируешь >The ``official'' Pascal language does not provide separate compilation, and so each implementation decides on its own what to do. >In any case, all such mechanisms are non-standard, and thus done differently by different systems. Тут нет пиздежа. Они признают, что есть реализации с поддержкой раздельной компиляции, но это никак не стандартизировано, и в этом проблема.
Пытался читать статью, попутно выполняя все описанные па. Негодяйский радаре отказался работать , точнее не работала команда ds. Ошибка чтения регистра. Не сталкивался никто с такой залупкой?
>>781873 >void DISP_configure(const DISP_config_t *config) DISP_config_t у тебя - тип переменной, а config её имя. Создаешь переменную типа DISP_config_t, заполняешь все поля, потом передаешь эту структуру в DISP_configure. Все, дисплей сконфигурирован.
>>781914 Это stm8, на него нет миллиарда либ, а в этой хорошо расписаны все дисплейные функции, пример от ST просто вырвиглазный пиздец по сравнению с этой. Да и неспортивно просто либу сменить. У ее написателя все работало. Правда на письма нихрена не хочет отвечать.
>>781918 Берешь любую либу для атмеги и переделываешь HAL. Если это hd44780, то только вызовы gpio меняешь, если i2c, то его вызовы меняешь. Сам для таких случаев использую либы как скелет, чтобы всю структуру не делать.
>>781925 С его инитом ничего не соберется. Компилер правильно ругается на малоаргументов. Pastebin.com/eybrb4jd Так у тебя заининтится на две строки с 16 символами, без ебучего мигающего курсора.
>>782104 В рот ебал космик с таким описанием ошибок. Поставил бы иар, чтобы мозг себе не иметь. хотя кому я советую, ты вывод ошибок на двощ выкладываешь, вместо того, чтобы самому разобраться
>>782431 Да я чот ёбся с кряками этого иара еще для стм32, нихуя он ровно не встал, так я на него и забил. > вывод ошибок на двощ выкладываешь Разбирался уже неделю, потом решил спросить. Ладно, не буду больш раз тебя это так нервирует.
Так, ананасы, прошу помощи с билдом. Короче, есть regex с унипсов, заточенный, по всей видимости под минговно. Собираю под шиндус. В общем, написал маленький смаке-файл http://pastebin.com/r3s1Au15 И собрал, установив заранее CMAKE_BUILD_TYPE равный Release. Потом, как положено, либу закинул в lib, а хедер в include миниговен, естественно. Но вот проблема, когда собираю тестовый сорец через гуся: http://pastebin.com/MaEd6nzw gcc -lregex -I... -o temp.o temp.c (к примеру) этот гад высирает мне, что такая-то функция (regcomp) не найдена. Как решать, посоны, видать с линковкой что-то накосячил, но понять не могу.
>>782478 > (.text+0x1e): undefined reference to `regcomp' > collect2.exe: error: ld returned 1 exit status
Линкор что-то выдает. Даже вручную заморочился собрал все: > gcc -I... -I. -mwindows -O2 -o regex_internal.o -c regex_internal.c (так для еще 3 раза для regex.c, regex_internal.c, regcomp.c) потом арой прошелся: > ar rs libregex.a *.o Значит, собрал он все это дело в кучу, но опять выдает то же дерьмо. Я даже высыпал все определения из этой либы: nm -C libregex.a и он-таки выдал мне, что все-же определен regcomp: > 0000000000003e30 T regcomp Но не видит, падла такая он этого определения
>>780630 (OP) Как сделать дамп памяти процесса через C? Допустим заинжектил кастомную либу в бинарник, как потом сохранить этот бинарник уже из памяти на диск?
lldb gdb не работают, т.к программа хитро написана - по pid - connection failed а через обычный запуск - exited with status = 45
>>782531 Короче, продолжаю ебать Scons, собираю bugle. Этот хуесос, несмотря на то, что либа работает и линкуется нормально как-то блять не так собирает. Флаг -l должен быть в конце всех файлов, насколько хорошо я смог вычитать это в мануале по гусю, но тут нихуя. Я не могу понять, что этот хуй пытается вызвать и с какимим параметрами. Либа есть, руками линкуется, скунс не собирает, потому что -l где-то не там ставит. Есть какой-то способ посмотреть вывод?
>>783875 По крайней мере, если использовать cmake, определив системные переменные CC и CXX, можно уже не думать сильно о последствиях, а вот скунс, который на пуфоне меня что-то сильно разочаровал, слишком он уж громоздкий код заставляет рожать
>>784050 Я просто наткунлся на статью Криса К. ТАм они были, ну я решил повторить трюк, пишу через коде блокс, но оглушительно соснул. И вот после дневного переыва мне пришла мысль-может, я сделал что-то не так?
>>784052 Синтаксис вставок не определен стандартом и зависит от компилятора, который ты используешь. Поэтому, если ты хочешь например, чтобы твой код компилировался на любом компиляторе (который поддерживает стандарт, под который ты пишешь), то лучше эти вставки не использовать. Если у тебя есть функция, с каким-то очень критичным циклом, то лучше её целиком на асме написать и прилинковать отдельно.
Почему на пикче выделенный красным нулевой байт имеет адрес, оканчивающийся на 7? Ведь адрес начала это 1383000, он указывает на нулевой байт. Тогда: 68 - нулевой байт 65 - первый 6С - второй 6С - третий 6F - четвертый 21 - пятый 00 - шестой
Адрес шестого байта: 1383000 + 6 = 13883006, а не 1383007
>>784414 > Почему на пикче выделенный красным нулевой байт имеет адрес, оканчивающийся на 7 Нет, у него адрес 0x01383006. Почему ты решил, что это не так?
>>784485 Options->Appearence->Fonts. А про eax тебе уже сказали. Ты прочитал 0 по eax = 0x01383006, сделал inc eax, eax стал 0x01383007, а потом ты уже проверил, что прочитал, и вышел.
Анон, я не понимаю: почему переход по правильному адресу заканчивается сегфолтом?
На первом скрине - пример из книги. Вывод сообщения об успешной авторизации там начинается по адресу 0x080484bf. У меня после компиляции он начинается по адресу 0x080485b6, смотри второй скрин. Если я забиваю буффер значением 0x080485b6, то появляется сообщение об успешной авторизации, а потом почему-то сегфолт. Но если забить буффер адресом 0x080484bf из книги, то сообщение выводится правильное, а сегфолта нет. Почему в этом случае его нет? На четвертом скрине видно, что находится по этому адресу. Это код функции проверки логина.
Почему переход по правильному адресу 0x080485b6 заканчивается сегфолтом?
Почему переход на 0x080484bf успешен и не вызывает сегфолт? Ведь этого адреса даже нет в листинге, смотри начало функции проверки.
>>785569 То есть суть эксплойта, который я запостил, такова: переписываем ret в функции аутентификации адресом 0x080484bf (как в книге), и когда выполняется ret, он переходит в то место, где печатается сообщение об успехе. Но в моем случае это переход опять на код функции аутентификации.
>>785572 Ты уверен, что адрес возврата main() не затираешь? Почему сегфолт не отлаживаешь? На чем он сегфолтится-то? Запусти под gdb, погляди адрес, регистры и стек. И по 0x80484bf мало сдампил, не видно же, чем функция заканчивается.
Посоны, как конвертировать double в long? Ведь в double порядок может принимать значения вплоть до 2^2048, что явно, блядь, не поместится в long, где максимальное число 2^63. Даже сраный float не поместится по такой логике в long. А если не поместится, то будет UB. Что делать, господа?
P.S. Вот вам выдержка из стандарта. Тут говорится "value", т.е. подразумевается, что если непосредственное значение во время рантайма влазит, то все будет ок. Я правильно понял?
>>786444 > если непосредственное значение во время рантайма влазит, то все будет ок Да. Просто проверяй перед преобразованием.
> будет UB Это одно из множества утверждений стандарта, где по-хорошему надо было бы написать, что значение выражение будет implementation defined или на худой конец indeterminate и, соответственно, заставить разработчиков компиляторов задокументировать, что на распространенных архитектурах ничего страшного не случится.
Хочу вкатиться в программирование на Си, пока не знаю, на каком конкретно. Но я практически ничего не знаю в программировании. Так, в школе немного паскаль учил, даже до массивов не дошёл. Посоветуйте годную литературу или какие-нибудь веб-уроки, которые подойдут такому, как я.
Нужна функция с сигнатурой mega_printf(const char * hui, ...), которая в зависимости от чего-то будет вызывать либо printf(hui, ...), либо fprintf(my_mega_pipe, hui, ...). Вообще, реально как-нибудь "..." пробросить?
(Раньше было сделано без пайпа, через переопределение stdout и stderr, но в новой редакции плюсов так бля нельзя)
Есть лог файл (... - всякий мусор): ... ... size=4654,3543 ... ... weight=13 ... ... Мне нужно извлечь 3 целочисленные переменные из строчек начинающихся с size и weight. Где именно эти строчки будут находиться в файле заранее не известно. С помощью каких функций это можно сделать?
Разбиваешь в цикле на строки (или просто ищешь конец строки), с помощью помощью strtok разбиваешь значения по знакам равно и запятым, с помощью strcmp сверяешь имена, с помощью strtol парсишь числа.
С википедии: >The restrict keyword is a declaration of intent given by the programmer to the compiler. It says that for the lifetime of the pointer, only the pointer itself or a value directly derived from it (such as pointer + 1) will be used to access the object to which it points.
Почему же когда я компилирую пик 1 с -O3, и clang, и gcc оба выдают что-то подобное пику 2? Почему после вызова f2 (функция ничего не делает, вынесена в отдельный файл просто чтобы не инлайнилась) значение аргумента для printf загружается из памяти, а не константой? Если изменить расположение вызова f2, то в обоих случаях будет использоваться константа (пик 3 и 4). Разве согласно приведенной выше цитате, объявление указателя p с restrict не говорит о том, что на всем протяжении времени жизни этого указателя доступ к переменной будет осуществляться только через него, что в свою очередь означает, что вызов f2 не должен повлиять на значение переменной a, а значит не требуется читать значение из памяти после вызова f2 и можно использовать константу?
>>790564 Потому что f2 все равно может иметь доступ к указателю на *p, и это не является нарушением семантики restrict. Вообще, restrict нужен чтобы сказать, что два или более указателя не пересекаются. Если нужна гарантия отсутствия других ссылок на объект то тебе в rust с его семантикой владения.
>>790637 Понятно. В общем-то так все и понял, исходя чисто из наблюдений. Просто формулировка на википедии (да и в стандарте) такая, что вводит в заблуждение. А restrict, получается, довольно бестолковая вещь, работающая только для очень ограниченного набора ситуаций. Может мне правда стоит rust поизучать? Но что-то как-то страшно за него браться, честно говоря
>>790664 > для очень ограниченного набора ситуаций restrict - это багфикс. В языке есть strict aliasing, когда указатели несовместимых типов по определению указывают на разные объекты. Это помогает компилятору оптимизировать. Но если у тебя десяток указателей на int, то компилятору легче не становится. Чтобы это решить, сделали restrict. Другое дело, что большинство адекватных людей конпелирует с -fno-strict-aliasing, и на алиасинг им вообще насрать, как и на restrict.
>>790791 Ну, например, до вызова f1 указатель на тот же объект, на который указывает p, был положен в глобальную переменную, из которой его возьмет f2.
Анон, почему переменная окружения с кодом эксплоита каждый раз находится по новому адресу? Можно ли зафиксировать этот адрес для того, чтобы после переполнения буфера передать туда управление?
>>790921 >Подумать головой и не хардкодить адреса, не, не подумал? Плохо представляю, как работает рандомизация. То есть при запуске эксплоита я вычисляю адрес переменной окружения, меняю порядок байт и делаю переполнение, пока адрес не изменился, так?
> According to Intel themselves, REP MOVS is optimal only for large copies, above about 2kb. Below that the large startup costs of the microcode sequence can be beaten by hand-written code for the target architecture. Which explains why glibc takes that approach. The linux kernel on the other hand, just goes with:
> shrq > andl > rep movsq > movl > rep movsb
> Torvalds justified it as a way to force Intel and AMD to do the right thing and optimize the rep movs instructions. He was annoyed at the code complexity of "more optimal" apporaches, and like you, concerned about icache effects.
>>790974 Нужно писать как можно более кроссплатформенный код, чтобы отличий не было (т.е., меняешь в VS Active Configuration с x86 на x64, и все так же работает, как и раньше). Разница в размерах всяких long и прочих указателей. На первых порах ты ее не заметишь.
Анон, как это работает? Если адрес переменной вычисляется так, как написано, тогда разные переменные для разных программ будут одновременно находиться по одному адресу, если длина содержимого переменных и длина имени программ одинаковые. Как такое может быть?
>>791013 Почитай про виртуальную адресацию. У каждой программы в современных ОС есть свое собственное адресное пространство. Процессор и ядро сами разбираются, какой странице физической памяти соответствует тот или иной адрес, принадлежащий процессу. Погугли virtual memory, virtual address space.
Только почему якобы рабочий эксплоит завершается сегфолтом? Все так хорошо написано про вычисление адреса возврата, на который передается управление, но на деле что-то пошло не так. Использование -fno-stack-protector не помогает. Но этот ключ, вроде, не делает стэк исполняемым, а отключает стэк канарис.
>>791100 Очевидно, что по этим и учиться, а когда будешь в них нормально разбираться, читать в бложеках про новые техники. Можешь параллельно со старым говном почитывать кулстори с Google Project Zero, например.
>>791103 Не знаю, как учиться, если ничего не получается. В книге написано, что этот эксплоит работает 100%, и показан результат получения шелла, а у меня при двух отключенных защитах что само по себе - лабораторные условия вылетает сегфолт. У меня бугурт и руки опускаются, потому что непонятно, в чем дело. Пойду читать главу про написание эксплоитов на nasm, а после этого шеллкодинг под линукс Криса Касперски.
>>791282 > Не знаю, как учиться, если ничего не получается. Ну посмотри год книги и поставь на виртуалку соответствующий году линукс. Главное - понять основы, а с современными ОС, с активированными по умолчанию защитами, да с 64 битами кроме основ лезут всякие ненужные на этом этапе детали.
Скинь название книги и главу, откуда ты взял >>791073 и давай разбираться. Не вижу в коде явных багов, которые могут дать шелл: оно должно перезапускать себя бесконечно, оно это и делает. Никаких сегфолтов.
>>791312 1) echo 0 > /proc/sys/kernel/randomize_va_space (лабораторные условия, да). 2) Почему оно не работает, а у автора работает: компилятор и опции компиляции. Если вкратце, strcpy помимо адреса возврата повреждает сохраненный стековый фрейм. Собери заново notesearch, отреверси пролог и эпилог main() и "донастрой" под нее свой эксплоит. Поставь бряк после closefd(), потыкай si и посмотри, какие регистры откуда восстанавливаются. В моем случае достаточно поменять в эксплоите размер буфера со 160 байт до 152 gcc 6.1.1, -O0, 32-битный линух.
А пока что я засел на неправильно сгенерированном бинарнике. В книге создание автономного шеллкода показывается на примере хелловорлда: https://ideone.com/KBW9qu
У автора программа просто ассемблируется и превращается в набор инструкций, но у меня nasm почему-то создает ELF-файл, смотри второй скрин. Погуглил опции nasm и нашел опцию -f bin, которая ассемблирует исходник как файл для доса. Сначала я думал, что в досе программы состояли из сплошных инструкций, но сейчас вспомнил, что в типичной программе для доса был стаб и выравнивание кода по смещению 100h.
Как сгенерировать только необходимые инструкции без этого мусора?
>>791721 > Как сгенерировать только необходимые инструкции без этого мусора? Быстро и удобно: взять фасм, его макроязык, хоть и ебанутый на всю голову, но позволяет делать всякие вкусные вещи типа кодирования нулей в шеллкодесе прямо на стадии компиляции (естественно, макрос сам пишешь).
> -f obj Просишь эльфа - получаешь эльфа.
> Погуглил опции nasm и нашел опцию -f bin, которая ассемблирует исходник как файл для доса Она дефолтовая, емнип.
> что в типичной программе для доса был стаб и выравнивание кода по смещению 100h. Во-первых, в .com стаба не было, во-вторых, чтобы был org 100h, его надо делать самому в исходнике. Так что nasm shellcode.s, bits 32 не забудь, и все конпелируется, как у автора.
Как в таких случаях находить причину краша? Адрес переменной окружения с шеллкодом известен, команда x/5i 0xbffff6d1 показывает, что по этому адресу действительно находится шеллкод, переполняю буфер адресом 0xbffff6d1, и возникает сегфолт. В дампе видно обращение по какому-то странному адресу.
>>791775 Странный адрес - часть строки "ODE=". Очевидно, что это нихуя не адрес возврата, ты промахнулся. >>791578 смотрел?
> Как в таких случаях находить причину краша? Живую программу отлаживать проще. Собираешь с -ggdb, делаешь gdb сплоент, b main, run, брякнется в main, continue, брякнется в notesearch:main, disassemble, b *адрес_в_конце_функции, set disassemble on, si, si, si...
Кто-нибудь ИТТ имеет опыт программирования микроэлектроники, когда на девайсе 10-пиновый 1.27 мм разъем, а у программатора выход 10-пиновый 2.54 мм? Какие переходники использовать и где кабели покупать?
Поясните пожалуйста что это за ошибка оталдчика gdb gdb -q ./a.out Reading symbols from ./a.out...(no debugging symbols found)...done. Или это нормально?
>>793030 gdb имяфайла или командой target exec имяфайла, когда gdb уже запущен. Предварительно желательно спиздить чей-нибудь конфиг типа https://github.com/dholm/dotgdb Ненастроенный gdb - боль.
Анон, как использовать hashcat для расшифровки хэша? Запускаю hashcat -m 0 ./myhash /usr/share/wordlists/rockyou.txt, и программа выдает line length exception. Пердолиться долго не хочется. Насчет того, что хэш именно md5, не уверен, просто вытащил из БД какой-то хэш.
Читаю C Primer Plus, делаю упражнения. Начало бодрое, но потом какие-то ненужные углубления идут. Сейчас на главе про string'и, я программировать-то не умею, а тут мне в одной главе все по верхам рассказали, а остальные главы какие-то дерби, тонкости языка и т.д. которые я не запомню и не выучу может я и не должен и юзать как справочник стоит?. Ну вот пол главы все о функции printf. Я понимаю, конечно, что я должен знать как оно работает, но не лучше ли сначала научиться использовать, а потом углубляться в тонкости? Скажите, это я неправильный или ?.?
>>793604 Этот примиер плюс то еще говно, лучше читай K&R, там все нормально объясняется, а вот это говно с разжевыванием нинужной информации нахуй не нужно.
Двощ, объясни нубу, есть массив символов char x[] = "32+"; , по которому проходит цикл со switch при этом в свитче выполняются сразу два условия и '+' и '-', код прилагаю pastebin.com/y00vRZyk
>>793737 это прост готу метки в переделах одной области (блять, как это называется? стейтмент?).
Долбоеб не может в указателиАноним11/07/16 Пнд 22:12:01#175№793830
У меня серьезная проблема: я не могу в указатели. Объясните что это такое, я нихуя не понимаю их принцип работы. И да * - это указатель, и & - тоже указатель. Скажите правильно как это называется, я уже 2 недели ебусь с этим Блядь, хочется выпилится из-за ебучих указателей
>>793830 & - это оператор взятия адреса. Вот есть объект (переменная), он где-то в памяти лежит. И значение выражения &объект равно адресу (номеру) первого байта этого объекта в памяти. Это значение "указывает" на объект, т.е., это и есть указатель. Но важно осознавать, что не & - указатель, а значение выражения с & (или переменной, в которую ты его запишешь). ∗ - это оператор разыменовывания (дереференс). Значение выражения ∗указатель - это значение по адресу, хранящемуся в указателе.
&чтото -> получить адрес чего-то ∗указатель -> сходить по адресу и взять оттуда что-то
>>793830 В любом непонятном случае дизассемблируй. Указатель - это такая коробочка, в которой лежит адрес другой коробочки, в которой лежит объект. Звездочка - это когда ты открываешь коробочку, переходишь по адресу и берешь объект. В коробочке может быть не адрес, а другая коробочка, в которой уже лежит адрес. Это указатель на указатель. Чтобы получить объект через указатель на указатель, надо открыть одну коробочку (один раз применить звездочку), открыть внутреннюю коробочку (второй раз применить звездочку), и тогда ты доберешься до объекта в памяти.
>>793877 int x = 2; // Компилятор создал переменную x по адресу 0x1000 (к примеру). Теперь x просто имя (псевдоним) для адреса 0x1000. Всегда (в пределах области видимости x), когда компилятор видит x, он думает об адресе 0x1000. int ∗y = &x; // Компилятор создал переменную y (указатель) по адресу 0x1004 и записал в нее значение 0x1000. int ∗z = y; // Компилятор создал переменную z (указатель) по адресу 0x1008 и записал в нее 0x1000. Почему 0x1000, а не 0x1004? Потому что = присваивает значения. Значение y - 0x1000. printf("%i\n", ∗z); // Оператор ∗ взял значение по адресу, содержащемуся в z и скормил его в printf. В z лежит 0x1000, по адресу 0x1000 лежит 2, в printf попало 2. printf("%p\n", y); // Оператора ∗ нет. Компилятор взял значение y и скормил его в printf. В y лежит 0x1004, в printf попало 0x1004.
Мне как новичку было сложно понять взглядом где идет создание указателя, а где разыменование. Где создание ссылки, а где операция взятия адреса. Особенно когда приходят скобки, типами выступают всякие указатели на функции. Пиздец
>>793913 К сожалению, автоматически (юзерскриптом) исправлять ошибки тех, кто постит с настоящими звездочками и настоящими [ i ] не получится, а макаке насрать, много раз уже просили. И в /d/, и кодера, когда он в /b/ прибегал, и соцсеточках тоже. Запилить галку "я не хочу разметку вообще никакую" для них слишком сложно. Написать не кривой парсер, видимо, тоже.
>>793917 Это нормально, лечится более частыми визитами в отладчик.
> где идет создание указателя Указатель можно заиметь тремя способами: получить из функции типа malloc(), присвоить от другого указателя и получить оператором &.
> Где создание ссылки, а где операция взятия адреса. А плюсы свои ты к нам не носи. Хотя там тоже все тривиально.
> указатели на функции Для них сахарок, о них вообще не нужно думать. Не нужно & писать, чтобы взять адрес и не нужно разыменовывать, чтобы вызвать. int (∗funcptr)(void); // Указатель на функцию, возвращающую int.
>>793954 Сахарок в том, что сколько бы ни было уровней указателей в funcptr, ее вызов не требует звездочек - оператор () будет неявно дереференсить указатель столько раз, сколько необходимо. Примерно то же происходит и с массивами, когда они используются там, где ожидается указатель.
>>793919 >>793922 нах это надо есть же табличка приоритетов операторов и их ассоциативности ну и все сложные объявления легко читаются посредством использования или заучивания этой таблички
>>793980 Вот я и интересуюсь. Не будет ли оверхеда на втором варианте? Или он эту пропущенную звёздочку подразумевает и так? только почему же тогда не выдает ошибку компиляции на этом варианте?
>>793976 Привет. Мы этот сахарок уже несколько постов предыдущих обсуждаем. Это указатель на функцию. Во всех случаях. Про эквивалентность ∗funcptr() и funcptr() знают многие, про то, что параметр-функция считается указателем на функцию - нет. Алсо, в одном из прошлых тредов обсуждали параметры-массивы, которые тоже неявно приводятся к указателю. И хорошо, потому что лучше написать с указателем самому, чтобы все было наглядно. Но это единственная причина.
>>793981 Никакого оверхеда, абсолютно идентичные вещи с точки зрения компилятора.
Допустим, есть один хеллоу ворлд, как его скомпелять в минимальный екзешник? Просто gcc hello.c -o hello.exe дает екзешник в 66 кБ. Это много же для хеллоу ворлда.
>>794151 Ага, точно, попробовал сейчас скомпилить. Но в шапке написано, что это плохой компилятор. Вот говорят, есть еще какой-то crinkler, но я не понял как его скрестить с gcc.
Есть два массива разных типов. Пусть условно один будет double, a другой int. Как мне сделать указатель на массив, чтобы потом работать с этим указателем и забыть про изначальный тип массива? Я собираюсь только читать из них.
>>795211 Да заебали вы. Во-первых, в VS нет зондов. Считать зондами телеметрию, которая записывает в лог имя модуля и таймстампы загрузки-выгрузки - это надо вконец мозолей объесться. И даже эта телеметрия по умолчанию отключена при линковке с динамической CRT и отключается при линковке со статической CRT (no_telemetry.obj).
Во-вторых, MinGW в тот десяток килобайтов, который тебе так не нравится, линкует статически те функции, которые в MSVCRT застряли в C89 (тот же печально известный vsnprintf) и прочий библиотечный код. Можешь вообще сказать гцц, что тебе не нужна стандартная библиотека, писать на Windows API и линковаться хоть в 512 байт. Можешь линковаться к какому-нибудь другому рантайму, тебе никто не мешает.
>>795166 А что там тебе непонятно? Я K&R осилил в 10 классе, лул, толку конечно немного было, но зато удовлетворил свою хотелку.
Долбоеб не может в указатели. Часть 2. МассивыАноним14/07/16 Чтв 13:46:09#224№795848
Я тот самый долбоеб, который не смог в указатели. Я благодарен всем, кто пояснил мне за указатели, но мне снова нужна помощь. Насколько я понимаю, то первый элемент массива, при передаче его в функцию является указателем на массив? Или массив, при передаче в функцию является указателем на первый элемент?
Почаны нашел книгу по си называется Head First C, там вроде интереснее пишут, чем КиР, да и охват тем больше. Стоит ее читать, опыта программинга на си нет?
>>795876 >>796023 Вот поясните мне. Я передал в функцию какой-то массив. И решил сделать в этой функции sizeof на массив и на первый элемент массива. В итоге получилось то что на пике. Почему так? Вроде же массив является указателем на первый элемент и его размер 8, а размер первого элемента 4. Почему так? В чем подводные камни?
>>796042 Заменил, теперь выходит 8 и 1 соответственно. Подумол, у чара 1 байт в большинстве случаев размер переменной. А можно ли передать в функцию массив, чтобы его размер можно было вычислить в функции через sizeof(массив) / sizeof(массив[0]), ибо обычным путем это невозможно сделать
>>796032 sizeof(array) == sizeof(&array[0]) == размер указателя (зависит от платформы) Настоящий размер массива из n элементов в памяти равен sizeof(array) * sizeof(n) Т.к. сишка размера массива не знает (он нигде не хранится), то вычислить настоящий размер не может.
>>796056 В С++ есть класс vector, устроенный примерно таким образом (хранит информацию о размере). В Си из коробки ничего такого нет, массивы там просто синтаксический сахар над указателями. А у строк длина вычисляется, потому что последний символ 0.
>>796157 когда я был школотроном, то пека еще небыло, а вот вкатывался я с ассемблера и архитектуры канпутера, чего и тебе советую, читай про архитектуру пека и ос, хотябы таненбаума, а погромирование чутка отложи, а то заебешь всех и станешь макакой
>>796166 Я сам стал заниматься программированием в 1991 году на спектруме, и в 12 лет мог писать на ассемблере (и даже в машинных кодах). Не надо заливать, никто с ассемблера не начинал.
>>796173 >никто с ассемблера не начинал. я начинал, или жопочтец? я считал, что си слишком сложна11 и начал с тасма и книги тома свана, ахуенная книга. вот.
>>796032 Когда массив является параметром функции, он неявно конвертируется в указатель. >>793991 вот совсем недавно даже стандарт выкладывали. Поэтому sizeof() возвращает размер указателя. В остальных случаях sizeof() с массивами работает, как ожидается.
>>796178 Вот же ты доебался до того анона. Я тоже начинал с ассемблера, что тут такого. Просто когда решил заняться программированием, я сначала хотел скачать вижуал студию, но как увидел, что качаться она будет чуть ли не неделю, то скачал вместо нее masm (а вскоре перешел и на fasm). А сишку и другие языки я попробовал только после того, как перекатился на линукс через пару лет.
>>796219 Лет 10-11 назад, и у меня тогда как раз появился "доступ" к интернету (через мобильник со скоростями в районе пары кб/сек). В моей стране около 250 тыс человек, а в городе хз. Конечно же, я не от хорошей жизни взялся тогда именно за асм. Но может оно и к лучшему.
>>796224 Машина должна и будет служить людям, она не шлюха, чтобы люди исполняли её прихоти. Отсюда байтобляди (а так же сочувствующие им императивные пидорасы, надрачивающие на показатели clock() - start) - пиздолисы, которые опускаются до полного говноедства, лишь бы ублажить её регистры и микросхемы. Альфапрограммисты, как и положено альфам, если машина не выполняет положенных ей задач и требует пресмыкаться перед ней и ублажать её байтами, просто берут и за патчкорды, ебашат с вертушки по передней панели и списывают машину на мороз, купив взамен ту, которая не будет выёбываться и выполнит код в сроки и без выебонов, будь там хоть 1000% неоптимизированного оверхеда. И настоящего программиста не волнуют вопросы выдрачивания и быстродействия - он решает важную задачу из предметной области гораздо более сложной, чем низкоуровневое дрочево, и отвлекаться на всякую подзалупную хуету вроде осоьбеннойстей какой-то там архитектуры ему некомильфо. Байтоёбство включает в себя: 1. Императивный стиль программирования как начало байтоёбского пути. 2. Дрочка на машинно-ориентированные типы данных (собственно, основной симптом байтоёбства) и последующее за ней закономерное возмездие байтомудакам в виде big endian vs. little-endian, особенности обработки чисел с плавающей точкой и.т.д. 3. Предтерминальные стадии байтоёбства - интринсикоёбство и его более тяжёлая форма - инлайн-ассемблероёбство. Подсадка начинается с убеждённости поциента в необходимости ручками использовать SIMD -инструкции. 4. Терминальная стадия, как итог п.3, тру-ассемблероёбство и "хроническая низкоуровневая оптимизация головного мозга" В нашем мире, к счастью, подобные симптомы с распространением Java, C# и прочей "замещающей терапии" встречаются реже, однако остались две отрасли, входящие в зону риска: 1. Гейдев. Байтоёбство в гейдеве берёт своё начало в 70х-80х, поскольку именно тогда зародилась традиция байтоёбства в геймдеве. Обязаны этим, в основном, восьмибитным соснолям и домашним компьютерам, которые, обладая малым объёмом ОЗУ и имея скудные средства программирования, требовали делать на них ёба-игры. Эта традиция продолжилась и далее, всё благодаря тем же консолям, на которых консолерабы должны были выпускать игры 5 лет, задрачивая их убогие байтоёбские архитектуры по полной. К сожалению, подобная практика перешла и на ПК, где байтоёбство, в общем-то не так оправдано. К слову байтоёбам-игроделам дали шанс выбраться из этой трясины в 2002 году, когда майкрософт запилила дуднет и менеджед дайректикс к нему. Но байтоёбы остались верны своим указателям, плюсам и байтоёбской оптимизации. Зашоренность, верность привычкам, безыдейность, десу. 2. Эмбеддед. Причины почти всё те же, что и в гейдеве. Маломощное железо, пара сотен байт озу, деревянные игрушки, прибитые к полу и.т.д. К этому прибавляется огромное количество разных железок разномастных архитектур, для которых нет толковых тулчейнов. Из хорошего - в последние годы байтоёбство в этой сфере потихоньку излечивается, спасибо дядям из ARM co ltd, сделавшим свою архитектуру более менее распространённым стандартом среди всех архитектур и огромному количеству появившихся фреймворков и компиляторов языков для этой платформы. Также распространено ложное утверждение что байтоёбство крайне необходимо в системном программировании. На самом деле этого легко избежать. Рассмотрим среднестатистическую аппаратную платформу. Краеугольными камнями любой аппаратной платформы являются: 1.Процессорная архитектура 2.Memory map - адресное пространство, в которое отображаются RAM, ROM и внешние устройства 3.Протоколы управления этими самыми внешними устройствами. Так вот, всё вышеперечисленное вполне можно вполне декларативно описать обычным конфигурационным файлом, не прибегая к программированию вовсе. Затем, скормить этот файл генератору платформ и на выходе получить готовый фреймворк-скелет нашей операционной системы, доступ к которому можно получить из любого языка программирования. Вот так вот просто, если бы байтоёбство гологного моска не мешало.
>>796238 >просто берут и за патчкорды, ебашат с вертушки по передней панели и списывают машину на мороз, купив взамен ту, которая не будет выёбываться и выполнит код в сроки и без выебонов, будь там хоть 1000% я работал в такой конторе, лучшим решением для инженеропидоров был апгрейд и перезагрущка серверрв раз в неделю. по сабжу, ты ебаный еаркоман оторванный от реалий.
>>796238 Двачую, байтоёбы рабы во всём - рабы машины. рабы предубеждений, рабы производительности, рабы стереотипов, рабы обрабатываемых штеудом х86 типов данных - для них всё, что не кратно 2 байтам и больше 16 байт не может быть примитивным типом, хотя число - это просто число, оно может быть целым, дробным, рациональным, комплексным, но не "в 2 байта в 4 байта в 8 байт". Да, байтобляди были актуальны пару-тройку десятков лет назад, когда кроме этого пресловутого отлизывания регистров и микросхем не было способов заставить машину быстро решать задачу. Но теперь-то в нашем распоряжении оптимизирующие компиляторы, многоядерные процессоры с параллелизацией, которые производительнее машин 20летней давности в сотни тысяч раз. Жаль, что программирование было поглощено стереотипным быдлом, не могущим в думать, и способным работать лишь по зазубренной инструкции, написанной кровью и потом сотен павших хомячков-байтоёбов до него. Настоящее, полноценное программирование, благодаря подобным обмудкам, мало теперь где востребовано. Хотя там где оно востребовано, можно кататься как в масле сыр и получать в три раза больше не то что сениор-байтоёба, а ёбанного заместителя директора быдлоконторы в которой этот байтоёб работает. С другой стороны это и хорошо - в космическую промышленность, Data mining и прочие сложные и непосильные для императивных байтохомячков сферы попадает лишь элита.
>>796131 >resize не нужно, выделяй блоки памяти сразу нужным и связывай их в спискок, доступк к элементу через функцию (есле нужен номер). если блок освободится, то можно освобождать, или в стек на отложенное освобождение.
>>796248 >число, оно может быть целым, дробным, рациональным, комплексным, >в космическую промышленность А ты почитай на чем пишутся спутники и марсоходы, и какой жёсткий realtime нужен ракете. Там байтоебство цветет и пахнет, потому что по другому никак.
Стандартобляди, поясните плиз. Какой тип дается по умолчанию, если в декларации функции забыть его указать? Для примера, какой тип будет у параметра bar в таком случае? void foo(bar){ printf("%lf p\n",bar/0.3048); }
>>796567 >Просто съеби в /b Нет ты. Единственная причина почему ваше байтоебство актуально в космической сфере — это потому что 100-летние деды в начальстве боятся обосраться с новыми технологиями и в 2016 году по прежнему используют 8-битные процессоры и ассемблер.
>>796593 Ты думаешь, будь это не 8085, то писали бы на православном JavaScript? Один хер это бы был Си с ачсемблерными вставками, байтоебством и записями в регистры. Такова реальность realtime
>>796238 Ок. Каждому своё и каждый пишет так как ему нравится. Но разве любая функция из функционального программирования не написана в императивном стиле? Вообще не совсем понятно: мне необходимо выбрать какой-то кусок данных из массива данных. Я использую SQL, пишу функционально инструкцию, но разве на низком уровне она не состоит из тех же базовых императивных кирпичиков? И тогда в чём собственно суть разницы если функции это есть те же самые подпрограммы императивного языка?
>>796659 >Я использую SQL, пишу функционально инструкцию И в зависимости от содержимого базы каждый раз получаешь разный результат. Это не функция.
>Unlike in imperative languages, a function in Haskell is really a function, just as mathematicians intended it to be. To distinguish it from cheap imitations, Haskell functions are sometimes called pure functions. Here are the fundamental properties of a pure function: >A function returns exactly the same result every time it's called with the same set of arguments. In other words a function has no state, nor can it access any external state. Every time you call it, it behaves like a newborn baby with blank memory and no knowledge of the external world. >A function has no side effects. Calling a function once is the same as calling it twice and discarding the result of the first call. In fact if you discard the result of any function call, Haskell will spare itself the trouble and will never call the function. No wonder Haskell has a reputation for laziness (more about it later).
>>796665 Всё равно не понятно. Т.е. наиболее главное отличие декларативного от императивного программирования это отвязка от архитектуры железа, на котором исполняется конечная программа? Тогда реквестирую пример когда функция из императивного языка возвращает каждый раз разный результат при одном и том же наборе аргументов.
>>796673 Суть чистой функции в том, что её вычисление можно рассматривать как переписывание термов. Это позволяет, к примеру, свободно заменять выражения их результатом или вычислять их по необходимости (лениво). Разумеется, не все функции в функциональных ЯП — чистые. Однако, в том же хаскеле есть разграничение между чистыми функциями и грязными.
>>796673 >Всё равно не понятно Байтоебы смешали в кучу понятия подпрограммы, процедуры и функции. В результате правильным посонам пришлось назвать функции — чистыми функциями. У функции есть четкое математическое определение: >"Let E and F be two sets, which may or may not be distinct. A relation between a variable element x of E and a variable element y of F is called a functional relation in y if, for all x ∈ E, there exists a unique y ∈ F which is in the given relation with x. "We give the name of function to the operation which in this way associates with every element x ∈ E the element y ∈ F which is in the given relation with x, and the function is said to be determined by the given functional relation. Two equivalent functional relations determine the same function."
>>796659 > каждый пишет так как ему нравится. А должен бы писать качественно. > И тогда в чём собственно суть разницы если функции это есть те же самые подпрограммы императивного языка? ВСЕ РАВНО ВСЕ КОМПИЛИРУЕТСЯ В МАШИННЫЙ КОД Абстракции - слыхал о таких вещах?
конечно, это вот когда ты дрочишь, можно конечно сконцентрироваться на писосе, руке и трении, но куда прогрессивней абстрагироваться в хатку с евой грин и её братцем - братец, это побочный эффект, оверхед. вы будите ебаться а он будет смотреть и дрочить, или там спать с вами в обнимку.
>>796690 Слыхали и что? Если я напишу функцию определенного интеграла, принимающую на вход пределы интегрирования и реализующую в себе какую либо мат.функцию это будет тоже абстракция. И я могу написать её на императивном языке.
>>796726 Но в манямире функциональных петухов нет IO, файлов, GUI и сетевых протоколов. Это очень удобно - объявить все нерешаемые функциональной парадигмой задачи грязными и нечестивыми, узаконить страдания для всего неправосланого, и затем сидеть, прихлебывая борщ, дрочить факториалы и постить на хабре статьи про теоркат для чайников.
>>796563 Тип по умолчанию у нас int. Но желательно сказать GCC -Werror=implicit, чтобы такого пиздеца не допускать.
>>796734 Кроме wchar_t, который уже упомянули (и который по сути implementation defined), в C11 у нас есть еще char16_t, в который влезает вся BMP и char32_t, в который влезает весь Unicode вообще. В целом, проще везде использовать UTF-8 (и хранить в char), а в тех нечастых случаях, когда требуется быстрый доступ к отдельным codepoint по их индексу в строке, декодировать UTF-8 до charX_t.
>>797873 Спиздил когда-то из ядра NetBSD компактный и простой переносимый printf. http://pastebin.com/nBi6G5cT Сейчас уже не могу найти его в дереве ядра.
Всё, что нужно функции do_printf — это твой коллбэк для печати одного символа, первым аргументом. Очень удобно!
>>797895 Я прерываниями BIOS пользовался только под MS-DOS, помню. Как дела с этим обстоят в современных ОС? Там всё то же самое? Мне чё-то кажется современная ОС тебя нахуй пошлёт с твоими вызовами прерываний.
>>797930 Тем более не стоит начинать с груба. Лучше осилить перевод процессора в protected mode и long mode самостоятельно, тогда и вопросы про прерывания отпадут.
>>797938 В ОС (ну кроме простых вроде DOS) тебе никто не даст писать в видеопамять, и даже если даст, режим видео будет неподходящий, и даже если подходящий - охуеет видеодрайвер.
Пацаны, хочу стать погромистом. Мудрые дяди сказали начать с С, какие подводные камни? Вот тут компилятор гцц у вас, он же только на линуксе? Мне линукс ставить обязательно или есть вменяемый аналог на винду?
>>798048 посмотри еще шапку c++ треда в иде нету компилятора, компилятор отдельно. если впадлу качать то там ведь есть pelles c + можешь скачать code blocks или освоить емакс а вообще просто поставь линукс, там гцц будет а под виндой visual c
Постараюсь решить проблему самостоятельно, но на данный момент ничего на ум не приходит
int n;
do { printf("Enter the height from please: "); n = GetInt(); } while (n <= 0, n > 23);
error: relational comparison result unused [-Werror,-Wunused-comparison] while (n <= 0, n > 23);
Понятия не имею, почему одно придралось. Мб неправильно задал условие?
Программа предлагает ввести целое число, которое не должно быть отрицательным и не больше 23. Потом она должна вывести на экран какую-то лабуду, которую ДЛЯ ЭКСПЕРИМЕНТА прописал так:
else printf("YOBA\n"); //Это после while.
Пхд вместо n <= 0 нужно убрать =, но это проблему не решает.
>>798152 отличная идея, щас зазвоню ей, чтобы она с пляжа отвлеклась на моё внимание, блядюка, и выскажу ей: я, сука, сделаю тебе бутер, и не важно когда ты приедешь обратно, всё поняла?
Хочу стать маминым отладчиком. Глава в "Искусстве дизассемблирования" про GDB подойдет для изучения отладки при помощи него? До сих пор использовал GDB только как дизассемблер и трассировщик.
Эмм, посоны. Почему этот код при запуске выдает сегфолт? https://ideone.com/j0uz5t Точнее, GDB показывает, что при записи в секцию кода mov BYTE PTR [ebx+0x7],al программа валится. Видимо, прав доступа нет. А под досом такое легко проворачивалось.
Прочитал, что mprotect не добавляет права, а перезаписывает, поэтому надо объединять флаги. Объединил 1 | 2 | 4 и передаю 0x07 как права доступа к памяти. Все равно не работает.
Проверку errno сейчас сделаю. Думал еще, что не тот номер системного вызова использую, потому что вот тут http://asm.sourceforge.net/syscall.html номер mprotect 125, но у меня в файле unistd.h номер именно 226.
>>798570 Указатель на имя /bin/sh, заканчивающееся нулем. Третий аргумент - 32-битный ноль. Вызов mprotect у меня почему-то возвращает -2. >>798567 Почему именно 125, если у меня в unistd.h вызов mprotect имеет номер 226? А с номером 125 у меня какая-то хуита, которая подвешивает консоль.
Итак, под отладчиком у меня шеллкод: 1. Выполнил вызов 125 функции 2. Успешно выполнился код, выводящий errno. 3. Как будто успешно перезаписал данные в секции кода (второй скрин). Буду трассировать дальше.
>>798602 Ебать я лох. Вся проблема в том, что когда перед вызовом execve я настраивал аргументы шелла и окружение, то использовал регистр ebp вместо ebx. Теперь шелл спавнится :3 Пойду писать сплоент на си, это будет просто по сравнению с тем, что было до этого.
>>798715 Классика это скорее краткий фулл-референс в годном изложении, чем учебник. Об этом даже в начале сказано. Да и упражнения там не то, чтобы сложные, просто непонятно что конкретно от тебя там просят. Ну так было в переводе на русский, английскую я не читал.
>>798869 Прочитай первые две главы, если все понятно и упражнения получаются, то тогда и дальше читай. Если же нихуя не понятно, то поищи что-нибудь другое
>>798992 Спецификатор %c выводит символ с кодом, который ты передаешь в аргументе. char i = '#' (или int i, похуй) присваивает переменной код символа #. Естественно, сделать это нужно до использования переменной (до вывода), а не после.
вот такой у меня цикл. n взято из предыдущего куска программы, и его задаёт пользователь. И почему вместо хешей выводит пустоту. Да, эта пустота будет занимать столько же строк, сколько я задам, но блять, я спать хочу уже
>>799008 Ты не понимаешь, что ты делаешь. А делаешь ты вот что: на первой итерации цикла (ты ведь уже читал про циклы? (initialization; check; increment) - вот это все?) ты перезаписываешь i нулем. Потом ты идешь в printf. И печатаешь символ с кодом (i + 2), т.е., 0 + 2 = 2. Это обычно смайлик, но твоя консолька может рисовать вместо него что-то другое. Например, ничего. Потом ты идешь на следующую итерацию, увеличиваешь i на единицу и печатаешь символ с кодом 3. А код символа '#' равен 35, если что. http://ideone.com/xcfPxz
>>799015 У тебя i отвечает за количество строк. Если ты хочешь в каждой строке выводить несколько диезов, тебе нужно считать эти диезы, т.е., тебе нужен вложенный for. Или ты можешь решать на основании какого-нибудь условия, когда тебе втыкать символ новой строки. http://ideone.com/wYfPA7
>>799573 Ну сам то привык всё решать самостоятельно, но когда ты вроде делаешь всё правильно, но ничего не выходит - нужно же спросить у кого-то совет.
Я не знаю, чего тебя это так задело, на самом деле. Вот скоро научусь - сам буду помогать таким же залётышам, каким являюсь сам. По моему - это очень даже хорошо
>>801698 Почему вы решили, что он умер? Его, бывало, и с последней страницы бампали. А вообще, все уже обсудили, и теперь просто отвечаем на вопросы ньюфагов.
Так, меня не было дома несколько дней, и тут нужно дальше решать эту фигню. И да, знаю - всем похуй, но продолжим.
Суть программы состоит в том, чтоб вывести полупирамиду из #. Типа вот так вот:
# ## ###
Компьютер предлагает ввести высоту выводимого объекта. Если пользователь вводит недопустимое число - предлагает ему ввести ещё раз.
{ printf("Enter the height please: "); n = GetInt(); } while (n <= 0 || n > 23);
Вторая часть уже занимается выводом ебаной фигуры. Пока что она выглядит так:
int c = '#'; //тут можно было и написать char, но пока оставил так
for (i = 0; i < n; i++)
{
printf("%c\n", c); //в гайде прямо тут предлагают через принт вывести необходимое количество пробелов, потом хешей ну и переход на новую строку, но не говорят как, да и вообще, там подруга несёт какую-то хуету. }
Чего я не понимаю, так это как заставить выводить количество #. Конечно, можно сделать по нубскому и прописать if (строка 0) принтф('#') и так далее, пересчитывать каждые варианты. А если формулой, то количество хешей должно равняться i+1. Индексация же с нуля проводится, да? Знач первая строка = 0, вторая = 1 и т.д. Тогда эта хрень по идее* должна работать, но я в душе не ебу, куда её пристроить, ведь тип там символы, а символ... ну вы поняли меня.
>>801798 А давай ты код на ideone/pastebin/gist будешь постить или картинкой на худой конец?
> через принт вывести необходимое количество пробелов От тебя ожидают очевидного: максимальная ширина такой полупирамидки равна ее высоте, т.е., n. Дальше: - в первой строчке ты выводишь 1 хэш, значит, перед ним должно быть n - 1 пробелов; - во второй строчке: 2 хэша, значит, перед ним n - 2 пробела - и т. д., Все правильно, количество хэшей i + 1, но зачем тебе делать цикл с нуля, когда ты можешь сделать его сразу с единицы: for (i = 1; i <= n; i++) (заметь, что там <=, потому что в последней строчке тебе нужно i = n хэшей, а если напишешь <, то тело цикла не выполнится, и последняя строчка не выведется). Если цикл с 1, тогда формулы упрощаются, и тебе нужно вывести в каждой строке n - i пробелов, потом i хэшей, потом символ перевода строки.
> в душе не ебу, куда её пристроить Тебе нужно сделать что-то n раз? Вывести n символов? Используй цикл. Хочешь вывести n строк, в каждой по m символов? Используй цикл до n, а в нем сделай цикл до m. А внутри уже printf или putchar.
Алсо, есть неочевидное решение. У printf в каждом спецификаторе форматирования кроме типа можно задать еще и ширину. Мало того, ширину можно задать динамически: http://ideone.com/iRkJAA (комментарии внутри). Тогда цикл понадобится один, но ты все-таки сделай с двумя а возможно, что и с тремя для начала.
>>801830 Так, как тебе нравится. Главное, не используй гнутый стиль, и с тобой все будет хорошо. Ну и если решишь все же ставить скобки на отдельной строке, заранее подумай, как далеко ты готов зайти (в do {} while, typedef struct {} name и прочих int values[100][2] = { { стоконстант }, { ещестоконстант }}).
>>801736 Обсудили всё?! Да это забавно. Как можно охватить такой огромный раздел в рамках маленького сообщества этой доски? У нас препод был который давал нам основы и утверждал, что знать все тонкости языков невозможно. И у меня нет оснований ему не доверять.
Что читать:
- Классика от Отцов: http://www.ime.usp.br/~pf/Kernighan-Ritchie/C-Programming-Ebook.pdf
- Годное пособие для гуманитариев: http://c.learncodethehardway.org/book/
- Немного примеров хорошего стиля: http://www.oualline.com/books.free/style/index.html
- ООП, например: http://www.cs.rit.edu/%7Eats/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 2015 Community Edition: внезапно этим стало можно пользоваться, особенно с тулсетом clang/C2. Поддержка C11 на уровне "есть все, что тебе понадобится в реальном проекте плюс кривая библиотека". Анализатор кода в комплекте.
- Pelles C (шиндоуз онли): поучиться, вкатиться в C11 (стандарт полностью реализован, имеются в том числе threads.h и прочие stdatomic.h), но количество багов в оптимизаторе и редкие апдейты напрочь отбивают желание собирать этим что-то сколько-нибудь серьезное.
- TCC: очень маленький компилятор с багами и неполной поддержкой C99. С ключом -run умеет компилировать код в память и запускать его, что позволяет писать скрипты прямо на сишечке.
Что еще почитать:
http://c-faq.com/
FAQ из comp.lang.c. Древний, но все еще актуален.
Stephen Prata "C Primer Plus, 6th Edition" (2014)
Свежая знает про C89, C99, C11, описывает различия, объемная около тысячи страниц, годная хотя есть некоторые шероховатости, с вопросами, упражнениями и ответами. Читать после K&R или до.
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? у нас в сишечке их гораздо больше, просто они лучше спрятаны, немного байтоебли и непонятно откуда взявшаяся глава про старинные плюсы. Читать в качестве сказки на ночь (на пару вечеров хватит).
Ben Klemens "21st Century C: C Tips from the New School" (2012)
Stephen G. Kochan "Programming in C (3rd Edition или 4th Edition, если найдется)" (2014)
MISRA Ltd. "Guidelines for the Use of the C Language in Critical Systems" (2013)
Набор рекомендаций по написанию надежного кода на C (промышленный стандарт). Читать - однозначно, следовать - вдумчиво и без фанатизма. Также можно посмотреть https://www.securecoding.cert.org/confluence/display/c/SEI+CERT+C+Coding+Standard
Еще более длинный список: http://www.iso-9899.info/wiki/Books#Learning_C
Прошлые треды:
- https://arhivach.org/thread/106153/
- https://arhivach.org/thread/131949/
- https://arhivach.org/thread/140570/
- https://arhivach.org/thread/153698/
- https://arhivach.org/thread/155908/
- https://arhivach.org/thread/173837/
- https://arhivach.org/thread/180461/
- https://arhivach.org/thread/182958/
Шапка: http://piratepad.net/bJ1SdmkZyu