Это копия, сохраненная 28 января 2016 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
Что читать:
- Классика от Отцов: 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: оче годно, батя рекомендует. Дрочим на --analyze.
- Intel C++ Compiler: оптимизации, тысячи их.
- Visual Studio 2015 Community Edition: внезапно этим стало можно пользоваться. Поддержка C11 на уровне "есть все, что тебе понадобится в реальном проекте плюс кривая библиотека" (да, в студию в последнее время завезли stdint и stdbool, почти все новые фишки из C11, static_assert и даже юникод). C snprintf все до сих пор плохо. Анализатор кода в комплекте.
- Pelles C (шиндоуз онли): поучиться, вкатиться в C11 (в частности, потыкать threads.h и stdatomic.h), но количество багов в оптимизаторе и редкие апдейты напрочь отбивают желание собирать этим что-то сколько-нибудь серьезное.
- TCC: очень маленький компилятор с багами и неполной поддержкой C99.
- Borl... ээээ...
Что еще почитать:
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 (4th Edition)" (2014)
Прошлые треды:
- https://arhivach.org/thread/106153/
- https://arhivach.org/thread/131949/
Посоны. Че там ~у хохлов~ в новом стандарте?
Шаблоны завезли? Многопоточность завезли?
Как там вообще?
Завезли еще немного юникода (никто не пользуется), многопоточность (никто не пользуется) и костыль вместо шаблонов (погугли _Generic). Ну и еще немного плюшечек туды и сюды. Как-то так.
Си, по сути, остается таким же незамысловатым процедурным языком, каким он был в семидесятых. Правда, теперь в нем есть ограниченная поддержка модулей, опирающаяся на два ключевых слова: extern и static. Поэтому старые добрые книжки по структурному программированию тебе в помощь.
Шутку про инкремент этому господину.
Надо строить конечное поле Галуа, в котором определены операции над многочленами. Степень расширения не более чем 32 из-за ограничения встроенных типов. Характеристика базового поля равна 2.
Предполагаю, что основой библиотеку будет функция GF(unsigned polynomial), которая возвращает указатель на таблицу индексов на куче. В функции GF надо определить номер старшего бита в переменной polynomial и снять с нее маску. Она нужна для построения таблицы индексов (определение переполнения разрядной сетки).
Для конкретной реализации конечного поля надо где-то хранить базис этого поля и следы базисных элементов. Думаю, что надо завести структуру gf, в которой будет храниться таблица индексов, таблица базисных элементов, таблица следов и, возможно, что-то еще.
Пусть необходимое поле уже построено, и информация о нем хранится в структуре gf. Как при помощи этой структуры выполнять операции над многочленами типа умножения, возведения в степень, нахождения обратного? Если умножением занимается функция gfmul, то как выглядит ее вызов, если многочлены хранятся в таблице индексов? gfmul(gf->index[5], gf->index[11])? Это же ебаный вырвиглаз. Хранить в структуре gf указатели на функции, которые реализуют арифметические операции над многочленами? То есть, если надо умножить два многочлена, которые представляют собой 5-ю и 11-ю степень порождающего многочлена, я могу захотеть сделать это вызовом gf->mul(5, 11). Поэтому функция mul должна как-то уметь находить в gf->index[] 5 и 11 элемент. Причем она объявлена отдельно, но сама является частью структуры gf и должна уметь пользоваться данными из этой структуры. Выглядит как говно.
На чистом си вообще можно написать что-то сложнее вирусов и консольных калькуляторов?
>На чистом си вообще можно написать что-то сложнее вирусов и консольных калькуляторов?
Линукс?
Я имею в виду полезное прикладное ПО, а не говно мамонта. На чем пишутся математические библиотеки? Как люди пердолятся со всем этим говном, не умеющим в архитектуру?
Ондроед на троечке базируется.
В любом случае, это легасиобразное говно мамонта вызванное недостаточным развитием железа.
Блять эти очки, рубашка и причёска. 100 процентый пидораха нахуй. Наверняка преподаёт в каком-нибудь засраном МГУ и втирает про успешность советской науки даже почти наверняка не читал никаких книг кроме советских. А эта улыбка в конец разозлила. Ещё и линукс ему наверно не угодил по вымышленной причине типа пользуйтесь отечественными аналогами.
Зекач такой зекач, как можно не знать Таненбаума?
https://ru.wikipedia.org/wiki/%D0%A2%D0%B0%D0%BD%D0%B5%D0%BD%D0%B1%D0%B0%D1%83%D0%BC,_%D0%AD%D0%BD%D0%B4%D1%80%D1%8E
> Эндрю Таненбаум также признан как автор учебников для высшей школы по некоторым областям информатики и вычислительной техники, в своих областях книги считаются избранными как стандарт, в частности:
> Computer Networks, ISBN 0-13-066102-3
> В переводе: Компьютерные сети, ISBN 5-318-00492-X
> Operating Systems: Design and Implementation, ISBN 0-13-638677-6
> В переводе: Операционные системы: разработка и реализация ISBN 5-469-00148-2
> Modern Operating Systems, ISBN 0-13-031358-0
> В переводе: Современные операционные системы, ISBN 978-5-498-07306-4
> Также написал:
> Structured Computer Organization, ISBN 0-13-148521-0
> В переводе: Архитектура компьютера ISBN 5-469-01274-3
> Distributed Systems: Principles and Paradigms, ISBN 0-13-088893-1
> В переводе: Распределённые системы. Принципы и парадигмы ISBN 5-272-00053-6
> Книга «Операционные системы: разработка и реализация» (англ. Operating System: Design and Implementation) и Minix [1] вдохновили Линуса Торвальдса на создание ядра Linux. В автобиографии Just For Fun Торвальдс описывает её как «книга, которая подняла меня на новую высоту». Впоследствии Таненбаум написал распределённую операционную систему Amoeba, полностью реализующую идею микроядра.
Только вот Linux взлетел, а профессор со своими микроядрами соснул.
> 100 процентый пидораха нахуй. Наверняка преподаёт в каком-нибудь засраном МГУ и втирает про успешность советской науки даже почти наверняка не читал никаких книг кроме советских.
Хотя вообще-то возможно, лол. Вот Вирт к примеру типичный пидорашка, любит рассказывать охуительные истории как американские рептилоиды убили европейскую науку. И СССР ему нравится.
>Вот Вирт к примеру типичный пидорашка, любит рассказывать охуительные истории как американские рептилоиды убили европейскую науку
Покажи
>На чистом си вообще можно написать что-то сложнее вирусов и консольных калькуляторов?
С в этом плане не так сильно отличается от любого ООП языка, ну наследования нет (бери в руки препроцессор), шаблонов (препроцессор), ну вместо this->yoba(x) надо писать yoba(this,x), нет перегрузки операторов (вместо a+b надо писать add(a,b)), исключений (вместо add(a,b) надо писать Result add(T a, T b, Tab_result), и возврата кортежей (Result add(T a, T b, Tab_result, T result2), и буфер надо выделять вне функции (вместо vector = yoba(a) надо писать vector=malloc(...);yoba(a, vector)).
Но так все точно так же, определяешь структуры данных, прячешь имплементацию в .c файл, чтобы наружу торчала только struct yoba;, пишешь конструктор, деструктор, и вперед.
Лекция, когда он приезжал в Россию, ЕМНИП в блоге Алены C++ было видео. О том, какая была передовая система Lilith и язык Oberon, но нам навязали Windows и C++.
add. по c#
Вот смотри более-менее нормальный сишный интерфейс для математики https://github.com/ampl/gsl/blob/master/spmatrix/gsl_spmatrix.h
>юникода (никто не пользуется)
збсь, можно будет запиливать нормальную человеческую интернационализацию в прошивках бытовых приборов.
>многопоточность (никто не пользуется)
збсь, можно будет запилисть реализацию "стандартной" многопоточности на базе BuguRTOS
>костыль вместо шаблонов (погугли _Generic)
спорная хрень, пока не знаю, как применить...
школьник-кун
Проектирование ПО != паттерны конкретного языка.
Как же я проиграл, хоспаде.
>Как люди пердолятся со всем этим говном, не умеющим в архитектуру?
Ебанашка, а как связаны архитектура и язык программирования?
Или ты думаешь, что аррхтектура, это когда ООП искаропки?
Тогда у меня для тебя плохие новости!
vim
2. Обнуляет в переменной Code биты по маске SET_IOCTL.
Тильда - побитовое не.
& - побитовый and. То есть
0110101 &
1100110 =
0100100
~ - побитовый not:
~101010111
=010101000
a &= b - краткая запись a=a&b
emacs
fgets(str, 128, stdin);
и использую strcat, например
strcat(str, str1);
он строки объединяет с переносом т.е. выводить будет не
"строка1строка2" а
"строка1
строка2"
а если использую gets(str);
тогда все нормально.
В чем подвох?
Сега прилипла
Пайк, залогиньтесь.
Алсо не используй gets, ты ему не можешь указать размер буфера и может быть buffer overflow.
Ну идея в том, чтобы \n заменить на \0.
[code lang="c"]
char str1 = "world";
char buf[128 + strlen(str1)];
fgets(buf, 128, stdin);
char pos = strchr(buf, '\n');
if (pos != NULL) *pos = '\0';
strcat(buf, str1);
printf("%s\n", buf);
[/code]
Светофор у меня будет работать по таймеру
Класс авто будет иметь функции передвижения и остановки.
Как проверять значение светофора? как проверять свободна ли полоса для поворота?
Как связать передвижение авто и светофор?
Я в этой теме ньюбас, так что остудите горящие пуканы пжалста.
Ну там потоки, семафоры, мьютексы... Вот это вот всё.
Я б перекресток как граф рассматривал, вершина графа - собственно полоса. Например с правой можно прямо (в идеале не меняя полосы, но можно) и направо только в крайнюю полосу, с центральной только прямо (опять же в свою полосу), с левой только налево в любую полосу (например). Быдлорежим "с левой полосы направо ты тачку мою видел еп" пока не рассматриваем.
В простейшем случае если на ребре графа есть машина, остальные "не занимают" перекресток и стоят за стоп линией, даже если на действие в данной полосе зеленый свет, если посложнее - посчитать, сколько машин вместит одно ребро графа (длина ребра/(длина машины+стандартная дистанция между машинами).
Как-то так, вот такие идеи. По идее рисовать надо, но ломак.
Можно просто считывать scanf("%s", &str); и через цикл выводить?
У меня к тебе вопросы.
1)Что значит size_t
2)Что значит asprintf и snprintf
3)Что значит putchar
size_t - это беззнаковый целый тип. Ну типа натуральное число. Я бы мог еще добавить, что он имеет разрядность, достаточную для хранения указателей, но лучше не буду. В принципе, можешь заменить size_t на unsigned int. В большинстве случаев эти типы совпадают.
asprintf - форматированный вывод в строку. Память под результирующую строку выделяется автоматически. Ты даешь этой функции неинициализированный указатель на строку, а она сама выделит памяти столько, сколько нужно. Эта функция является расширением GNU и не входит в стандарт.
snprintf - почти тоже самое, но есть два нюанса. Память под результирующую строку должна быть выделена заранее (хоть на стеке, хоть в куче, хоть в статической памяти). Функция считывает не более n символов, включая завершающий нуль (n передается в качестве второго аргумента). Есть еще sprintf, но я бы не советовал, ибо она не контролирует количество считываемых символов. snprintf входит в стандарт C99.
putchar - вывод одного символа.
> Я бы мог еще добавить, что он имеет разрядность, достаточную для хранения указателей
Правильнее сказать, что он имеет разрядность, достаточную для хранения размера любого объекта (т.е, для хранения результата sizeof). Размер указателя теоретически может быть как меньше, так и больше размера size_t.
>>613485
> вариант рабов Стандарта
В случае отсутствия asprintf, она реализуется буквально тремя строками. Хорошая, удобная функция, как и strdup, которой тоже в стандарте нет. А вот хранить в size_t что-то, не являющееся размером, количеством или индексом - моветон.
>Правильнее сказать, что он имеет разрядность, достаточную для хранения размера любого объекта
Точно. Спасибо. Это я с D уже путаю. Там по спецификации: size_t is an alias to one of the unsigned integral basic types, and represents a type that is large enough to represent an offset into all addressible memory.
>В случае отсутствия asprintf, она реализуется буквально тремя строками.
Если человек спрашивает, что такое putchar, врядли стоит грузить его такими вещами.
>моветон
В данном случае некритично, я считаю.
>>613526
Потому, что тупо пишется короче. Можно, конечно, взять какой-нибудь uint32_t, но это же дополнительный хедер подключать надо.
> Если человек спрашивает, что такое putchar, врядли стоит грузить его такими вещами.
Врать не стану, но про asprintf и snprintf я не очень понял.
Как я понял то что они динамически выделяют память. Ты даешь указатель на строку, а она выделит сама столько сколько надо. Но для чего это используется я не понимаю я до конца не понимаю.
Все, все стало понятно.
Если будут не цифры, а символы, то тогда
len = asprintf(&s1, "%c", str);
Или нет?
Да, забыл еще кое-что. Если ипользуешь asprintf, то потом выделенную память желательно освободить. Обрпти внимание на строки 2 и 22.
Освобождаем чтобы потом можно было повторно использовать s1, ну и чтобы не грузило так сказать?
Вот смотри. Есть функция printf. Она принимает формат и список переменных/констант для вывода. Функция выводит все указанные переменные и/или константы на стандартный вывод (чаще всего в консоль) в соответсвии с форматом. То есть, она все конвертирует в строку.
Функция asprintf делает тоже самое. Только она сконвертированные данные сохраняет в строку, а не выводит в консоль.
>>613565
Да. Чтобы не было утечки памяти.
Если тебе уже не нужна строка, сохраненная в s1, то чтобы использовать s1 для хранения другой строки, память надо освободить. Если ты просто вызовешь asprintf второй раз для s1, то функция просто выделит новую память и запишет указатель на новый блок память в эту переменную, но прежняя строка так и останется "висеть в воздухе".
Изобразил вот схематично. Может быть, так будет понятнее.
Кстати, если тебе это задание дал препод, то мне кажется, он может не принять вариант решения с использованием библиотечной функции. Так что, на всякий случай, иди вот сюда: https://ru.wikipedia.org/wiki/Itoa_%28%D0%A1%D0%B8%29 и списывай реализацию Кернигана и Ричи.
Неужто в си пытаются вкатиться подобные тупорылые долбаебы котрым на пальцах нужно разжевывать ручное управление памятью.
Мимо жаба-примат
Дело в том, что многие вкатываются не по своей воле, а по воле преподов, которые дают такие задания до того, как объяснять что-то про управление памятью. Типа, вот я вам рассказал как объявлять переменные и делать условия/циклы. Вперед! Выполняйте задание. Для некоторых изучение Си - необходимость, которая отнюдь не вселяет в них желание побольше узнать о языке и уж точно не прибавляет энтузиазма для изучения по этой теме чего-то большего, чем рассказывают на занятиях.
Да не, никто не давал.
Хуй знает.
15 лет назад когда мне на 2 курсе преподавали теорию операционных систем, то на сях там был минимум и почти сразу перекатились на кресты.
Жаба-примат.
Так у тебя же 1234567 изначально является строкой, а не числом. Ты просто ее читаешь с клавиатуры и вставляешь пробелы между символами.
Алсо, strlen лучше вынести за цикл.
А что в этом плохого? Наоборот же, решение более универсальное.
Так ты имел ввиду? А почему так лучше?
Изначальное условие было такое: дано натуральное число. Я это понял как то, что у нас есть двоичное представление этого числа, а не строковое. Но если тебя устраивает строковое представление, то можно и так, если тебя не смущает, что программа фактически работает со строками, а не с числами.
>А почему так лучше?
Потому что семантически это означает, что функция strlen должна вызываться на каждом проходе цикла. А естри strlen вынесена за цикл, то и вызываться будет только один раз. У тебя ведь длина строки не меняется по ходу цикла. Так зачем делать одну и ту же бесполезную работу на каждой итерации? Сейчас считается, что большиснтво компиляторов самостоятельно оптимизирует такие вещи. Тем не менее, в данном случае, вынесение функции за цикл выглядит более логично и является примером хорошего стиля. Причем это не я придумал. Можешь Криса Касперски почитать, например (серия статей "Сишные трюки").
За 15 лет общее число программистов увеличилось сильнее, чем число хороших, поэтому если раньше дегенератов было 10%, то сейчас 75.
Подскажите какие-нибудь тесты порешать.
Сложнее -лучше.
Наподобии этого.
> "Си: грязные истории"
Это такая тонкота или одно из двух? Поисковики находят только этот тред, а хочется почитать.
http://pastebin.com/p4m2Sg6i
Выдает ошибку сегментирования.
Нет. Они могут и в регистрах быть. Вообще сишечку создавали в качестве абстрактного ассемблера, где намеренно замалчивается конкретная реализация регистров и памяти.
Это толстота. Оно на английском http://btdigg.org/search?info_hash=&q=Expert+C+Programming.+Deep+C+Secrets
>>613990
Собираешь с отладочной информацией (gcc -g), пускаешь под gdb, оно говорит, где ты соснул. Ты рассказываешь нам, и мы разбираем проблему.
Но вообще, тебе нужно выделять каждому потоку свой ip, и пробрасывать его через pthread_create если уж ты каждому подключению отдельный тред выделяешь. Алсо, адрес весьма просто инкрементируется одним циклом, а не этим безобразием.
У тебя ip = NULL, туда пишет sprintf, это нормально? Алсо, после создания потока туда снова пишет sprintf, хотя поток мог еще не успеть воспользоваться значением из буфера.
Да в принципе хуй с ним. Спасибо за помощь, пацаны. Напишу на масме, это быстрее, чем ебаться с сишкой.
Нихуя не быстрее. Пофикси еще переменные i, j, u, y, их никто за тебя нулем инициализировать не будет.
Еще как быстрее. Сейчас увидишь.
Хули там, wsa стартуешь, инкрементируешь ecx и через ustr$ переводишь в текст, потом добавляешь в пременную, добавляешь точку и еще так 4 раза, потом обновляешь и все ок. В поток отправляешь всю хуйню, тот быстро копирует и все. Ну короче элементарно бля. Там ебли намного меньше, чем с сишкой.
кстати зря многие говорят, что масм - язык низкого уровня. он высокоуровневый, как и другие языки ассемблера. Более высокоуровневый fasm, но мне масм больше нравится
Кто тебе мешает абсолютно то же сделать на Си?
for (uint32_t v4addr = 0x7f000001; v4addr < 0x7fffffff; ++v4addr) {
_beginthread(scan_port, 0 (LPVOID) htonl(v4addr));
}
int scan_port(LPVOID arg) {
SOCKADDR_IN sa;
sa.sin_port = htons(12345);
sa.sin_addr.s_addr = (ULONG) param;
socket();
connect();
}
Говнокод, но суть понятна.
Вот мое решение, но оно не верное. И не до конца правильное в плане поставленного условия.
Это ты уходи, он и в Си может.
Да что вы вспоминаете срач более чем 20-летней давности! Сам Таненбаум с тех не критикует линуксы. Линуксы с давних пор уже не монолитные, а по большей части модульные. Да и с микроядрами он не соснул, так как сделал надежную ОС (правда для учебных целей и встроенных систем). Просто данную идею сложно реализовать, так как найдется немного людей, которые будут создавать с нуля ОС, опираясь на архитектуру.
Почитай об указателях. Попробуй сам попрактиковать. А то, что на пике - абсолютно бессмысленное дерьмо. Ярчайший пример говнокода. Такое вряд ли часто пишут. Но хорошо понимая логику работы с памятью и собственно сами указатели, даже это можно понять за пару минут.
Есть один проект и этот проект писан под линуксы с использованием пары либ, в т.ч. libusb. Взял я значит его, сунул в проект кодблоксов под виндами, скачал прекомпиленные mingw либы, положил рядом, настроил в кодблоксах опции сборки (build options -> search directories -> compiler/linker, сунув туда, соответственно пути к директориям include и lib библиотек). И соснул большого, получив целый ворох undefined reference'ов, например:
> undefined reference to `libusb_get_bus_number
Что я сделал не так, кроме использования виндов? Дайте советов мудрых. В гоголе, стеке и прочем уже искал.
> сунув туда, соответственно пути к директориям include и lib библиотек
Так же, как инклуды нужно использовать в исходнике, так и используемые либы нужно явно указать линкеру, а не только место, где их искать. В командной строке ты можешь сделать -lusb, поищи подобное в Code::Blocks.
Понял, разобрался, помогло. Большое спасибо, анон!
#include "test.h"
[/code]
Есть строка вида 12345,6789,x,0123,"xyi, pizda",333,"333-33",,,,"",,,"",0,98,"",,,, ну и так далее.
Нужно вытаскивать строки между запятыми и кавычками(если они есть) для дальнейшего использования. Реализовать это получилось в теле main, а в отдельную функцию, возвращающую очередную строку между запятыми не получается: вылезает ошибка сегментации. Причём первые строки вытаскиваются и возвращаются нормально, а вот последняя вообще никак.
Сама функция:
char NextstrField(char buf, int posbuf)
{
char str=NULL;
if (!(str=(char)malloc(sizeof(char)BUF_SIZE))){
printf("Out of memory\n");
system("pause");
exit(-1);
}
int i;
unsigned short QwoteActive=0;
for (i=0,memset(str,0,sizeof(str));i<445;++i,(posbuf)++){
if (buf[(posbuf)]=='"'){ // если встречается кавычка
(posbuf)++;
if (QwoteActive) QwoteActive=0;
else {
if (buf[(posbuf)]=='"') break;
QwoteActive=1;
}
}
if ((str=buf[(posbuf)])==',' && !QwoteActive || buf[(posbuf)]==0x0A || buf[(*posbuf)]==0x00){
str='\0';
break;
}
}
return str;
}
Кусок кода в main:
for (posbuf=0;str1[posbuf]!=0;posbuf++){
if (str1[posbuf]=='\0' || str1[posbuf]=='\n') break;
str2=NextstrField(str1,&posbuf);
puts(str2);
}
Есть строка вида 12345,6789,x,0123,"xyi, pizda",333,"333-33",,,,"",,,"",0,98,"",,,, ну и так далее.
Нужно вытаскивать строки между запятыми и кавычками(если они есть) для дальнейшего использования. Реализовать это получилось в теле main, а в отдельную функцию, возвращающую очередную строку между запятыми не получается: вылезает ошибка сегментации. Причём первые строки вытаскиваются и возвращаются нормально, а вот последняя вообще никак.
Сама функция:
char NextstrField(char buf, int posbuf)
{
char str=NULL;
if (!(str=(char)malloc(sizeof(char)BUF_SIZE))){
printf("Out of memory\n");
system("pause");
exit(-1);
}
int i;
unsigned short QwoteActive=0;
for (i=0,memset(str,0,sizeof(str));i<445;++i,(posbuf)++){
if (buf[(posbuf)]=='"'){ // если встречается кавычка
(posbuf)++;
if (QwoteActive) QwoteActive=0;
else {
if (buf[(posbuf)]=='"') break;
QwoteActive=1;
}
}
if ((str=buf[(posbuf)])==',' && !QwoteActive || buf[(posbuf)]==0x0A || buf[(*posbuf)]==0x00){
str='\0';
break;
}
}
return str;
}
Кусок кода в main:
for (posbuf=0;str1[posbuf]!=0;posbuf++){
if (str1[posbuf]=='\0' || str1[posbuf]=='\n') break;
str2=NextstrField(str1,&posbuf);
puts(str2);
}
Ситуация следующая.
Есть функция, в которой создается массив типа char - db и массив указателей на char, указывающие на каждое отдельное слово в db. В первом цикле определяется длина текущего слова strlen(ptr_arr+i) и прибавляется к l - общей длине массива db. В db передается строка: "1;qwe;asd;zxc;2;cvb xc vbc;1823;12;3;m". strtok выделяет лексему в соответствии с разделителями(';' и '\n'), следующая инструкция находит длину l. Ну, и суть, собсно, проблемы: во время трассировки на нулевой итерации внешнего цикла вместо, ожидаемого мной l=2, я, сука, получаю l=4!! Где моя ошибка, подскажи Анон? На пикче код и отладчик. ( использование средств языка весьма ограничено, не обращайте внимание на реализацию )
В ДНК, очевидно же!
l = l+... вместо l+=...
*(ptr_arr+i) вместо ptr_arr
Входные данные у тебя не
"1;qwe.." a "1\0qwe...".
И самое главное:
ptr_arr + i это указатель на указаель на строку, а не указатель на строгу, уебок, блядь.
Когда ты ptr_arr + i его передаешь в strlen, strlen считает "длину указателя", ВНЕЗАПНО оказывается, что это там 4 ненулевых байта подряд...
школьник-кун
ptr_ar должен быть с кватратными скобками, но движок их захавал, бида-пичать!
Передо мной стоит такая задача: принять по UART несколько пакетов, описание протокола есть, осталось понять, как эффективнее это сделать.
Когда приходит байт - вызывается прерывание.
Как более эффективно складывать в буфер байты и далее находить в нем пакеты?
Вижу 2 варианта, поясните за плюсы и минусы:
1. Кольцевой буфер, вот такой вариант: http://microsin.ru/content/view/1098/44/
как только в нём появится новые данные, в главном цикле забираю байт, прогоняю через конечный автомат, который ищет начало пакета, данные и конец пакета.
2. Кольцевой буфер, который работает так: если массив заполнился, смещает в цикле все элементы буфера (цикл в том же прерывании выполняется), добавляет ноль в конец массива.
Далее можно уже в главном цикле при помощи привычных функций из string.h и stdio.h найти пакет и т.д.
Вот тут походу минус в том, что в прерывании крутится цикл.
>2. ...
Допустим ищешь ты пакет в главном цикле, работает какой-нибудь scanf и тут БАЦ! приходит новый байт и весь буфер смещается на один элемент.
Что случится?
>Как более эффективно складывать в буфер байты и далее находить в нем пакеты?
Конечным автоматом.
> смещает в цикле все элементы буфера
Каким образом? Копированием? Чем это лучше простого сдвига указателя в случае кольцевого буфера? Хуита какая-то.
Какого типа протокол?
Запрос-ответ, или потоковый асинхронный?
Вообще-то оба твои варианта- сорта говна, причём второй полное ровно, а первый может не подойти для протоколов типа запрос-ответ.
>Каким образом? Копированием? Чем это лучше простого сдвига указателя в случае кольцевого буфера? Хуита какая-то.
Да, копированием.
>Конечным автоматом.
Это хорошо.
>Какого типа протокол?
>Запрос-ответ, или потоковый асинхронный?
Потоковый асинхронный.
На некоторые пакеты надо отправить что-то в ответ.
В основном только принимаю.
Да, DMA есть.
Сейчас вот смотрел про DMA: в циклическом режиме заполняет половину буфера, генерируется прерывание, далее заполняется вторая половина и генерируется прерывание.
Т.е. мне надо поставить флаги в прерывании, что типа пора обрабатывать, в главном цикле запустить обработку, при помощи конечного автомата?
Зависит от железки, протокола и требуемого размера буфера, вестимо. Если тебе не лень реализовывать FSM - делай на кольцевом буфере, будет быстро и красиво. Если лень - делай это свое копирование, будет медленно и понятно.
У меня протокол не сложный, с FSM не заебусь.
Вариант с копированием я увидел у одного старого погромиста с опытом, думал - во как красиво то сделано.
Оказалось, что сделано максимум хуево.
Тогда делай кольцевой буфер с DMA, если там есть регистр с текущим адресом, то на прерывания можно забить: в главном цикле смотришь, разницу между текущим и прошлым значением регистра, - разбираешь соотв. число байт, разбирать лучше всего автоматом.
Для ответов сделай пинг-понг буферизацию через DMA, один пакет отправляется, - второй пишется в свободный буфер, дальше меняешь буфера местами.
Для пинг-понга можно заюзать прерывания
>в главном цикле смотришь, разницу между текущим и прошлым значением регистра, - разбираешь соотв. число байт, разбирать лучше всего автоматом.
Классный подход, мне нравится.
Это типовое решение тащемта.
У меня так один знакомый хекс-файлы в бутлоадере разбирал.
школьник-кун
К сожалению нет. Но что-то там произошло, да.
char F(char s1,char s2)
{
/ тут делаем что-то со строкой s2, используя s1, при этом s1 не изменяется, а s2 - да /
возвращаем s2;
}
int main()
{
/ где-то тут выделяем память для s1 и s2 */
s2=F(s1,s2);
}
Просто мне хочется, чтобы возвращалась именно строка, а не через void. Терзают сомнения, что может что-то случиться плохое.
Что за нах, куда потерялись звёздочки.
можно, но дизайн хуевый получился
Если ты возвращаешь s2, то можно не принимать его в качестве аргумента. Конечно же в случае, если s2 полностью выводится из s1 (допустим измененная копия строки). Ты просто можешь вернуть указатель на s2 без выделения памяти для нее в функции main, выделив ее в F(char \*s1).
char \F(char \s1)
{
/ объявляем и выделяем память под s2
/ тут делаем что-то со строкой s2, используя s1, при этом s1 не изменяется /
возвращаем указатель на s2;
}
int main()
{
/объявляем s2
/ где-то тут выделяем память для s1 и заполняем ее чем-то */
s2 = F(s1);
}
Как-то так.
Может тебе еще программу сделать, которая за тебя пишет код и рассказывает охуительные истории?
>Ищу книгу по С, не такую нудную, как K&R
>но и не такую объемную, как у Прата.
Не осилил или слишком скучно, тогда программирование - это явно не твое.
>Желательно коротенькую, описывающую актуальные методы с примерами.
https://learnxinyminutes.com/docs/c/
>>617722
Двачую. Ньюфаги совсем охуели. Я K&R в десятом классе читал и мне было интересно. Особенно задания выполнять.
Вообще Си уютный язык. И ламповый.
К сожалению программирование меня всё больше и больше печалит засильем скриптовых языков, которые порождают такие программы как Firefox, при открытии с пустой вкладкой сжирающий 350 мегабайт оперативки. И всех всё устраивает: докупим ещё планочку на 8 гигов оперативы и норм.
Может я старею, но меня всё больше тянет на что-то старое доброе, чем на ту парашу, которую остервенело клепают обезумевшие рынки, которым кровь из носу нужно расти каждый год.
На неё ссылались некоторые источники, хотелось бы ознакомиться.
Я модифицирую игру для PS1, приходится ковырять экзешники, читая много mips кода. А игры писались на сишечке, хотел упростить себе жизнь.
Замени её «Архитектурой компьютера» Эндрю Таненбаума.
Ничего особенного там скорее всего нет, кроме оптимизаций, т.е. рассказа о том, что вычислительные действия вроде:
A + B + X + Y
могут быть выполнены не за три команды, а за две, как:
(A + B) + (X + Y)
где действия в скобках займут один такт процессора, и сложение между скобками займёт ещё один такт, MIPS это умеет.
Похожим образом ускоряются и операторы условия, т.к. процессор вместо флажков состояния ("conditional
flags") использует обыкновенные регистры.
Взято из книги «Understanding and Writing Compilers», Richard Bornat.
А где мне задавать вопросы? Ну, понимаешь, это такая сфера деятельности, где некоторые ответы можно вечность искать. Живого ассемблер треда нет, а самостоятельно понять "какой код на си мог при компиляции привести к ЭТОМУ" я не всегда могу.
Как я его оживлю, если я не могу отвечать, а могу только спрашивать? Вернее, я уже и отвечать могу, но вопросы никто не задаст моего низкого уровня, ибо людей нет в сфере.
Согласен. Я хоть не профессионал, но на Си, как любителю мне очень нравится писать. Все прозрачно, как напишешь так и будет. Теория заключается в понимании работы железа. Можно написать абсолютно все, что пожелаешь. Радует, что замену сишечке так и не нашли.
>Firefox, при открытии с пустой вкладкой сжирающий 350 мегабайт
У меня съедает примерно 90Мб на старте(это под линем). Что я делаю не так?
>которую остервенело клепают обезумевшие рынки, которым кровь из носу нужно расти каждый год.
Нужны же ИННОВАЦИИ!!! Даже если эти инновации представляют из себя пропиаренную переделку уже давно известной технологии.
Во вы два долбоеба. Работобыдло из офисов повывалило, видимо.
>>617448
>можешь вернуть указатель на s2 без выделения памяти для нее в функции main, выделив ее в F
Всё-таки мне этот момент непонятен. Если я возвращаю указатель из функции, программа крашится. Там же неизвестно что хранится по адресу, после завершения функции? Получается, нужно объявлять в самой функции как static или что?
Ой, нет всё нормально. Крашится, когда функция void, а не char* и в неё же я передавал указатель на строку и выделял там память.
>Там же неизвестно что хранится по адресу, после завершения функции?
Известно. Функция возвращает указатель на участок памяти, с которым ты работал. При завершении работы, функция самостоятельно не освобождает память.
>Получается, нужно объявлять в самой функции как static или что?
static необходим только для того, что значение переменной, отмеченной как static, сохранялось до следующего вызова функции. Как просто пример использования static, можно взять подсчет количества вызовов этой самой функции.
> просто отправлять строку в которой различные поля разделены при помощи \r\n
Да.
> библиотеки
Ну curl же.
Благодарю.
С совершенно произвольными данными ничего не сделаешь. Рассказывай подробнее, что сделать надо.
Стандарт запрещает любые подобные выебоны (в том числе и >>619969 union). Чтобы все было пиздец как кроссплатформенно, нужно читать побайтово и вручную собирать многобайтовые типы (сдвигами и т. д., что особенно весело для какого-нибудь double).
Если ты нормальный человек, то указатели вполне ок, озаботься только выравниванием и endianess - будет достаточно переносимо.
>>620075
Советую взять любой понравившийся ассемблер (nasm, fasm), писать ассемблерный код отдельным модулем (файлом) и потом линковать к основной программе. Когда ты осознаешь, что код на ассемблере можно заменить интринсиками, проще будет его найти и переписать.
Алсо, в tcc дохуя неисправленных багов и напрочь отсутствующий оптимизатор. Единственное, за что его следует любить и уважать, так это за -run.
> нужно читать побайтово и вручную собирать многобайтовые типы
Это как раз то, что я и имел ввиду.
> то указатели вполне ок,
А это как раз то, что я хотел сделать.
Спасибо за ответ.
>Алсо, в tcc дохуя неисправленных багов и напрочь отсутствующий оптимизатор. Единственное, за что его следует любить и уважать, так это за -run.
Тогда посоветуй еще какой-нибудь компактный компилятор, который генерировал бы маленькие экзешники. Хеллоуворлд, скомпилированный tcc, весит всего 2.5 кб, почти как на ассемблере. Другие компиляторы даже с оптимизациями меньше 25 кб не генерят.
>Другие компиляторы даже с оптимизациями меньше 25 кб не генерят.
$ clang -O3 helloworld.c -o helloworld && du --apparent-size -b helloworld
6600 helloworld
$ gcc -O3 helloworld.c -o helloworld && du --apparent-size -b helloworld
6720 helloworld
>почти как на ассемблере
$ clang -O3 helloworld.s -o helloworld && du --apparent-size -b helloworld
6568 helloworld
$ gcc -O3 helloworld.s -o helloworld && du --apparent-size -b helloworld
6704 helloworld
Ты ведь понимаешь что эти 6 кб это всякие таблицы релокаций и прочая ELF-хуйня? От нее не избавишься.
А впрочем можно вот так сделать.
$ clang -O3 helloworld.c -nostdlib -lc -o helloworld && du --apparent-size -b helloworld
3424 helloworld
$ cat helloworld.c
#include <stdio.h>
#include <stdlib.h>
void _start(void)
{
printf("Hello, World!\n");
exit(0);
}
tcc просто динамическая линкуется к рантайму. Рантайм в Windows весит 400 КБ (используется древняя MSVCRT.DLL, что само по себе плохо).
Можно взять Pelles C из шапки, с -MD он тоже сгенерит 2 КБ плюс 300 КБ рантайм (если статически линковать рантайм, будет что-то около 30 КБ минимум) . Можно взять Visual C++, он генерирует 4.5 КБ плюс рантайм (со статической линковкой 50 КБ). А можно перестать загоняться по поводу размера файла.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void print(void);
int i;
int main(void)
{
char buff = malloc(1000);
pthread_t t[2];
pthread_create(t[1], NULL,(void ()(void )) print, NULL);
pthread_create(t[2],NULL,(void ()(void ))print,NULL);
}
void print(void)
{
i++;
printf("huyhuyhuy\n %d", i);
}
//ну кроме того, что с типом функции объебался. Ну похуй. Это насрать. Компилируется без ошибок и прочей хуйни. У меня в принципе ни одна программа скомпилированная не запускается. Я писал сканнер портов и нихуя. Написал другой. опять нихуя. Включил kdbg и там у меня показывает ошибку сегментации ДО входа в майн. Что за нахуй?
Компилирую gcc -pthread [sourcename].c
>>620288
Можно дос стаб удалить и будет еще меньше. А так да. я под венду пишу на масме, потому что ебал я писать на сишке там. У меня там MessageBox по 64кб выходит. Я помнится, писал под DOS когда-то, так с тех пор я вообще каждый байт блядь пытаюсь сэкономить. Даже в сишке ассемблерными вставками пользуюсь. Вообще, используй __imp_MessageBoxA@16 и не еби себе мозг. Хотя лучше, конечно, пиши на масме под венду. Под прыщами на нем не попишешь.
Абу просто жабогосподин. Вот и режет указатели. Ибо нехуй.
https://ideone.com/VWF7Ln
int strcmp(char s, char t){
\twhile(s++ == t++)
В цикле while указатели убери. У тебя это итак указатели. Ты просто адрес инкрементируй, а не то, что находится в указателе, киса.
>>620324
Долбоеб. 16 - это кол-во байт передаваемых в MessageBoxA(dword hwnd, dword capture, dword text, dword status(или как там)); дебильный блядь.
А ты думал это под дос, сука, мессадж бокс блядь? Охуеть не встать. Иди блядь мсдн читай, уебок.
Потому что внутри while и s, и t уже инкрементировались и указывают на следующий символ. Ты, кстати, хуйней какой-то занимаешься, нормальные компиляторы все равно обнаруживают эти паттерны и заменяют на вызовы библиотечных функций (которые быстрее потому что реализованы через sse.)
Да мне просто интересно писать говно.
>Иди блядь мсдн читай, уебок.
А оно мне надо?
>кол-во байт передаваемых
>2016
>x86-64
>не передавать аргументы через регистры
>MessageBoxA
>A
Кто тебе сказал, что через регистры, уебок? А ты не слышал о том, что можно передавать адрес операнда, который находится в переменной? Ты не слышал про макро среду языков ассемблера различных? Не? И если что в таблице экспорта именно так обозначается все. Ебать ты даун, хуево быть тобой. Не надо ему мсдн читать, бля. Охуеть не встать, с какими ебланами я на борде сижу.
>Почему я долбоеб?
Тебе все перечислить?
1. Не проверяешь возвращенный malloc-ом результат на NULL.
2. Не освобождаешь память.
3. А нахуя ты ее вообще выделил-то?
4. Массив t не инициализирован перед использованием, привет undefined behavior.
5. Первый аргумент pthread_create - не просто какой-то произвольный указатель. По этому указателю будет записан ид созданного потока. Собственно, у тебя падает как раз потому что этот ид записывается в рандомное место памяти.
6. print кастуется к несовместимоу типу.
7. После создания потока его надо где-то либо join-ить, либо detach-ить.
8. main должна возвращать int, но return нигде не видно.
9. print неправильного типа - она не принимает аргументов, а должна принимать один типа "указатель на void".
10. i не атомарная, поэтому в i++ возникает race condition между потоками.
11. print должна возвращать указатель на void, но return опять нигде нет.
12. Компилируй gcc -Wall -Wextra -Werror -pthread yoba.c -o yoba, тогда гцц тебе сразу все это укажет.
>Кто тебе сказал, что через регистры, уебок?
Я и говорю, какой мудак в 2016 на 64-битном хуе86 передает не через них? Шиндовсбляди, видимо.
>А ты не слышал о том, что можно передавать адрес операнда, который находится в переменной?
Это тут вообще при чем?
>Ты не слышал про макро среду языков ассемблера различных?
Ты не слышал про си?
А, еще i не инициализирована.
Ты не углядел главное - t[2] - это вне массива.
> Шиндовсбляди, видимо.
Ты не поверишь, но 64-битный fastcall в шинду завезли точно такой же.
>64-битный fastcall
Во-первых он называется System V ABI.
Во-вторых в шиндовсе опять свой стандарт. Он, кстати, довольно интересный - первые 4 аргумента передаются через регистры, но 32 байта на стеке под них все равно выделить надо (но не надо заполнять), причем даже если функция принимает меньше 4 аргументов. Остальные аргументы идут над этими 32 байтами.
22 - стек разве позволяет взять такой огромный размер.
Дальше лень смотреть. Говнокод я лютый вижу здесь.
мимокрок
>ЧЯДНТ?
>pthread_t t[0x7fffffff]
http://ideone.com/rQVWum
Дальше не читал, хуйня полная написана.
> pthread_t t[0x7fffffff];
Всегда так делаю.
> ЧЯДНТ
Не прочитал ничего про многопоточное программирование. Например, у address все шансы затереться раньше, чем поток им воспользуется. И я тебе уже об этом писал в середине треда.
>Не проверяешь возвращенный malloc-ом результат на NULL
Боишься, что на твоем калькуляторе не хватит памяти для выделения?
Про квоты слышал когда-нибудь?
А если требуется брать много памяти, а система и так загружена? Будто что-то плохое, предусмотреть такую ситуацию. Тем более, она вполне реальна.
> предусмотреть такую ситуацию
И свалиться не просто, а успев выругаться в консолечку. Потому что в программе серьезнее хелловорлда выругаться в логи может не получиться, и показать уведомление может не получиться, и даже завершиться красиво может не получиться. Поэтому если программа не сервис, мелкие аллокации проще всего вообще не проверять и в том редком случае, когда память кончится, просто свалиться.
Спрашивающий - новичок. Он не может в неблокирующие сокеты. И в сырые сокеты тем более не может.
>Потому что в программе серьезнее хелловорлда выругаться в логи может не получиться, и показать уведомление может не получиться, и даже завершиться красиво может не получиться.
А может и получиться. Гвидон вон вполне нормально бросает MemoryError в таких случаях.
Да и сваливаться ведь не обязательно. Иногда же бывают случаи, когда невозможность выделения памяти не является критической ошибкой. В таком случае, можно просто залочить возможность на некоторое время или же просто выделить меньше памяти, если это возможно.
У тебя же есть реализованный strlen
if (strlen(s)<strlen(t)) return -1;
if (strlen(s)>strlen(t)) return 1;
if (strlen(s)==strlen(t)) return 0;
Ну тогда хуй с ним
Поясни-ка мне за сокеты. Почему select возвращает 1, а данных для чтения нет?
FD_ZERO(&check);
FD_SET(Socket, &check);
if (select(0, &check, 0, 0, &timeout) > 0)
{
ioctlsocket(bind_socket, FIONREAD, &read_byte); // != SOCKET_ERROR
}
Почему read_byte == 0? WSAGetLastError() возвращает 0.
Сижу, обзавшийся своим же говном. Извините
И что там нового для меня? Возвращается 1, а данных нет. По таймауту не отваливается.
Открыл страницу в man'e и понял уже. Прошу прощения за столь глупый вопрос.
В древней опере тестирую, всё почти нормально. Хотя бы первый запрос обработать получается, а keep-alive по таймауту завершаю. А с хромом ни в какую. Он пересоздаёт подключение, запрашивает одну страницу, а остальные отваливаются на select с нулём байт и не срабатывает таймаут.
Сам нашел. Обычно шрифт можно было с клавиатуры увеличивать, а тут никак.
>Не освобождаешь память.
Если память используется на протяжении всей работы программы, какой смысл её освобождать по завершении программы? Она будет автоматически освобождена операционной системой.
>Если память используется на протяжении всей работы программы
Как часто такое бывает? Если маленькое приложение, ладно. Но вообще, всегда рекомендуется это делать явно для обеспечения все той же переносимости. Да и разве сложно сделать это?
> нет больше данных
Да, например если удаленный хост закрыл соединение (сделал shutdown(..., SD_SEND)), по TCP уйдет FIN, select на другой стороне прервется, а в сокете будет 0 байтов.
Может быть, у тебя в реализации протокола проблемы, и оно просто не хочет с тобой разговаривать?
>>620450
Да, именно так. Если не нравится, можешь сделать общий хедер и инвертировать в нем условие (#ifndef DEBUG #define NDEBUG ... #endif). И потом собирать с -DDEBUG, а релиз без.
Ну а оставлять ли ассерты в релизах - дело твое. Только не используй их по назначению - для проверки соблюдения контракта, а не вместо обработки ошибок.
>>620553
Такое бывает часто, в любой мелкоутилитке. При нормальном выходе рантайм обязан сделать и flush файлам, и закрыть их потом, и память освободить.
>сырые сокеты
А они разве нужны для сканера портов? Если я не ошибаюсь, сырые сокеты просто позволяют тебе собрать свой пакет, со своими параметрами, не прибегая к помощи ядра. А для сканера портов не будет достаточно, просто слать TCP и/или UDP пакеты и просто ждать ответа? Или есть нюансы?
Существует несколько способов сканирования. Полноценная установка соединения - самый медленный из них.
Ладно. Попробую почитать на досуге подробнее о сырых сокетах. Пока мне на голову приходит только: 1) отправить SYN; 2) дождаться SYN/ACK; 3) перейти к следующему порту, не отправляя ACK.
Да, именно так. Только желательно на SYN/ACK отвечать RST, чтобы все были счастливы а то мало ли, хост решит, что это у тебя SYN flood такой и обидится. Алсо, у нас тут тредик про сишечку. А про хакеров где-то рядом тонет.
У штульманавта пригорело?
apt-get source <ftp-client-name> если линукс.
Если windows, гугли свободные ftp-клиенты, заходи на официальный сайт и качай исходники.
https://ru.wikipedia.org/wiki/%D0%9A%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D1%8F:%D0%A1%D0%B2%D0%BE%D0%B1%D0%BE%D0%B4%D0%BD%D1%8B%D0%B5_FTP-%D0%BA%D0%BB%D0%B8%D0%B5%D0%BD%D1%82%D1%8B
Спасибо. Собственно, проблема в том, что пока-что программа работает в диалоговом режиме - я ввожу команды протокола, а сервер мне отвечает. Вот тут и появляются проблемы. Или программа виснет на recv() после отправки первой же команды, или при использовании неблокирующего сокета recv() как-то странно данные возвращает, с запаздыванием на пару отправленных команд. Скорее всего, это я накосячил, но как поправить - непонятно.
Покажи код, может быть? Попробуй написать простой телнет-клиент для начала и потестить на локалном netcat - сразу увидишь, где и как у тебя что отправляется. Потом этим же телнет-клиентом уже к ftp вручную коннектиться попробуй.
Собственно, у меня пока только это и есть (телнет клиент). Код завтра скину, еще помучав.
А, и про netcat - спасибо, не знал о таком.
В си с юникодом традиционно все плохо (до C11).
Конкретно не так ты указываешь format specifier - 'c' - это char, а чтобы был wchar_t, надо '%lc'. Дальше тебе стоит кодировку исходника. Например, в гцц -finput-charset по умолчанию UTF-8, другие компиляторы не будем показывать пальцем могут ожидать какую-то другую.
А если у тебя шиндоус, тебя ждут проблемы в MSVCRT, баги в реализации консоли и прочие радости. В определенный момент ты решишь написать свой велосипед для вывода в консоль под виндой, я гарантирую это.
gcc rus_alpha.c -finput-charset=UTF8
Так? Если да, то мне вместо символов выводит знаки вопроса. Кодировка в терминале (xfce4-terminal) также UTF-8.
Хуй знает. По идее, да. Зачем тебе это вообще? Выводи UTF-8 через printf, это работает и не требует усилий.
>>621192
С '%c' оно берет из аргументов int и преобразовывает к signed char. А если из юникодной кириллицы отбросить старшие биты, ничего похожего на нормальный результат получиться не должно в принципе.
А, ну если тебе с символами работать, то конечно так не получится разве что делать работу %lc вручную, wctomb, все дела. А просто вывод строк работает если терминал UTF-8.
Забей, это был плохой совет.
Оу... Оказывается что в юникоде "ё" вне последовательности... Как все сложно то.
Всмысле? Ты имеешь ввиду это:
https://ru.wikipedia.org/wiki/%D0%AE%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4#.D0.9C.D0.BE.D0.B4.D0.B8.D1.84.D0.B8.D1.86.D0.B8.D1.80.D1.83.D1.8E.D1.89.D0.B8.D0.B5_.D1.81.D0.B8.D0.BC.D0.B2.D0.BE.D0.BB.D1.8B Впрочем. Придется ознакомится наверное поближе с чудесным миром кодировок.
Например, хочу организовать такой крутой цикл в одну строчку:
while (++i<len && !isalpha(inq));
Как будет себя вести i ?
Чтобы дождаться данных select(0, ..., ..., ..., &timeout);
Если возвращает >= 1, то данные есть. Если ты передавал больше 1 сокета, то используй макрос FD_ISSET. Если только один, то пришли данные на этот сокет. Если < 0, то отвалилось по таймауту или какая-то ошибка.
Чтобы узнать, сколько на данный момент доступно данных ioctlsocket(bind_socket, FIONREAD, &read_byte);
А если ты мне ответишь на вопрос, почему select возвращает 1, а ioctlsocket ноль, буду очень благодарен.
Сначала инкрементируется, затем сравнится.
Если префиксная форма, то инкрементируется перед операцией, если постфиксная — после выполнения операции над i.
Что именно у тебя вызывает сложности? Префиксный инкремент/декремент выполняется до обращения к переменной, постфиксный, соответственно, после. В твоём примере произойдёт увеличение i на единицу и сравнение его с len, поэтому ты не обработаешь последний символ. Здесь надо постфиксный. Или местами поменять условие, т.к. у тебя i будет указывать на следующий символ за нужным тебе. Ещё неплохо бы inq изменять каким-то образом в сторону увеличения.
>хочу организовать такой крутой цикл в одну строчку
Оно, конечно, круто while (∗s++ = ∗t++), но, как по мне, лучше избегать таких конструкций.
> ∗s++ = ∗t++
> лучше избегать таких конструкций
Это идиома, ее поведение абсолютно прозрачно, зачем ее избегать? Другое дело, что конкретно в примере >>621588 лучше сделать нечто вроде:
while (i < len && !isalpha(inq[ i ]))
++i;
или в крайнем случае пустой for а еще лучше функцию типа skip_non_alpha, тогда будет одновременно читаемо и красиво.
>>621690
> как в winsock узнать, есть ли данные, которые сокет принял и можно их оттуда забирать
Это целиком и полностью неверный подход: это очень медленно, и это неудобно, когда у тебя много сокетов. Правильнее попросить систему уведомить тебя, когда можно будет читать/писать. И вот тут появляются варианты. Если уже есть окно, и нужно передавать медленно и немного - WSAAsyncSelect хватает с головой. Если скорость важна - overlapped IO или IOCP. Если не осилишь такое, WSAEventSelect. Если нужно кроссплатформенность - select. Если не осилишь ничего из описанного вообще, тогда блокирующие сокеты. А про существование FIONREAD лучше вообще пока забыть.
>>621690
> почему select возвращает 1, а ioctlsocket ноль
select возвращает общее число выбранных дескрипторов (во всех наборах), а ioctlsocket - код ошибки.
Сложить.
А... Курсив!
>Это идиома
Просто привёл пример "крутого цикла в одну строку". Хотя мне всё равно не нравятся такие конструкции.
>Это целиком и полностью неверный подход
А если у меня на каждое подключение создаётся отдельный поток?
Не >>620375
>Если уже есть окно
У меня нет виндового окна.
Жду до таймаута с помощью select, потом читаю/закрываю, смотря что вернулось.
>Если нужно кроссплатформенность - select
Не сказать, что нужна. Но с помощью select и жду, когда данные придут.
>overlapped IO или IOCP
WSAIoctl, WSARecv, WASSend? Или что?
>А про существование FIONREAD лучше вообще пока забыть.
Что с ним не так?
>ioctlsocket - код ошибки
Не нашёл, как с помощью неё узнать код ошибки. Сделать неблокируемым, доступное кол-во байт и некое SIOCATMARK. Ошибка же через WSAGetLastError.
Грамотные примеры реализации можешь посоветовать, где посмотреть?
> WSAIoctl, WSARecv, WASSend? Или что?
Все функции, где есть lpOverlapped.
>> FIONREAD
> Что с ним не так?
А зачем лишний сисколл, если можно сразу прочитать, когда одна из функций ожидания сказала, что данные есть (или получить WSAEWOULDBLOCK без ожидания, если состояние сокета по какой-то причине неизвестно)?
> Не нашёл, как с помощью неё узнать код ошибки.
Она сама возвращает SOCKET_ERROR, если ты ей неверные аргументы скормишь, и 0, если отработала нормально. А select возвращает SOCKET_ERROR (-1) или количество дескрипторов. Вопрос >>621690 вроде об этом был, разве нет?
> примеры реализации можешь посоветовать
http://www.amazon.com/Network-Programming-Microsoft-Windows-Edition/dp/0735615799 ответит на все твои вопросы. Не уверен насчет второго издания, но первое даже на русском есть.
>>621876
Хуй знает... ну можно командную строку перезадать или дополнить в каких-то случаях. Например, в зависимости от какого-то ключика читать командную строку из файла. Например: https://www.google.com/search?q=compiler+response+file
Рихтер, потом MSDN. Можно просто MSDN, ее можно прямо по разделам читать.
Премного благодарен.
Разбираю даташит и атмеловские библиотеки, замечаю запись такого вида:
var1 = (uint_8)(var2 >> 8);
или просто:
var1 = (unsigned char)var1;
Беглый просмотр по объявлению переменных объяснения не дал, что это за запись такая?
Также есть вопрос по поводу объявления функций, что такое inline разобрался, но почему очень часто функцию объявляют как static inline разобраться не могу.
Приведение типов же.
(имя_типа) переменная — это такое явное преобразование типов из одного в другой.
static кажется и в случае с inline ограничивает ее область видимость до файла, в котором она находится. То есть, это функция будет видна только в том файле, в котором она объявлена.
> но почему очень часто функцию объявляют как static inline разобраться не могу
static здесь говорит, что функцию снаружи вызывать никто не будет. Поэтому в объектный файл она может вообще не скомпилироваться, если компилер ее везде заинлайнит. Если просто inline, то компилер попытается инлайнить функцию везде, где может, но все равно дополнительно в объектник положит копию функции, которую можно вызвать снаружи. А она может и нахуй не нужна.
Вот для примера:
static inline a(int i) { return i + 1; }
int b(int i) { return a(a(a(i))); }
Если положить в 1.c и компилировать с помощью `gcc -Os -c 1.c`, то на выходе в объектнике нет символа `a` (можно посмотреть с помощью `readelf -s 1.o`). Если же static убрать, то символ есть, то есть функция `a` теперь тоже есть в объектнике и ее можно вызвать снаружи.
Когда не знаешь, попробуй гуглить.
https://gcc.gnu.org/onlinedocs/gcc/Inline.html
>When a function is both inline and static, if all calls to the function are integrated into the caller, and the function's address is never used, then the function's own assembler code is never referenced. In this case, GCC does not actually output assembler code for the function, unless you specify the option -fkeep-inline-functions.
С какого конца раскручивать?
Мб лучше сначала хедеры читать, а потом *.c?
Просто я наткнулся на проект на ncurses, принцип работы которого хотел бы понять. А именно, как "прибит" интерфейс к самому приложению.
>Стандарт ISO/IEC 9899:2011 (он же C11)
теперь можно быстрые веб-сайтики клепать на сишке?
Ты думаешь, раньше кто-то запрещал? Но вообще, для сайтиков есть более подходящие инструменты.
>Ты думаешь, раньше кто-то запрещал? Но вообще, для сайтиков есть более подходящие инструменты.
с++?
а реально, есть какие фреймворки или типа того? Занимается этим серьезно?
А в этом стандарте много нового ввели? Я думал там потоки только завезли. И кажется еще что-то с юникодом связанное.
Python/PHP/Java конечно На роутерах бэкенд иногда на сишечке, иногда на плюсах. За фреймворки не скажу, всё, что видел - велосипеды.
>>622009
Потоки, чуть лучший юникод, выравнивание в памяти, static_assert, анонимные структуры (как у MS было), _Generic, эксклюзивный доступ к файлам, ну и еще что-то по мелочи.
vibe.d
eoucheck = fgetc(DB_table);
while (!feof(DB_table)) {
\twhile (eoucheck != '\n') {
\t\twhile (eoucheck != '|') {
который не работает. Он и не должен работать, или это я такой аутист?
Т.е. это должно выглядеть, как while((eoucheck = fgetc(DB_table)) != EOF) <блаблаблаблабоди> или о чем ты?
Да.
У тебя какая-то очень странная конструкция. Зачем здесь циклы для '\n' и '|'? Что ты хочешь сделать вообще?
Согласен, поэтому и спрашиваю. Окей, рассказываю поподробнее. Есть файлик DB_table с содержимым вида:
S | himpanze
G |orilla
M | akaka
Необходимо пройтись по строчкам и в переменную w1 вписать до |, а в w2 соответственно после. В общем, с этим все ясно. Я пришел к выводу, что можно пройтись по строчкам и до | с помощью fgetc() записать необходимые символы в переменную, и после | соответственно тоже. Код получился таким, каким я указал выше.
Т.е. в таком случае я должен использовать fread, верно?
Тебе кажется нужен strtok. С помощью него удобней парсить строки. Считай все из файла и парси.
Да, я думал о таком. Но как указать максимальный размер строки? Писать условный 1024? А если выйдет так, что строчка равно 1025? Или плевать на них, и сказать, мол, у меня запрещено так делать?
Создавай динамический массив и изменяй его размеры, когда считанных символов становится больше чем твой буфер.
man malloc
man realloc
Да, это очевидный вариант, хоть и затратный по памяти. Хорошо, я попробую, спасибо.
Здраствуй анон, помоги нублу.
Учу основы кодинга по пику, однако встал вопрос, который даже стыдно задавать, не могу понять как работает простейшая программка.
Есть одна функция, которая выводит на экран строку в обратном порядке.
void print_reverse(char s)
{
size_t len = strlen(s);
char t = s + len -1;
while(t >= s)
{
printf("%c", t);
t = t - 1;
}
puts("");
}
*
Помоги, задать вопрос больше некому.
Ну затратный он или нет, зависит от того, как ты будешь увеличивать. Куда затратней, статику большую использовать. Но в твоем случае, это вообще не существенно, так как у тебя больше нескольких кБ вероятно не будет.
>>622131
https://ideone.com/C8gQOy
Сюда код, в котором есть указатели не выкладывай. Здесь звезды съедает.
#include <stdio.h>
#include <stdlib.h>
void print_reverse(char s)
{
size_t len = strlen(s);
char t = s + len -1;
while(t >= s)
{
printf("%c", *t);
t = t - 1;
}
puts("");
}
int main()
{
char x[40];
puts("Введи строку \n");
fgets(x, 39, stdin);
print_reverse(x);
return 0;
}
Вот весь код, который работает. Однако понимания не прибавило лол
#include <stdio.h>
#include <stdlib.h>
void print_reverse(char s)
{
size_t len = strlen(s);
char t = s + len -1;
while(t >= s)
{
printf("%c", *t);
t = t - 1;
}
puts("");
}
int main()
{
char x[40];
puts("Введи строку \n");
fgets(x, 39, stdin);
print_reverse(x);
return 0;
}
Вот весь код, который работает. Однако понимания не прибавило лол
Спасибо, анон. Кажется начинаю вникать. И еще вопрос: где найти задачи на большее усвоение тем указателей и строк?
Вдогонку, почему мои программы неадекватно работают с кириллицей? Либо толпы вопросов, либо ошибка.
ЧО ДЕЛАТЬ НАХУЙ ПИЗДЕЦ СРОЧНО
после while( chunksize > 0 ) присваевается ноль
я перегрелся?
и не нашел где плюсотред.
не, тут все верно вылетает
на этом скрине >>622169 видно что chanksize внутри while не подсвечивается.
компилятор его считал другой переменной.
объявлена была в самом конце цикла, то есть после использования.
http://pastebin.com/dEmybkBY
Ну вот. Потом идёт
Record Table[RNUM];
Где RNUM - количество читаемых строк из некоего файла, это число нельзя поставить больше 75. Может, нужно выделять память через malloc?
Не уверен, что тебе нужно, но попробуй int a = @(uint64_t@)&phil4.get_id; где @ - *
В гугле пиздят, #pragma optimize(none) не помогает от этой ошибки.
Вообще там обо всем пиздят. Отключение оптимизации в настройках не помогает.
http://forum.pellesc.de/index.php?topic=2862.15
Давай больше технической инфы. Адрес ошибки, код исключения, имя модуля, какая винда?
ЧЯДНТ?
https://ideone.com/ICuvSY
>>622131
Если дебаггер не завезли, хотя бы с помощью printf("1");fflush(stdout); ошибку локализуй.
>Бред. Ты сравниваешь адрес с числом
Арифметические операции с указателями разве не так реализуются?
Адрес имеет значение вида 0x0c4233dd. Число, которое сравнивается с указателем в том цикле является длинной строки. Сам подумай, есть ли в этом смысл.
Уточнение:
Было бы правильно, если бы сравнивался указатель на начало строки с указателем на начало строки + длинна строки. Тогда было бы нормально.
Но как тогда "передвинуть" указатель первого символа строки на Nый символ оной? Видимо я недопонял саму концепцию операций над указателями, лол
Ты передал первый элемент массива через аргумент. Создай в той же функции указатель, который будет указывать на то, что ты передал (начало строки), Это для того, чтобы не потерять саму строку. Затем, ты можешь делать со строкой все что угодно. Для того чтобы передвинуть указатель, тебе нужно добавить целое число. Допустим есть у тебя указатель на char. Прибавляя единицу, ты сдвинешься на один байт. Если указатель будет на double, добавив единицу, ты сдвинешься на 8 байт, так как double = 8 байтам. Естественно, размеры char, int , double - не фиксированы и зависят от платформы. Но я взял к примеру amd64.
Спасибо за объяснения Вчера ли не ты мне помог?, приму к сведению, пойду перечитывать главу с указателями.
Да. Перечитай и попрактикуйся. Указатели лишь поначалу кажутся сложными и непонятными, но если приловчится, начинаешь без проблем работать даже с самыми сложными конструкциями.
Ага. Если ты про книги, юникод и комментарии.
Формальные — это тот, который ты задаешь при определении функции. Фактический — тот который используется при вызове.
типа int huy (int govno) - huy это формальный, govno - фактически - правильно поняЛ?
Нет. Возьмем этот https://ideone.com/xixkIN пример (не обращай внимание, что код в не абсолютно не правильный).
Здесь на строке 17 и 33 у нас определения функций. Аргументы, которые они принимают — формальные. То есть на не обязательно, передавать аргументы с теми именами, которые указаны. Главное чтобы тип совпадал.
А вот вызовы этих функций, на строке 39 и 49 — принимают фактические аргументы.
А, ясно короче, блин. Лол. а так описано ФОРМАЛЬНЫЕ ФАКТИЧЕСКИЕ, лол, я думал там сложно А это оказывается принимаемые параметры и объявляемые в фцункции, спасибо.
Короче
где-то в программе int huy_pizda;
int huy (int govno)//формальный
{..}
huy(huy_pizda) - фактически
Забыл сказать - спасибо.
Небольшое уточнение.Это параметры объявляемой и вызываемой функции.
>int huy (int govno)//формальный {..}
Здесь именно int govno - формальный параметр
>huy(huy_pizda) - фактически
huy_pizda - фактический параметр.
Опять я выхожу на связь. Портирую свою программу на виндовс. Через тот же Qt и CMake. И тут вылезает такая segmentation fault в следующем участке:
char buf=((char)malloc(sizeof(char)10BUF_SIZE)); <- если использовать такую конструкцию, то для буфера хватит аж целых 10 кБ, и никакой ошибки не возникает
char buf; <- если использовать такое объявление и прикрутить проверку на выделение памяти, вылезает segmentation fault и пишет Out of memory: not enough space (причём здесь выделяется всего лишь 1кБ.
if ((buf=((char)malloc(sizeof(char)*BUF_SIZE)))==NULL){ \t \t
perror("Out of memory");
system("pause");
exit (-1);
}
через #define
Но вот щас интересная магия происходит: убираю отладочный printf - программа крашится...
А я по твоему должен думать о нищебродах, у которых меньше 8Гб ОЗУ?
Да я не он. Просто вспомнил многопоточный сканер портов, который был сотней постами ранее.
> memset(buf,0,sizeof(buf));
http://www.viva64.com/ru/b/0360/
Покажи дефайн с BUF_SIZE. Или проблема в нём, или ты кучу распидорашиваешь где-то в другой части программы.
Хм. Возможно, стоит отказаться от использования этой функции.
Дефайн вот:
#define BUF_SIZE 500
Если поставить, к примеру, 1000, то программа не выдерживает.
Пробовал объявить и глобальную
size_t BUF_SIZE=1000;
Проблема та же.
Не надо отказываться, надо после malloc кормить в memset то, что кормил в malloc, а не sizeof указателя. А вообще, у нас calloc есть.
А, тогда норм.
QtCreator ещё почему-то не завершает программу, которая запустилась нормально и завершилась нормально, и если не убить её вручную, то следующий запуск будет с фейлом.
https://msdn.microsoft.com/en-us/library/974tc9t1.aspx посмотри там в конце, как включить отладку кучи (не помню, можно ли где-то галочкой поставить).
Не совсем понятно, зачем там add esi,24 и прочие shr до dec. В остальном все ок же. Я бы сделал fldz и цикл из нужного количества fadd. Как-нибудь так: http://pastebin.com/LUPasL1Z
for (int i=0; i<5; i++) {
for (int j=0; j<5; j++) {
printf("%d\t", kk[j] );
printf("\n");
}
}
Какой у меня дабл, наркоманы
Покажи как kk[][] объявлял.
Стоит лезть с пулл-реквестами, но постарайся делать это не так:
https://lkml.org/lkml/2015/11/19/466
Чего-о-о? Нет никаких камней, обязательно используй.
Гитхаб норм же. Можешь какого-нибудь инди-разработчика найти с проектом, который тебе интересен - и он будет рад внезапным помощникам, и тебе опыт.
Кто нибудь кодит в XCode ?
Начал свой небольшой проект на чистом С. И столкнулся с такой хуйней.
Есть 3 файла.
//main.c
#include "cpu.h"
//код программы
//cpu.c
#include "cpu.h"
//тут реализация пары функций из cpu.h
//cpu.h
#ifndef cpu_h
#define cpu_h
// тут объявлены 11 глобальных переменных, используемых
// и в main.c и в cpu.c
#endif / cpu_h /
Так вот я не могу скомпилировать это дерьмо. Потому что на линковке выдает ошибку - 11 duplicate symbols for arhitecture bla bla.
Что за хуйня? такой же код и файлы в Visual Studio компилируются нормально.
если глобальные переменные extern, их значения надо присваивать в cpu.c, а не cpu.h
extern yoba_t YOBA; // cpu.h
yoba_t YOBA = {Kruzhok, Zhelty}; // cpu.c
это потому что такие значение линкером помечаются как экспортируемые, а для каждого экспортируемого символа должно быть ровно одно значение на все файлы.
еще можно в cpu.h просто пометить переменные как static, тогда на самом деле main.c и cpu.c будут использовать разные копии.
Например вот: только после fclose в успешную, ты имеешь гарантию что данные записались на диск - иначе нет.
В с нет такого понятия как ассемблерные вставки. Такое понятие есть на уровне компиляторов - у каждого свои.
Во-первых, это всего лишь потому, что fclose делает fflush, а во-вторых, ОС может с тобой не согласиться, а накопитель тем более может не согласиться.
Ну всякие part of speech tagger (проставлялка частей речи, допустим в английском), какие-нибудь библиотеки для автоматизации рутинной ебли с указателями на массив символов.
Регекспы устраивают, но не совсем. Да и медленновато ими.
Ну это уже совсем новый уровень не слышал про такое никогда лол, вряд-ли это к "программированию" прям вопрос, хотя я и других библиотек не знаю, более приземлённых.
Ну да. Хочется чего-то такого.
https://stackoverflow.com/questions/21871374/is-there-any-part-of-speech-tagger-in-c
https://stackoverflow.com/questions/1805099/c-c-nlp-library
Даже что-то нагуглил, есть тут кто с опытом использования?
Ну как бы это сказать, треды ты же про них?, сильно платформо-зависимы. Например, под линь можно почитать боровского - коротенькие статейки с примерами.
>так и больше размера size_t
Карнавал продолжается. Хотя с числовыми эквивалентами указателей дикий наёб (вспомнить хоть ptrdiff_t к тому), тут только строго c99 (со своими модными intptr_t и uintptr_t) иначе не как .
В чём проблема то? Бери да кастуй, не нравится - определяй юнион, если там есть массивы переменной длины - объявляй структуру прям внутри функции, где укажешь какой размер массивов в данный момент. А вообще, я не понял что хочешь ты.
>Стандарт запрещает
Стандарт определяет тебе за щеку. Какая хуйня разница на порядок байт, если это не внешние данные, например Или с чего ты взял что это не так?
да, пиздуй отсюда, хуесос
Мелкомягие тоже могут, оказывается ))
C:\TEMP\1>cl /GS- 2.c /link /NODEFAULTLIB /ENTRY:mainCRTStartup /SUBSYSTEM:CONSOLE /IGNORE:4254 kernel32.lib
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.42 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
2.c
Microsoft (R) Incremental Linker Version 8.00.50727.42
Copyright (C) Microsoft Corporation. All rights reserved.
/out:2.exe
/NODEFAULTLIB
/ENTRY:mainCRTStartup
/SUBSYSTEM:CONSOLE
/IGNORE:4254
kernel32.lib
2.obj
C:\TEMP\1>2
Hello, World!
C:\TEMP\1>dir 2.exe|findstr 2.exe
15.01.2016 14:40 1 024 2.exe
C:\TEMP\1>type 2.c
#include <windows.h>
#pragma comment(linker, "/MERGE:.rdata=.data")
#pragma comment(linker, "/MERGE:.text=.data")
#pragma optimize("gsy", on)
int mainCRTStartup()
{
DWORD dwCharsWritten = 0;
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
char sMsg[] = "Hello, World!\n";
WriteConsole(hStdout, sMsg, lstrlen(sMsg), &dwCharsWritten, NULL);
return 0;
}
Мелкомягие тоже могут, оказывается ))
C:\TEMP\1>cl /GS- 2.c /link /NODEFAULTLIB /ENTRY:mainCRTStartup /SUBSYSTEM:CONSOLE /IGNORE:4254 kernel32.lib
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.42 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
2.c
Microsoft (R) Incremental Linker Version 8.00.50727.42
Copyright (C) Microsoft Corporation. All rights reserved.
/out:2.exe
/NODEFAULTLIB
/ENTRY:mainCRTStartup
/SUBSYSTEM:CONSOLE
/IGNORE:4254
kernel32.lib
2.obj
C:\TEMP\1>2
Hello, World!
C:\TEMP\1>dir 2.exe|findstr 2.exe
15.01.2016 14:40 1 024 2.exe
C:\TEMP\1>type 2.c
#include <windows.h>
#pragma comment(linker, "/MERGE:.rdata=.data")
#pragma comment(linker, "/MERGE:.text=.data")
#pragma optimize("gsy", on)
int mainCRTStartup()
{
DWORD dwCharsWritten = 0;
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
char sMsg[] = "Hello, World!\n";
WriteConsole(hStdout, sMsg, lstrlen(sMsg), &dwCharsWritten, NULL);
return 0;
}
Индексы могут быть любыми, т.е. мы отрезок одного массива копируем в отрезок другого массива.
Я уже погуглил memcpy. Как его правильно использовать, если массив C создан на куче? Есть указатель на его начало. Как с его помощью копировать диапазон элементов из данного массива в другой?
Считаешь, сколько тебе элементов нужно скопировать. Копируешь:
memcpy(&dest_array[dest_index], &source_array[source_index], sizeof(source_array[0]) ∗ num_elemets);
Где созданы массивы, значения не имеет. Разве что, если диапазоны хотя бы частично перекрывают друг друга, нужно использовать memmove.
Выражение &array[index] можно заменить на array + index, это вопрос личных предпочтений. Я считаю, что с & и индексом нагляднее.
Я вот что пишу. Видимо, я неправильно использую memset, потому что даже спижженное откуда-то копирование при помощи двух циклов дает мне некоторое подобие отсортированного списка. У меня же получается просто мусор.
Как можно исправить алгоритм?
https://ideone.com/b5Slww
У меня все компилируется и запускается. Про free я забыл, но сейчас допишу.
Блджад, а при добавлении free вне if'а или внутри программа падает при запуске.
Еще одну ошибку увидел: при выделении памяти не домножаю на размер типа данных.
Лел, исправил эту ошибку, и сразу заработало. Тогда просто подскажите, как из этого говна сделать хороший код. Что я делаю не так?
Вот моя окончательная реализация, господа. https://ideone.com/quzyJ8
В процедуре mergesort выделяется память для двух массивов даже когда не выполняется условие n > 1, то есть будет утечка памяти. Как это исправить? Можно освобождать память внутри mergesort, но ведь логичнее это делать после слияния, когда массивы стали больше не нужны.
Например free перенести из merge в mergesort?
>Разве что, если диапазоны хотя бы частично перекрывают друг друга, нужно использовать memmove
Против линуса попереть решил? Не стыдно?
Почему? Он как раз всё по Линусу предлагает:
[CODE]
The memcpy() function copies n bytes from memory area src to memory
area dest. The memory areas must not overlap. Use memmove(3) if the
memory areas do overlap.[/CODE]
[code]
printing_str = int_data % 10 + '0';
[/code]
Каким образом это работает? Остаток от деления int на int будет int и к нему прибавляют char '0'. Ничего не понятно. Тут какое-то хитрое преобразования типов?
char - беззнаковый целочисленный 1-байтный тип данных. То есть [0; 255]. В стандартной кодировке числа идут по порядку, поэтому можно из '0' сделать '1', прибавив единицу. Или из 'a' сделать 'b'.
Ну так просвети, ёбана. Я могу также сказать, что ты не читал мануал к функции memcpy().
Про типы данных в выражениях тебе нужно знать одно: если они меньше чем int они неявно кастуються в int, если больше, например безнаковый int, то кастуются в большое, понятно, по приоритетам операций. Всё, например, просто.
>char - беззнаковый целочисленный 1-байтный тип данных. То есть [0; 255].
Блять, вы же тралите так? Как вас земля носит. Знаковость он определил, ещё и диапазон вместимости чара, ну ахуеть.
class os_vzai
....
DWORD, WORD я писал на винапи... какой шквар
....
Методы заебись:
void fu_cp_001(u_char bb) { //Просто пишим символ
bool fu_cp_002(WORD beck,WORD fore) { //Устанавлеваем цвет от 0-15
void fu_cp_002(WORD beck) { //Устанавлеваем цвет от 0-15
void fu_cp_003(u_sint xz,u_sint yz) { //Размер консоли
....
Потом я видимо на структуру и функции переписал:
struct OSVZAIM
....
OSVZAIM O1488=OSVZAIM(); - Что это в спп значит, помнит кто?
#define CRE_ALL_CON_SHIT(); \
({ \
O1488.CON_HAN_VIVO=GetStdHandle(STD_OUTPUT_HANDLE); \
O1488.CON_HAN_VVOD=GetStdHandle(STD_INPUT_HANDLE); \
....
Короче это обёртка для вывода на виндавс консоль....
/
> Функция умножения ДЦПТ на ДЦПТ.
> Во всех операндах(1) части по 32бит. 2 - не больше 31
иначе я неебу чё произойдёт. ОСТОРОЖНО БЛЯТЬ например
неучтино что навыход число вдва раза больше.
> [1-Слагаемое] [2-Сдвиг на] [3-Байт колличесто]
/// 8 12 16 20
void bnFU_UDVx32_Mul(void Var_1, u_int Var_2, void Out_3, u_int Byt_4) { //ЭТО ПОЛНАЯ ХУЙНЯ, ПЕРЕПИСАТЬ
asm volatile (
STRING_LITERAL(
/ ~~ПУПОВИНА~~ /
movl 8(%esp) , %edi ;
movl 12(%esp) , %esi ;
movl 16(%esp) , %ecx ;
addl 20(%esp) , %esi ; //Смещь. умножитель на младьшее
movl 20(%esp) , %ebp ;
xorl %edx , %edx ;
/ ~~ТЕЛО~~ */
LAB_0301:
subl $4 , %ebp ;
movl 20(%esp) , %ebx ; //
addl %ebx , %edi ; //Смещь. умножаемое на младьшее
subl $4 , %ecx ; //Смещь. результ на доб смещь
subl $4 , %esi ; //Смещь. умножитель
LAB_0302: //ЗДЕСЬ умножаем 1 часть умножителя на умножаемое
/
> Функция умножения ДЦПТ на ДЦПТ.
> Во всех операндах(1) части по 32бит. 2 - не больше 31
иначе я неебу чё произойдёт. ОСТОРОЖНО БЛЯТЬ например
неучтино что навыход число вдва раза больше.
> [1-Слагаемое] [2-Сдвиг на] [3-Байт колличесто]
/// 8 12 16 20
void bnFU_UDVx32_Mul(void Var_1, u_int Var_2, void Out_3, u_int Byt_4) { //ЭТО ПОЛНАЯ ХУЙНЯ, ПЕРЕПИСАТЬ
asm volatile (
STRING_LITERAL(
/ ~~ПУПОВИНА~~ /
movl 8(%esp) , %edi ;
movl 12(%esp) , %esi ;
movl 16(%esp) , %ecx ;
addl 20(%esp) , %esi ; //Смещь. умножитель на младьшее
movl 20(%esp) , %ebp ;
xorl %edx , %edx ;
/ ~~ТЕЛО~~ */
LAB_0301:
subl $4 , %ebp ;
movl 20(%esp) , %ebx ; //
addl %ebx , %edi ; //Смещь. умножаемое на младьшее
subl $4 , %ecx ; //Смещь. результ на доб смещь
subl $4 , %esi ; //Смещь. умножитель
LAB_0302: //ЗДЕСЬ умножаем 1 часть умножителя на умножаемое
> если он по ссылке пиздит про то что надо memmove
> Хотя это многое объясняет
жопой читал, но ему много объясняет - так и запишем.
просто иди нахуй
>memcpy acts randomly (and differently) with overlapping areas
>It's a common bug to use memcpy() instead of memmove()
>So from a pure Quality-of-Implementation standpoint, just make glibc implement memcpy() as memmove()
>However, I still don't understand why you guys can't just admit that you might as well just do memmove() and be done with it.
1) Задаю начальный размер буфера;
2) Выделяю память при помощи malloc;
3) Делаю цикл для считывания введенных символов с клавиатуры до тех пор, пока символом не станет '\n';
4) В цикле есть счетчик, с помощью которого узнаю, не превышаю ли размера буфера;
5) В случае, если запись текущего символа превысит размер буфера будет превышен, удваиваю размер буфера при помощи realloc;
6) После цикла, выставляю '\0' в качестве значения для последнего элемента строки;
7) Если буфер заполнен не полностью, усекаю размер буфера до размера строки при помощи realloc.
Все правильно делаю? Или можно как-то иначе и лучше сделать это?
Ты внатуре ебанько, он пишет за баг в либс, хотя его там нет, заебись так сделать memcpy как memmove. Короче о чём с тобой говорить....
> В случае, если запись текущего символа превысит размер буфера будет превышен,
посылаю нахуй пользователя, потому что 1кб на строчку должно хватать.
> realloc
Не пользуйся этим говном. Память не нужно реалацировать, память нужно выделять и связывать.
>посылаю нахуй пользователя, потому что 1кб на строчку должно хватать.
>память нужно выделять и связывать.
А если вместо пользователя файл? 1KB не хватит. А заранее выделить необходимое количество не выйдет.
>Не пользуйся этим говном.
А вот здесь по-подробней. Что не так с этой функцией?
> А если вместо пользователя файл
И что, там будут строки больше 1кб? Вот ты прочитал строку, дальше ты с ней что делаешь?
> Что не так с этой функцией?
Всё так, я просто боевой школьник, и иметь кучу вызовов алока/реалока - странно, суть всегда в том, чтобы сразу выделить много и этим пользоваться. Усекать уж точно не нужно, как и давать возможность пользователи запросить бесконечно много памяти.
1. Программа, подсчитывающая, в какой день недели родились. Входные данные - дата рождения.
2. Программа, считающая количество полных дней с даты рождения. Входные данные - дата рождения и текущая дата.
3. Программа, определяющая, високосный ли год. Входные данные - год.
Нет, это ты даун, раз сразу не понял, в чем здесь проблема.
Это тупое переполнение char, надо делать unsigned.
Это не С++ тред. Но кажется, эти задания я видел у старины Бьерна. Там в главе про классы кажись.
Просто char в функциях с переменным числом аргументов автоматически преобразуется к int. Спецификатор %x предназначен как раз для вывода int, и этот самый int он и выводит. Но размер типа char от этого, конечно же, не меняется, поэтому второй спецификатор выводит 1.
>int
Собственно говоря потому, что при вызове функции в С, на стек аргументы так и кладутся, интами, ну, кратно.
Если функция принимает char (есть формальный параметр), то на x86 компилятор может сделать push eax, не обнуляя старшие биты eax. Если функция с переменным числом аргументов, компилятор обязан будет сначала сделать movsx.
Он пишет про workaround для решения проблем, вызванных некорректным использованием memcpy() разработчиками софта.
>заебись так сделать memcpy как memmove
По факту там хуйнули патч для x86 архитектуры, что заместо memcpy() вызывался memmove(), т.к. он работает нормально с overlapped буферами. Каким макаром замечание, что
>если диапазоны хотя бы частично перекрывают друг друга, нужно использовать memmove
противоречит Линусу, я не понимаю. Хотя о чём с тобой говорить.............
Проиворечит линусу то, что он допускает неправильное использование memcpy, при перекрывающихся (и пошёл хуярить именно на либу), а ты предлагаешь человеку делать "как надо" - но ты нихуя не улавливаешь ни связи, не смысла - уёбок, что с тобой сделать................................
>>627759
Вы уже надоели! Читаю вас и не могу понять, о чем вы спорите. Какие-то последователи Линуса или что-то еще. Просто объясните мне. Читаю я значит в мане, что рекомендуется использовать вместо memcpy, memmove в случае, если одна область (в которую копируем) накладывается на другую. Что не так?
Тоже не могу понять, о чем спор. То, что в каких-то линуксах реализация memmove практически идентична по быстродействию memcpy, не означает, что так будет в других реализациях на других платформах. Поэтому правила остаются теми же:
1) memmove, если области перекрываются или есть сомнения.
2) memcpy в остальных случаях.
Понятно. Очередной Qt фанатик. А я надеялся ты аргументируешь как-то. На линуксах оно живее всех живых ведь. GNOME 3 хоть и утратил популярность, но держится на плаву. А крыса и вовсе сейчас процветает (вероятно скоро самой популярной станет), так как у нее многие пользователи — это беженцы с тех же KDE и GNOME, в которых от релиза к релизу все ломают. Также есть множество людей, которые предпочитают чистый Си, а не кресты (я не из таких). Впрочем, это уже тема для срача.
Я не фанатик, я просто реалист. Когда даже такие крупные проекты как, например, Wireshark валят с гтк (или скорее валят на qt), это о чем-то говорит.
У меня складывается такое впечатление, что они начитаются статей от васянов на какой-то хабре или прочем ресурсе и принимают сказанное за истину, вместо того, чтобы самостоятельно разобраться в теме.
>>627852
https://en.wikipedia.org/wiki/List_of_GTK%2B_applications
https://en.wikipedia.org/wiki/Category:Software_that_uses_GTK%2B
Ну да. Действительно умирает. Кстати, я почему-то думал, что хромиум на Qt. А оказывается вот оно как. Два единственных браузера и то зависят от мертвого тулкита.
Внимание не обращайте, делайте как написано в мане, а не как васяны-хакеры могут, и не будет такой хуйни по итогу.
Должен заметить, что ваешарк на кт редкостное глюкавое неузабельное говно получилось пока.
Они еще тестируют его. И пока у них две версии (Qt, GTK), рано еще говорить о чем-либо говорить. Есть вероятность, что они и в Qt найдут какой-нибудь фатальный недостаток, коих у обоих тулкитов достаточно.
Теку от этой шапки.
Ты бы и от собаки тек.
Что тебе нужно? Ты так коряво сказал, что я подумал, что ты хочешь чтобы тебе запили сканер портов.
Если ты удалил это у себя, то уже не вернуть. Он никому не нужен, чтобы его хранить. А за твои ошибки тебе уже поянили.
Да это не я, просто тредами как-то не баловался ещё, буду базу данных писать, запилю её на тредах, чтоль, один обработчик ввода, другие - выполнение. Ввод/вывод - пайпы, или сокеты, хмм....
Ребят, кстати, почему в рекомендациях нет "Искусства Эксплойта" второго издания Эриксона? Там же охуенное введение, как в С, так и сразу же на наглядных примерах его применение. Там даже с отладчиком сразу показывают, как работать надо.
http://www.ozon.ru/context/detail/id/4833854/
хотя по любому уже и так в сети есть
Почитай про мнопоточность лучше. В случае с серваками, если я не ошибаюсь применяют две модели: 1) поток на соединение; 2) поток управляемый событием (то есть потоки используются по мере надобности);
Не расходуй ресурсы процессора впустую. На ввод/вывод требуется очень мало ресурсов процессора. Оно там не нужно.
>>628634
Не стоит. Ты видишь какой здесь контингент? Лучше пусть изучают принципы программирования, а не то каждый ньюфаг сразу будет хватать это и задавать глупые вопросы.
> Почитай про
Я и так вкурсе вопроса.
>Оно там не нужно
Что значит не нужно, а кто будет рождать потоки на выполнение? Я хочу чтобы можно было, например параллельно вести поиск чего-то по базе. Да и её саму (базу) в отдельный процесс.
Очень давно его не читал. Но честно говоря год назад наткнулся на его вью и как-то он имхо, как человек, дико испортился. Видимо после визита ФБР.
Здесь вечный срач. Интелловский самый распространенный, так как интел его продвигает. AT&T многие считают очень удобным и более логичным. Но он настолько мало распространен.
Как можно зная один синтаксис, не осилить другой. Они же все равно похожи очень.
А, нет, там, вроде, интеловский. Зря я сиранул на синтаксис.
Посоветуйте, как проще всего смотреть код сишных функций в дизассемблере, и я пойду обмазываться. До этого изучал в отладчике только проги на чистом асм.
Сложно запомнить, что регистры начинаются с % (%eax, %ebx или %rax %rbx) и значения с $ ($0x80, $40 и т.д)?
>как проще всего смотреть код сишных функций в дизассемблере
Как это вообще понимать? Может глазами, там.
Тебе смотреть на него или писать? В любом случае, код на нем более самодокументируемый.
Например, мне нужно узнать, во что скомпилилась конкретная функция. Как ее найти в кратчайшее время?
Скомпилить с флагом -S и прочитать вывод в текстовом файле?
http://www.proklondike.com/books/hacking/ericson_Haking_iskustvo_exploita_2009.html
Тут даже с исходниками.
Ну ладно, ладно, убедили, скачаю. пойду memcpy использовать как memmove - хакирь же. Напишу плагин к браузерам, что-бы можно было красивую и мелковесную рекламу вешать - вот будет заебись
С одной стороны, если учить Си и сразу смотреть, что творится на ассемблерном уровне, все становится простым и понятным. С другой стороны, потом нужно будет потратить много времени, чтобы избавиться от плохих привычек и начать писать кроссплатформенный код.
> начать писать кроссплатформенный код
Я бы хотел добавить, платформы и их популярность меняются достаточно часто, относительно того, что у новичка да и у других бывает в голове. Вот перешли все на 86-64, и охуели c того, что int может быть не равен размеру void*, да и стандарты до, были не полны, щас с11 - это реально глыба, и самое правильное на чём нужно писать в С. И так-то правильно понимать что ты пишешь, но не забывай что стандарт - это то в чём пересекаешься ты и те кто реализуют этому коду работу. Остальное - чёрная дыра.
Опишите на русском языке или одном из языков программирования алгоритм подсчета максимального количества подряд идущих четных элементов в целочисленном массиве длины 30.
Вот мое решение. Правильно?
алсо, как сделать проверку на пустой элемент массива?
http://pastebin.com/xJGMMST1
Тебе разве здесь не нужно найти максимальное количество подряд идущих элементов? У тебя сейчас ищется общее количество подряд идущих. А по поводу пустого элемента — никак. В элементах, которые у тебя есть, могут быть любые числа. Даже если ты инициализируешь их каким-то числом, это может быть неправильно, так как придется зарезервировать одно число для этого.
По поводу кода. Зачем тебе sdafx, iostream и locale? Они не нужны. locale может пригодится, разве чтобы на кириллице писать. Зачем тебе system? Это тоже излишне.
sdafx стандарт в vs
iostream и locale, локале забыл убрать, иострим для остановки программы.
А точно, сейчас переделаю.
Ты еблан даже не знаешь зачем sdafx нужен. Это блядь файл с прекомпилированными блядь заголовками, для проекта уровня laba2 они не нужны, потому что он и так за пару секунд компилиться.
Ты сам не можешь проверить? Записал программу, скомпилировал, запустил, смотришь на результаты. В чем проблема?
Ну ясно тогда, удачи в делах
Пиздец, стоит ли читать блевоту в начале, если я осилил всего Кернигана и Ричи? Будет ли польза? Я думаю, нет.
Лучше стандарт прочти. Гораздо полезнее.
Повторюсь для тебя: "Стандарт прочти."
В С11 уже можно объявлять локальные переменные в любых блоках, в том числе и в заголовке фора.
>bool
Сам без понятия нахуя оно нужно, вот еслиб он конвертировал возврат из функции (из стандартных) как "получилось", "не получилось" - это другое дело, только это не С. Но а так то - прост)
Я обычно пользуюсь 1 - true, 0 - что-то специальное, <= -1 ошибка, её тип.
> bool
> _Bool
Одно и тоже.
> Что-то странная система
Она логичная, есть диапазоны положительного исхода, есть отрицательного. Выявить принадлежность просто, >0 или <0. Что тут странного?
Достаточно хороша. Там очень наглядно разжевывают всю еблю с указателями, памятью, переполнениями буферов и, например, сетевая стекоебля.
>Одно и тоже.
И я о том же.
>Что тут странного?
Все нормально. Просто я не выспался и перемешалось все в голове.
>>629395
> всю еблю с указателями, памятью, переполнениями буферов и,
Это в K&R есть.
> сетевая стекоебля.
А это, уже не имеет прямого отношения к самой Си, но есть в различных источниках. Точкой входа можно взять "Компьютерные сети" Таненбаума.
Я, конечно, сам в Си новичок, но я правильно понял, что ты делаешь массив без объявления элементов этого самого массива?
> "Компьютерные сети" Таненбаума
А чё не снайдер? Чтобы вкатится сходу, можно накатить статейку шаргина на рсдн Программирование сокетов в Linux.
>Stephen Prata "C Primer Plus, 6th Edition" (2014)
Уже есть.
>>629395
>Это в K&R есть.
Только там все с крайне наглядными примерами в отличие от K&R
>А это, уже не имеет прямого отношения к самой Си
с чего это не имеет?
В общем, мое дело предложить. Елси ты уже такой охуенный парень, что освоил C по K&R, то только успехов тебе на поприще остается пожелать.
Как-то криво, имхо, идет работа с max и submax, мне почему-то кажется, что это можно соорудить с использованием всего одной переменной.
Павильно. В случае, если где-то в середине массива условие не будет соблюдаться, submax'y опять присвоится 0, и дальше твой if if(max<submax) будет False, в следствие чего и max будет считаться не правильно.
Может лучше сначала изучить как работает сеть, перед тем, как йписать приложения для работы с ней? Таненбаум дает фундаментальные знания просто.
>>629424
>Только там все с крайне наглядными примерами в отличие от K&R
Не осилил примеры из K&R?
>с чего это не имеет?
Потому, что это сторонние API, а не стандарт Си.
> Елси ты уже такой охуенный парень, что освоил C по K&R
Ну охуеть теперь.
>Может лучше сначала изучить как работает сеть
Лучше, всё-же, сходу иметь работающий код, а потом сидеть понимать как он работает, модифицирую его там, переписывая на более низкий уровень, итп. Хотя это всё, например, дискуссионно.
То есть, допустим, я могу вызвать grep из сишки? Могу скормить вывод ls?
>Платиновый вопрос: как программы на сишке взаимодействуют с другими (внешними) программами на ней же
Посредством:
1) Перенаправление вывода другой программы;
2) FIFO;
3) Сигналы.
>То есть, допустим, я могу вызвать grep из сишки? Могу скормить вывод ls?
Перенаправление потоков. То есть stdout одной программы (ls) перенаправляется на stdin grep.
В качестве теста, можешь в цикле, прогнать getchar.
Не внимательно прочитал.
Нет, пасты про лисперов и хаскелистов смешнее.
Это достали из стека адрес аргумента printf, зря поторопился спрашивать.
Это копия, сохраненная 28 января 2016 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.