Сохранен 295
https://2ch.hk/pr/res/1095677.html
Прошлые домены не функционирует! Используйте адрес ARHIVACH.VC.
24 декабря 2023 г. Архивач восстановлен после серьёзной аварии. К сожалению, значительная часть сохранённых изображений и видео была потеряна. Подробности случившегося. Мы призываем всех неравнодушных помочь нам с восстановлением утраченного контента!

C Programming Language #26

 Аноним OP 21/11/17 Втр 20:01:06 #1 №1095677 
С Programming Language.png
Тред, посвященный прародителю всех С-подобных языков и по совместительству единственному идеальному и всесторонне годному средству программирования как на системном, так и на прикладном уровне.

Пожалуйста, пользуйтесь https://ideone.com/ или http://pastebin.com/ для вставки кода, если он длиной больше нескольких строк или содержит [​i​] или ∗.

Что читать:

- Классика от Отцов: http://www.cypress.com/file/56651/download
- Stephen Prata "C Primer Plus, 6th Edition" (2014): свежая, знает про C89/C99/C11, описывает различия, объемная (около тысячи страниц), годная, с вопросами, упражнениями и ответами. Читать после K&R или до.
- Годное пособие для гуманитариев: http://web.archive.org/web/20160727235220/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 2017 Community Edition: внезапно этим стало можно пользоваться, особенно с тулсетом clang/C2. Поддержка C11 на уровне "есть все, что тебе понадобится в реальном проекте плюс кривая библиотека". Анализатор кода в комплекте.
- Pelles C (шиндоуз онли): поучиться, вкатиться в C11 (стандарт полностью реализован, имеются в том числе threads.h и прочие stdatomic.h), но количество багов в оптимизаторе и редкие апдейты напрочь отбивают желание собирать этим что-то сколько-нибудь серьезное.
- TCC: очень маленький компилятор с багами и неполной поддержкой C99. С ключом -run умеет компилировать код в память и запускать его, что позволяет писать скрипты прямо на сишечке.

Что еще почитать:

http://c-faq.com/
FAQ из comp.lang.c. Древний, но все еще актуален.

Samuel P. Harbison, Guy L. Steele Jr. "C: A Reference Manual, 5th Edition" (2002)
Ебаный пересказ стандартов C89 и C99 (включая стандартную библиотеку). Для не осиливающих стандарт в оригинале. Читать в качестве подготовки к собеседованиям (есть задачник с ответами) и для ознакомления с масштабами пиздеца перед написанием своего парсера/компилера.

Peter Van Der Linden "Expert C Programming. Deep C Secrets" (1994)
"Си: грязные истории". Смехуечки, немного объяснений, чем обусловлены особенности языка, всем известные подводные камни кто там ругал косяки в JS? у нас в сишечке их гораздо больше, просто они лучше спрятаны, немного байтоебли и непонятно откуда взявшаяся глава про старинные плюсы. Читать в качестве сказки на ночь (на пару вечеров хватит).

Richard M. Reese "Understanding and Using C Pointers. Core Techniques for Memory Management" (2013) - почитать, вкатиться в указатели.

Ben Klemens "21st Century C: C Tips from the New School" (2012)

Paul Deitel, Harvey Deitel "C for Programmers with an Introduction to C11" (2013)

Stephen G. Koch@n "Programming in C (3rd Edition или 4th Edition, если найдется)" (2014)

MISRA Ltd. "Guidelines for the Use of the C Language in Critical Systems" (2013)
Набор рекомендаций по написанию надежного кода на C (промышленный стандарт). Читать - однозначно, следовать - вдумчиво и без фанатизма. Также можно посмотреть https://www.securecoding.cert.org/confluence/display/c/SEI+CERT+C+Coding+Standard

Еще более длинный список: http://www.iso-9899.info/wiki/Books#Learning_C

Онлайн-утилиты:

- https://godbolt.org/ - Compiler Explorer позволяет посмотреть выхлоп компиляторов для введенного куска кода (больше полусотни разных версий компиляторов).
- http://cdecl.org/ - С Gibberish ↔ English помогает читать сложные сишные декларации.

Прошлые треды:

- №23: https://arhivach.org/thread/277223/
- №24: https://arhivach.org/thread/291766/
- №25: https://arhivach.org/thread/303902/

Шапка: http://piratepad.net/bJ1SdmkZyu
Аноним 21/11/17 Втр 20:10:21 #2 №1095682 
Почему язык Си такой классный?
Аноним 22/11/17 Срд 00:16:25 #3 №1095842 
А как вообще программировать на С и при этом не косячить, если компилятор проглатывает практически любой код, даже такой, который очевидно ошибочен?
sageАноним 22/11/17 Срд 00:27:13 #4 №1095854 
>>1095842
Осторожно.
sageАноним 22/11/17 Срд 01:29:59 #5 №1095879 
>>1095842
Как программировать на <любой язык нейм>, если компилятор проглатывает умножение на -2 там, где нужно было прибавить 3? Это же очевидная ошибка!
Аноним 22/11/17 Срд 02:34:32 #6 №1095898 
image.png
image.png
помогите, почему не выделяет память?
sageАноним 22/11/17 Срд 04:59:38 #7 №1095913 
>>1095898
> .cpp
Во-первых, ты ошибся тредом. Во-вторых, тебе чистейшим английским языком написали, что в этих ваших крестах указатель на воид не кастуется в другие указатели автоматом (а в Си кастуется). Поэтому:
1) Не юзай маллок, у вас там завезли всякие векторы или new на худой конец.
2) Если уж юзаешь маллок, влепи каст к (char *).
Аноним 22/11/17 Срд 08:42:36 #8 №1095941 
Сичиач, разьясни мне зачем кармак запилил два отдельных аллокатора и чем hunk лучше чем zone?

https://github.com/id-Software/Quake-III-Arena/blob/master/code/qcommon/common.c#L1193
Аноним 22/11/17 Срд 12:39:08 #9 №1096014 
>>1095913
>2) Если уж юзаешь маллок, влепи каст к (char *).
что енто значит? ет не плюсы, просто на сайте почему-то cpp не обращай внимание
Аноним 22/11/17 Срд 13:00:19 #10 №1096025 
>>1096014
значит переменная не в начале блока объявлена и это < c99
Аноним 22/11/17 Срд 13:44:09 #11 №1096031 
А почему sprintf сводит в ноль значение в переменной?

char a[2];
int b = 10;
sprintf(a, "%d", b);
printf("%d\n", b); // 0

Нахуй так делать? Может я где-то ошибаюсь?
Если заслать ему const, то всё нормально кстати. Но для меня это не решение.
Аноним 22/11/17 Срд 13:49:54 #12 №1096033 
>>1096031
прост)
как же ты заебал, даун.
Аноним 22/11/17 Срд 14:30:08 #13 №1096056 
>>1096031
>почему sprintf сводит в ноль значение в переменной?
Схуяль? https://ideone.com/MQcxI6
Аноним 22/11/17 Срд 14:38:54 #14 №1096058 
>>1096033
> прост)
Ещё и даунами кого-то называет.

>>1096056
Разобрался. Если объявить "b" перед "a", то будет ноль. Причём на ideone и в таком случае всё нормально, а вот у меня на комплюхтере не нормально.
clang 3.8.1-24
Аноним 22/11/17 Срд 14:39:41 #15 №1096059 
>>1096056
что, тож даун, очевидно что в младший байт его числа записался завершающий \0. компилируйте уже через gcc, там хоть чаще падать будет из за защиты стека.
Аноним 22/11/17 Срд 14:53:45 #16 №1096068 
хотя, это наверно от системы зависит... но я помню читал, на винде что-то же было подобное, может в vc.
Аноним 22/11/17 Срд 14:58:51 #17 №1096071 
Вот ведь вам делать же нечего, дорогие С-разработчики. Для вас даже создание строки на хипе - это уже проблема, в то время как все остальные об этом даже не задумываются. Вы хоть сами понимаете, как низко вы пали, со своим устаревшим на десятки лет языком программирования?
Аноним 22/11/17 Срд 15:05:33 #18 №1096072 
>>1096068
> хотя, это наверно от системы зависит... но я помню читал, на винде что-то же было подобное, может в vc.

Довен, у тебя массив утек, sprintf записал в a[2] терминирующий ноль следом за двумя цифрами, компилятор в стеке разместил b следом за массивом. И терминирующий ноль у тебя записался в b.

>>1096068
>хотя, это наверно от системы зависит

Да, довен, зависит. От endiannes процессора. На штеудах байты идут в памяти от младшего к старшему, на коком-нибудь PowerPC ты бы долго думал что у тебя все в порядке.
Аноним 22/11/17 Срд 15:09:24 #19 №1096074 
>>1096071
>Для вас даже создание строки на хипе - это уже проблема

Для тебя, довен, это действительно проблема.

> в то время как все остальные об этом даже не задумываются

Ога, core i7 с 64гб памяти будет достаточно каждому для запуска калькулятора, как же, слышали-слышали.

> Вы хоть сами понимаете, как низко вы пали, со своим устаревшим на десятки лет языком программирования?

шел бы ты отсюда, скриптушок. У нас тут эффективные программы, бекэнды, операционные системы и прочие высокоэффективные вещи пишут. Со своими дружками-скриптушками в другой тред иди пердолиться.
Аноним 22/11/17 Срд 15:13:06 #20 №1096077 
>>1095941

Hunk - это чтобы такой выделять-выделять, а затем прибить все разом. Для больших данных - карта там текстурки, модельки.

Zone - такой обычный велосипедный malloc повер большого куска уже выделенной при запуске памяти. Для всякой текучки. Я не понимаю чего там непонятного, по твоей ссылке там все очевидно на уровне хеллоуворлда.
Аноним 22/11/17 Срд 15:17:48 #21 №1096080 
>>1096072
тут даже читать не умеют. нахуй ты мне это всё написал - загадка истории.
Аноним 22/11/17 Срд 15:20:27 #22 №1096081 
>>1096072
> компилятор в стеке разместил b следом за массивом. И терминирующий ноль у тебя записался в b.
Да кстати, разумно, так оно и было.

>>1096031-кун

> прост
> даун
> довен
Но это конечно совсем пиздец. Мочан во всей красе.
Аноним 22/11/17 Срд 15:52:35 #23 №1096094 
>>1095842
В этом и челлендж, руки и мозги должны быть, кто хочет просто писать говно для заработка бабосиков и думать, что он крут и 300к в секунду цель его жизни, то пусть топает в иные языки ну или просто в жопу.
Аноним 22/11/17 Срд 15:58:23 #24 №1096100 
>>1095842
> А как вообще программировать на С и при этом не косячить, если компилятор проглатывает практически любой код, даже такой, который очевидно ошибочен?

Сорцы линух кернела почитай, ну или там кваки iii кою тут вывесили.
Аноним 22/11/17 Срд 16:13:14 #25 №1096108 
>>1095677 (OP)
посоветуйте что нибудь написать на си , знаю глупая просьба, но я сам учусь и по книгам надоело хочу написать что свое что, но знаю что, а то из-за соло обучения скоро депрессия сожрет
Аноним 22/11/17 Срд 16:24:02 #26 №1096116 
>>1096108
арифметику безграничной длины. сложение, вычитание, деление, умножение - соответственно и сдвиги.
sageАноним 22/11/17 Срд 17:56:38 #27 №1096165 
>>1096014
Окей, если ты хочешь кодить на плюсах, как на Си по давно протухшим статьям, посмотри внимательно на свой же скриншот, тебе там компилятор волшебный ключик подсказал в скобочках.
Аноним 22/11/17 Срд 21:15:40 #28 №1096274 
Безымянный.png
Я только начинающий и столкнулся с проблемой, суть её представлена на скриншоте. Как видно, в результате нескольких арифметических операций число теряет своё значение. Я ожидал что уже после первого умножения число станет равным 122.000060. Та же проблема наблюдаются и при преобразовании типов.
Каким образом можно решить данную проблему? Использование только целочисленной арифметики, написание специальных функций или существуют особые ключи для компилятора?
Аноним 22/11/17 Срд 21:33:16 #29 №1096285 
>>1096274
> Каким образом можно решить данную проблему?
Округлять, менять методы вычисления, использовать типы с большей мантиссой (double, long double).
https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ - скроллим чуть-чуть вниз, там список статей, которые категорически рекомендуются при попытках писать что-либо с использованием арифметики с плавающей точкой.
Аноним 22/11/17 Срд 21:49:55 #30 №1096291 
>>1096274
> Я только начинающий и столкнулся с проблемой, суть её представлена на скриншоте. Как видно, в результате нескольких арифметических операций число теряет своё значение. Я ожидал что уже после первого умножения число станет равным 122.000060. Та же проблема наблюдаются и при преобразовании типов.

Добро пожаловать в мир байтов.

В мире байтов разряды у чисел не 1,10,100,100 и 0.1, 0.01, 0.001

а 2 4 8 16 32 и 1/2, 1/4, 1/8, 1/16 соответсвенно. И с числами, не кратными 1/степень двойки будут всегда проблемы.

https://www.youtube.com/watch?v=PZRI1IfStY0
Аноним 22/11/17 Срд 22:43:04 #31 №1096314 
>>1096291
> В мире байтов разряды у чисел не 1,10,100,100 и 0.1, 0.01, 0.001
На самом деле, в IEEE 754 (и, сооответственно, в Си) допускается существование чисел с плавающей точкой с FLT_RADIX=10 - реализуй такое в железе или софтфлоат в компиляторе, и будут тебе 0.1. Но на практике, да, в большинстве случаев везде FLT_RADIX=2.
Аноним 22/11/17 Срд 23:09:13 #32 №1096320 
Хочу реализовать уже наконец длинную арифметику на C.
В интернете встречал два подхода:
1. Лезть в байты, арифметические функции с нуля, так сказать, даже "+" нинужны.
2. Реализация, которая базируется на стандартных "+", "*".
Имеет ли смысл лезть в (1)? Или на (2) готовые функции на ассемблере всё равно опередят?
Если захочу в (1), то "Алгоритмические трюки для программистов" - то, что надо?
Аноним 23/11/17 Чтв 00:00:09 #33 №1096346 
>>1096320
> арифметические функции с нуля
Лолшто? Ты хочешь реализовывать побитовую арифметику софтом на ксорах и вручную перенос в каждый бит добавлять? Какой в этом практический смысл?

> Реализация, которая базируется на стандартных "+", "*".
Есть стандартный стул: берешь stdint.h, берешь какой-нибудь uint, работаешь, соответственно, со словами. Слова хранишь в массивах, little endian (слова, а не байты одного слова!), бегаешь по этим массивам быстро и комфортно.
Аноним 23/11/17 Чтв 08:48:12 #34 №1096406 
>>1096346
А как я могу, допустим, поксорить элемент произвольной длины, если у меня есть указатель на него и его размер?
Аноним 23/11/17 Чтв 08:54:53 #35 №1096409 
Алсо, есть что противопоставить NumPy в плане визуализации результатов экспериментов (графики, диаграммы)? Такая же удобность, конечно, не нужна, но чтобы хотя бы была возможность на экран вывести.
Аноним 23/11/17 Чтв 13:43:19 #36 №1096527 
>>1096346
Он спрашивал длинную арифметику, это где флаг переполнения проверяют. Carry Flag то есть.
Аноним 23/11/17 Чтв 16:34:59 #37 №1096616 
>>1096320

3. Запилить арифметику на BCD.

П.2 ты не сделаешь по причине отсутсвия доступа к флагам переполнения на чистых сях. Изи делается на ассемблере.
Аноним 23/11/17 Чтв 18:36:30 #38 №1096688 
>>1096616
>П.2 ты не сделаешь по причине отсутсвия доступа к флагам переполнения на чистых сях.
Это не так. Как минимум можно просто считать старший разряд битом переноса.
Аноним 23/11/17 Чтв 18:57:37 #39 №1096697 
05528acf39211030293de3255d0a3fbf.jpg
>>1096527
>это где флаг переполнения проверяют
Нет, так поступают только говномесы. Использование флага C и инструкций adc не позволяет использовать векторные операции над массивом данных, которые выполняются мгновенно. Поэтому в одном разряде числа хранятся числа в таком диапазоне, чтобы переполнение не возникало. При этом флаг C не используется вообще, и число дробится на увеличенное число Chunk'ов (увеличено за счет уменьшения диапазона значений разрядов).
Аноним 23/11/17 Чтв 19:07:13 #40 №1096699 
05528acf39211030293de3255d0a3fbf.jpg
>>1096697
Иначе говоря, если число дробится на chunk'и по одному байту, то в этом байте используется не весь диапазон, а только 5 битов. При таком подходе переполнение не возникает вообще, и операция adc не нужна. Проблема здесь в том, что векторные операции отбрасывают флаг C.
Аноним 23/11/17 Чтв 19:39:15 #41 №1096712 
BattleAngelAlita.jpg
А ещё я сосу хуи.
Аноним 23/11/17 Чтв 19:41:18 #42 №1096716 
05528acf39211030293de3255d0a3fbf.jpg
>>1096712
Ты, может, и сосешь, а я предпочитаю тянок.
Аноним 23/11/17 Чтв 20:04:00 #43 №1096732 
А ведь, если подумать, я и сам непрочь соснуть хуйца. Такого сочного, жилистого, горячего.
Анонимус
Аноним 23/11/17 Чтв 20:21:05 #44 №1096748 
>>1096406
> как я могу, допустим, поксорить
С чем поксорить? С другим подобным? Просто ксоришь побайтово или пословно, пока один из массивов не кончится.

>>1096527
Я про длинную арифметику и отвечал. Просто я так понял, он хочет по битам считать, и проверять флаг каждый бит. А можно по словам считать, и переполнением заниматься каждое слово.
Аноним 23/11/17 Чтв 22:40:24 #45 №1096888 
>>1096732
А что в этом приятного?
Аноним 24/11/17 Птн 19:37:26 #46 №1097325 
напомните как инициализировать переменную как int и одновременно как char
Аноним 24/11/17 Птн 20:42:49 #47 №1097344 
>>1097325
union foo
{
int foo_int;
char foo_char;
}
И это твой тип новый.
Аноним 24/11/17 Птн 20:56:47 #48 №1097346 
>>1097344
спасибо
Аноним 25/11/17 Суб 04:31:11 #49 №1097504 
>>1095842
Мимо напомнило. Пилил руками транслятор, над каждой функцией в комментариях ставил соответсвующее правило на манер Exp = Term {('+' | '-') Term. В одном месте забыл про //, и нихуя сожрал всё, только много странных предупреждений выдал.
Аноним 26/11/17 Вск 11:20:57 #50 №1097966 
бамп
Аноним 26/11/17 Вск 11:43:49 #51 №1097968 
>>1095842
Очевидно, обмазываться разными инструментами, которые призваны облегчить жизнь C/C++ разработчика.
valgrind, clang-analyzer, pvs studio - вот это все
Аноним 26/11/17 Вск 11:51:00 #52 №1097971 
>>1095677 (OP)
Есть ли разница между static и static inline функциями?
Аноним 26/11/17 Вск 12:10:06 #53 №1097977 
>>1097971
есть, первая ссылка в гугле: https://www.greenend.org.uk/rjk/tech/inline.html
Аноним 27/11/17 Пнд 05:02:49 #54 №1098556 
image.png
Недавно наткнулся на волшебную тулзу - Process Hacker. Трейсит практически все что можно на венде, поэтому я узнал про такую штуку как сервисы типа драйверов.

Судя по всему именно сюда прописыват себя вся первоклассная малварь (на этапе работы), ибо найти эти сервисы можно только в реестре, либо с помощью той же тулзы.

У рихтера почти ничего нет про это, мс предлагает качать последнюю WDK и идти по туториалам.
Может тут сможет кто подсказать где искать материал?
писал только обычный сервис на крестах
Аноним 27/11/17 Пнд 05:38:40 #55 №1098561 
>>1098556
>Недавно наткнулся на волшебную тулзу - Process Hacker. Трейсит практически все что можно на венде, поэтому я узнал про такую штуку как сервисы типа драйверов.
в сервисах не показывается?
Аноним 27/11/17 Пнд 05:48:32 #56 №1098565 
image.png
>>1098561
Нет, в services.msc показывает только выделенное.
Аноним 27/11/17 Пнд 10:14:48 #57 №1098596 
есть какая-нибудь вики/референс мануал с поиском, чтобы удобно было листать прямо во время кодинга?
Аноним 27/11/17 Пнд 13:15:00 #58 №1098633 
Поступило предложение на вакансию в сбере, требуют знание чистого С, и С++ вдобавок. Но как я понимаю от С++ там только малая часть в основном это С с классами, что меня очень устраивает, и сразу говорит о высоком уровне разработчиков.
Кто в теме вообще по этой вакансии, там я как понял щас идет массовый набор?
Аноним 27/11/17 Пнд 15:16:37 #59 №1098695 
>>1098596

очевидный cppreference.com
Аноним 27/11/17 Пнд 16:20:26 #60 №1098739 
>>1095677 (OP)
Где можно достать тулчейн с компилятором gcc version 4.2.0 20070413 (prerelease) (CodeSourcery 2007q1-21. Marvell GCC-4.2.0 201111.12345)) для сборки ядра линукс 3.0.0 под ARM?
Аноним 27/11/17 Пнд 16:48:28 #61 №1098778 
const int a = 1;
const int b = a * 2;

clang на маке компилирует, а msvc на вниде или gcc (4.8.4) на убунте ругаются на
>initializer element is not constant

Собственно, с какого перепугу он не константа-то? Как починить? static дела не меняет.

И ещё относительно связанный вопрос: как можно во время компиляции записать в константу результат (чистой) функции? Квадратный корень числа получить надо, поэтому вручную все действия расписай (через макро, например) не особо получится.
Аноним 27/11/17 Пнд 16:55:28 #62 №1098783 
>>1098739
Какой-то ебанутый вопрос.
Почитай лучше это: http://xyproblem.info/
Аноним 27/11/17 Пнд 16:59:22 #63 №1098789 
>>1098778
Попробуй повыставлять разные стандарты и расширения в компиляторах.
Аноним 27/11/17 Пнд 17:00:42 #64 №1098791 
>>1098778
>с какого перепугу он не константа-то
Это лишнее, погуглил уже.

Короче говоря, могу я как-то произвести вычисления некоторые во время компиляции для статичных констант?
Аноним 27/11/17 Пнд 17:02:23 #65 №1098796 
>>1098791
Попробуй constexpr.
Аноним 27/11/17 Пнд 17:07:06 #66 №1098802 
>>1098789
Да я уже нашёл, что я не так понимал слово "constant" в ошибке, там именно constant expression нужен, стандарты/расширения не помогут, это clang "особенный".

>>1098796
А мы же, вроде, в си-треде, а не плюсах?
Аноним 27/11/17 Пнд 17:16:14 #67 №1098806 
>>1098802
Точняк лол. Тогда макросы.
Аноним 27/11/17 Пнд 17:19:24 #68 №1098808 
MadeinAbyss.jpg
>>1098783
>Какой-то ебанутый вопрос.
Мы занимаемся реверсом прошивки. Модули ядра написаны под kernel 3.0.0, собранного под ARM.
Аноним 27/11/17 Пнд 17:22:24 #69 №1098810 
made in abyss2.jpg
>>1098808
И нам нужно собрать ядро версии 3.0.0 под ARM, чтобы запихать его и модули ядра в отлачик и по стеку вызовов определить, откуда вызывается очень интересная для нас функция и что в нее передается.
Аноним 27/11/17 Пнд 17:29:34 #70 №1098814 
>>1098810
Ясно, т.е. вам нужно чтобы ABI той же версии было. Хуй знает, а эти CodeSourcery не дают доступ к исходникам своей бадяги? Можно было бы нужную версию скомпилировать.
Аноним 27/11/17 Пнд 17:55:26 #71 №1098844 
>>1098596
> Может тут сможет кто подсказать где искать материал?
Zeal

>>1098778
Констант в Си почти нет. const задает тип доступа в рантайме, а не то, что принято считать константой в других языках (собственно, тебе и ругается, что ты инициализируешь одну переменную значением другой переменной, а инициализировать можно только константным выражением). Если не можешь что-то вычислить простой арифметикой в макросе - используй кодогенерацию или C++. На самом деле, любой уважающий себя компилятор и сам отлично свернет sqrt(константа) в вычисленное значение на этапе компиляции, но полагаться на это без проверки не стоит.

>>1098810
Да возьмите обычный ARM-ассемблер какой-нибудь fasm, точнее fasmarm умеет ассемблировать "поверх" файла, хукните свою интересную функцию прямо в бинарнике, сдампите обычным printk параметры и LR. Дел - на 20 минут, и никакой возни со сборкой.
Аноним 27/11/17 Пнд 17:59:55 #72 №1098851 
Почему ебучий кланг прпоускает этот код тогда? (который const int b = a * 2;)
Аноним 27/11/17 Пнд 18:03:42 #73 №1098866 
>>1098851
Потому что расширения. Можешь считать, что это баг.
Аноним 27/11/17 Пнд 18:05:30 #74 №1098871 
>>1098866
Но даже с -std=c89/c11 -pedantic пропускает, как это расширение отключить то?
Аноним 27/11/17 Пнд 18:09:22 #75 №1098879 
>>1098844
>Да возьмите обычный ARM-ассемблер какой-нибудь fasm, точнее fasmarm умеет ассемблировать "поверх" файла, хукните свою интересную функцию прямо в бинарнике, сдампите обычным printk параметры и LR. Дел - на 20 минут, и никакой возни со сборкой.
Можешь описать подробнее?
Аноним 27/11/17 Пнд 18:12:38 #76 №1098884 
1444438163166025395.jpg
Из документации:

However, Clang is more strict than other popular compilers, and may reject incorrect code that other compilers allow.

Они там что, охуели?
Аноним 27/11/17 Пнд 18:13:18 #77 №1098885 
made-in-abyss.png
>>1098808
>>1098810
А именно, у нас есть модуль supplies.ko с очень интересной функцией, которая получает данные, в формате которых нужно разобраться. Сейчас известно немногое: например, поля в дампе, где содержится чек-сумма. Мы хотим раскрутить эту функцию, чтобы узнать назначение всех полей в данных. Пока мы договорились до возможности все это дело проэмулировать, но для этого надо собрать ядро.

Аноним 27/11/17 Пнд 18:30:42 #78 №1098909 
wince.png
>>1098879
> Можешь описать подробнее?
Ну, если у тебя есть рабочая прошивка и железка:
Читаешь любую статью по хукам в Windows (их овердохуя). Делаешь то же самое в прошивке: ищешь пустое место (длинный ненужный текст, неиспользуемую функцию, можно даже "ненужную" функцию, их дохуя в ядре - втыкаешь возврат в начало, остальные байты твои) - будешь там хранить свой код. Воруешь из интересующей тебя функции несколько инструкций, на их место втыкаешь безусловный переход на свой код, твой код дампит все, что тебя интересует, под конец выполняет украденные инструкции и возвращается на следующую после украденной. Возможны варианты.
Пикрелейтед - подобный хук, дампивший RSA-ключи из одной софтины под WinCE прямо во время инициализации библиотеки, работающей с длинными числами. Вместо того, чтобы долго и мучительно искать два десятка ключей в каждой новой версии покриптованного бинарника, мы патчили программу по сигнатурам, и ключи самостоятельно укладывались штабелями в txt-файл рядом с ней.
Аноним 27/11/17 Пнд 18:33:25 #79 №1098915 
>>1098885
Блин, не увидел сообщения. Ну у вас немного не тот случай, да. Можно заняться инструментированием по-крупному (не вручную). Правда, тут уже может оказаться быстрее собрать ядро.
Аноним 27/11/17 Пнд 19:58:41 #80 №1098997 
>>1098909
>2017
>не использовать дефайны для регистров
sageАноним 27/11/17 Пнд 20:12:23 #81 №1099017 
>>1098997
Какие именно дефайны и зачем они в коде, написанном на скорую руку? Там даже GetProcAddress на каждый вызов заново делается, потому что возиться было лень. Алсо, это совсем не 2017, а скорее где-то 2009.
Аноним 27/11/17 Пнд 20:15:33 #82 №1099023 
3453254.png
>>1099017
Открываешь такой через неделю код
@
Не понимаешь что там происходит
@
Удаляешь все нахуй
@
Делаешь заного


>True story
Аноним 27/11/17 Пнд 20:16:09 #83 №1099026 
Аноны, при создании char-массива, т.е.
char array[5];
нуль-терминатор (\0) автоматически добавляется в последний элемент массива? Т.е. в a[4] уже записывается \0, как только я пишу char array[5]?
Аноним 27/11/17 Пнд 20:18:13 #84 №1099030 
>>1099026
Нет.
sageАноним 27/11/17 Пнд 20:26:27 #85 №1099051 
>>1099026
Терминатор "автоматически" добавляется только в строковый литерал (например, "test" - это { 't', 'e', 's', 't', '\0' }). В том числе, когда ты инициализируешь им свой массив char[5].
Аноним 27/11/17 Пнд 20:36:16 #86 №1099066 
>>1099051
Хорошо. Тогда, например, создаю char array[5];
затем заполняю его символами с помощью scanf
Во-первых, какой формат ввода нужно использовать в scanf? %c или %s? И как вообще заполнять массив через scanf? Можно увидеть коротенький пример?
Аноним 27/11/17 Пнд 20:50:35 #87 №1099087 
>>1099066
%c читает и присваивает один символ. %s присваивает последовательность символов до первого пробельного символа или пока не превышен лимит (например, %4s). При этом %s допишет \0 автоматически (т.е., для %4s массив должен вмещать минимум 5 элементов). Алсо, если тебе нужно ввести кусок строки с пробелами, можно задавать наборы символов - какое-нибудь %4[^\n] то же, что %s, но читает до конца строки, а не до первого пробела. И вообще, http://en.cppreference.com/w/cpp/io/c/fscanf
Аноним 27/11/17 Пнд 21:02:03 #88 №1099093 
>>1099087
Спасибо за пояснение. Теперь стало понятнее.
"%s присваивает последовательность символов до первого пробельного символа или пока не превышен лимит (например, %4s)"
А Enter прерывает ввод аналогично пробелу?
Аноним 27/11/17 Пнд 21:16:04 #89 №1099101 
>>1099093
Да, Enter, Tab - вообще всё, что isspace().
Аноним 27/11/17 Пнд 21:31:10 #90 №1099120 
>>1099101
Хм, тогда почему в таком коде программа падает при после ввода строки? Ввожу однозначное или двузначное число, например, 5 или 14, нажимаю Enter, получаю виндовое сообщение об ошибке, типа, "Прекращена работа программы...".
int main () {
char b[3];
scanf_s ("%s", b);
printf ("%s\n", b);
return 0;
}
Аноним 27/11/17 Пнд 21:41:10 #91 №1099129 
for(i = 0; i > var1 + var2; i++)

Компилятор вычислит значение "var1 + var2" один раз, или будет это делать в каждой итерации?
Будет ли правильным создать ещё одну переменную перед циклом, "var3 = var1 + var2;", и использовать её в условии?
Аноним 27/11/17 Пнд 21:43:55 #92 №1099136 
>>1099129
var1+var2 вычислит один раз.
Можно создать var 3 перед циклом и использовать ее в условии - разницы никакой
Аноним 27/11/17 Пнд 21:48:27 #93 №1099144 
>>1099120
> scanf_s
Потому что:
1) #define _CRT_SECURE_NO_WARNINGS.
2) Не используй никогда scanf_s и все прочие _s. Их обещали выпилить из C2x.
3) Если уж используешь, читай справку. У scanf_s на каждый спецификатор нужно ДВА аргумента. Первый - указатель на переменную, как в scanf. Второй - максимальный размер.

>>1099129
Стандарту определяет "наблюдаемое поведение": выражение вычисляется каждый раз. Если ты не можешь никак увидеть, что реальное поведение как-то отличается (например, в твоем случае никаких побочных эффектов от вычисления выражения до цикла не будет), тогда компилятор может оптимизировать, а может и не оптимизировать. Можешь надеяться, что такое простое выражение он проглотит, но вот если у тебя там есть что-либо сложнее strlen, лучше создавать переменную. Например, так: for (int i = 0, n = var1 + var2; i < n; i++). Или использовать цикл с декрементом, если тебе похуй на порядок for (int n = var1 + var2 - 1; n >= 0; n--) (хотя тут нужно думать уже - можешь только еще сильнее отсосать по скорости из-за кэша).
Аноним 27/11/17 Пнд 21:52:01 #94 №1099145 
>>1099120
Алсо, я тебя наебал про %с в scanf. Я тут полез в справку и внезапно узнал, что оно тоже умеет читать несколько символов, но только указанное количество (%c - 1 символ, %3с - 3 символа), и НЕ дописывает \0 в конец.
Алсо, >>1099144 тут я тебя тоже наебал. Второй аргумент с размером нужен только для спецификаторов %s %[] и %c. Никогда этим говном не пользовался.
Аноним 27/11/17 Пнд 21:54:09 #95 №1099146 
>>1099144
>Их обещали выпилить из C2x
Кто обещал?
И когда этот стандарт выйдет?
sageАноним 27/11/17 Пнд 21:56:11 #96 №1099147 
>>1099146
> Кто обещал?
Комитет по стандартизации. Потому что это хуйня, интересная только Microsoft и попавшая в стандарт под ее давлением.

> И когда этот стандарт выйдет
С99 вышел в 1999. C11 вышел в 2011. Используй логику, чтобы понять, когда выйдет C2x.
Аноним 27/11/17 Пнд 22:01:00 #97 №1099152 
>>1099145
аа, так вот почему у меня программа падала. Спасибо, тогда буду онли использовать scanf, вместо scanf_s. А можно еще за \0 пояснить? Что будет, если его не дописывать в конец массива? Ну, допустим буду заполнять через %c. Или это уже совсем другая тема и лучше сейчас этим не заморачиваться?
Аноним 27/11/17 Пнд 22:03:11 #98 №1099155 
Котаны, у меня есть ~200 разных файлов следующего содержания:

#define FILE_(номер файла) (размерность массива)

int myfunc(double (звездочка)x, бла-бла)
{ бла-бла}

Также есть один на всех main-файл. Хотелось бы переписать его так, чтобы он по очереди запускал каждый из двухсот файлов, получал некоторый результат и записывал его в выходной файл (выходной файл тоже один на всех).
Как это можно сделать?
Аноним 27/11/17 Пнд 22:07:03 #99 №1099162 
>>1099147
>Комитет по стандартизации.
Где можно ознакомиться с обещаниями?
>С99 вышел в 1999. C11 вышел в 2011. Используй логику, чтобы понять, когда выйдет C2x.
C++0x тоже обещали в нулевых, а вышел он аж в 2001 году. Стандарт не принимают каждое десятилетие, а по мере необходимости. Си не особо живой язык, новый стандарт никому не нужен, учитывая, что C11 спустя 6 лет после выхода полностью реализован только в одном компиляторе - Clang/LLVM
Аноним 27/11/17 Пнд 22:07:33 #100 №1099163 
>>1099162
>а вышел он аж в 2001 году
В 2011, конечно.
sageАноним 27/11/17 Пнд 22:13:57 #101 №1099173 
>>1099162
> Где можно ознакомиться с обещаниями?
Знакомство осуществляется копанием тут: http://www.open-std.org/jtc1/sc22/wg14/

> новый стандарт никому не нужен
Многие считают по-другому. Я, например, атрибутов жду. И где-то в 21-22 году стандарт должен выйти, а к 25-26 можно будет даже начинать ими пользоваться, лол.

>>1099155
Выкинь впизду дефайны, сделай структуру, описывающую имя (если нужно) и параметры файла (размерность, или хуй знает, что там у тебя), сделай массив таких структур. В рантайме в цикле иди по массиву, открывай и обрабатывай в соответствии с указанными параметрами каждый файл.
Аноним 27/11/17 Пнд 22:27:24 #102 №1099182 
>>1099173
Это вариант, но я не хотел так делать из-за "раздутия"исходного кода.
Каждый файл -- некоторый ОГРОМНЫЙ функционал. В нынешней тестовой версии самый большой из них занимает 270 страниц двенадцатого вордовского текста и нихуя не работает работает, но в ожидании ответа я успею умереть, самый маленький -- страниц 20.
Скорее всего для ускорения придется дописывать некоторую вспомогательную ерунду, из-за которой каждый файл еще вдвое увеличится в объеме.
Получится даже не "Война и мир", а какая-то ебучая Британника.
sageАноним 27/11/17 Пнд 22:32:26 #103 №1099183 
>>1099182
Попробуй русским языком более полно описать то, чего ты хочешь. Никакого раздутия исходного кода быть не может. Либо у тебя массив с параметрами, либо массив указателей на параметры или колбеки (а параметры и вспомогательные функции в отдельных файлах). Никакие дефайны там не нужны. Ну разве что для создания похожих элементов массива.
Аноним 27/11/17 Пнд 22:43:19 #104 №1099185 
>>1099183
Я тебя кажется понял. Извини за предыдущий дурацкий комментарий.
Аноним 27/11/17 Пнд 23:40:18 #105 №1099214 
dot = 1;
for (unsigned int i = 0; i < strlen(valinstr); i++) {
if ((i == dot) && (i>0)) {
continue;
}
else {
printf("i = %d\n", i);
dig = TO_DIGIT(valinstr);
val += TO_DEC(dig, powerint);
powerint--;
}
}

В данном фрагменте кода видно, что dot = 1;
В цикле, в условии if сказано:
if ((i == dot) && (i>0)) {
continue;
}

То есть, когда i == 1, то должна быть следующая итерация цикла, т.е. i == 2. В дальнейшем уже постоянно должно выполняться условие else.
В консоли должно выводиться:
i = 0
i = 2
i = 3

И так далее...
Однако, в действительности, я вижу
i = 0
i = 1
i = 2
i = 3

Т.е. i = 1 не должно выводиться, так как итерация цикла c i == 1 пропускается с помощью continue.
Подскажите, в чем проблема
Аноним 27/11/17 Пнд 23:40:46 #106 №1099215 
>>1099214
бля, извиняюсь, сейчас фиксану
Аноним 27/11/17 Пнд 23:42:30 #107 №1099216 
>>1099215
dot = 1;
for (unsigned int i = 0; i < strlen(valinstr); i++) {
if ((i == dot) && (i>0)) {
continue;
}
else {
printf("i = %d\n", i);
dig = TO_DIGIT(valinstr);
val += TO_DEC(dig, powerint);
powerint--;
}
}
В данном фрагменте кода видно, что dot = 1;
В цикле, в условии if сказано:
if ((i == dot) && (i>0)) {
continue;
}
То есть, когда i == 1, то должна быть следующая итерация цикла, т.е. i == 2. В дальнейшем уже постоянно должно выполняться условие else.
В консоли должно выводиться:
i = 0
i = 2
i = 3
И так далее...
Однако, в действительности, я вижу
i = 0
i = 1
i = 2
i = 3
Т.е. i = 1 не должно выводиться, так как итерация цикла c i == 1 пропускается с помощью continue.
Подскажите, в чем проблема
Аноним 27/11/17 Пнд 23:48:34 #108 №1099219 
Я тут спросить хотел, может кто-нибудь сможет просто объяснить.
Хочу написать диспетчер задач для своего проекта в МКК. Просто микрик, я там сделал простецкое меню на указателях, и большая часть всего на костылях.

Тоесть функцию которая могла бы реагировать на разные события, и периодически сама добавляла те, которые должны быть опрошены по таймеру. Я конечно нашел нужные мне, уже сделанные, проекты на аврфрикс, под названием микроменю. Но я даже не могу построить модель этого в голове. Там кучи новых созданных структур, каким-то образом динамически подключаемые таймеры, обработчики событий, очереди, и все это обильно смазано огромным слоем указателей и переназначений. Я попросту нихуя не пойму, а коментарии только в заголовочном файле, сами функции почти не описаны.
Аноним 28/11/17 Втр 01:25:41 #109 №1099271 
>>1099216
В коде вроде бы все норм. Добавить в printf по else вывод dot. Может быть, ты его где-то повреждаешь, хуй знает.
Аноним 28/11/17 Втр 07:53:14 #110 №1099352 
>>1099271
Да, действительно. В том фрагменте кода, который я привел, должно быть все норм. То есть реализовал эту часть как отдельную программу - все норм работает. Тогда если не найду ошибку в фулл коде, то скину сюда
Аноним 28/11/17 Втр 08:02:16 #111 №1099355 
>>1099219
Начни с создания очереди сообщений в первом потоке (и единственном).
Аноним 28/11/17 Втр 11:50:09 #112 №1099421 
Почему игровые движки пишут на С++, но не на Сишечке больше?
Про кваку и дум не надо, тогда ещё динозавры по земле ходили.
Аноним 28/11/17 Втр 13:12:33 #113 №1099461 
>>1099421
Сам уже давно не увлекаюсь этим, но в студенческие годы пилил свой 3Д двиган.
Во-первых, выблядки из негрософта сделали D3D API на С++.
Во-вторых, некоторые и до сих пор видел пилят на С.
В-третьих, так принято в геймдеве.
В-четвертых, у многих и не только гейдевелов промыты мозги о всесильности и охуенности ОО подхода.
В-пятых, ОО подход действительно в геймдеве может успешно применяться.
В-шестых, никто не запрещает писать в Си стайле на С++ и пользоваться только самым необходимым из С++.
В-седьмых, просто куча либ и двиганов уже написана на С++ и он тащится как ебаное легаси.
Аноним 28/11/17 Втр 15:24:57 #114 №1099542 
Аноны, какой диапазон для целой и дробной части у типов float и double?
Вот, например, все мы знаем, что тип int занимает 4 байта = 32 бита. Следовательно, для unsigned int диапазон будет [0, +4 294 967 295], так как (2^32)-1 = 4 294 967 295. А для signed int диапазон значений равен [-2 147 483 648, +2 147 483 647].
Так вот, float занимает 4 байта, а double - 8. Но опять же, повторю свой вопрос: какой диапазон значений в целой и дробной части будет для каждого из них?
sageАноним 28/11/17 Втр 19:48:25 #115 №1099691 
>>1099461
> выблядки из негрософта сделали D3D API на С++
Лож-пиздеж. DirectX использует COM, а COM в Си отлично работает. Во-первых, тебе никто не мешает делать pDirect3DDevice->lpVtbl->DoSomething(pDirect3DDevice, ...), во-вторых, специально для тебя в DirectX до сих пор включают макросы типа IDirect3DDevice_DoSomething.

> так принято в геймдеве
Ложь-пиздежь. Существует дохуя игр, написанных на Си. Иногда со вкраплениями C++. Иногда на C++ в Си-стиле (даже без классов). Да, большинство таких игр выпущено до 2005, но они есть.

> ОО подход действительно в геймдеве может успешно применяться
Ты можешь пилить объекты на структурках и быть счастливым.
sageАноним 28/11/17 Втр 19:52:01 #116 №1099693 
>>1099691
Все твои выпады - полная хуйня.
Аноним 28/11/17 Втр 19:58:10 #117 №1099702 
>>1099691
Ладно, давай разберем тобою написанное.

1. Использовать уебищные костыли, когда можно нативно писать более менее нормально на С++ - бессмысленно и тупо.

2. Без пруфоф ты сам знаешь кто. Более того, это вообще ничего не значит. В геймдеве принято писать на С++ - это факт. Для пруфоф можешь зайти на любой геймдев форум.

3. Можешь. Я и не спорю. Только учитывая все то, вышеперечисленное, пишут те же объекты на С++.
Аноним 28/11/17 Втр 20:00:47 #118 №1099703 
>>1099702
>В геймдеве принято писать на С++ - это факт
они там впще ебанулись. нпхуй на конпелируемых языках писать что то кроме движка?
Аноним 28/11/17 Втр 20:03:44 #119 №1099706 
>>1099703
Так никто и не пишет.
Вся игровая механика и логика пишется на скриптовых языках типа луа или яваскрипта.
Аноним 28/11/17 Втр 20:07:27 #120 №1099709 
>>1099702
> какой диапазон значений в целой и дробной части будет для каждого из них
float как бы намекает, что это тебе не fixed-point, поэтому размеры целой и дробной части не фиксированы, и зависят исключительно от положения десятичной точки. В float тебя должны интересовать размеры мантиссы и экспоненты.

В 32-битных числах (float) на мантиссу выделено 23 бита (плюс один неявный), т.е., ты можешь без потерь представить все целые в диапазоне от 20 до 224 (дальше уже ты сможешь представить только некоторые целые), знак отдельно, на экспоненту, соответственно, остается 8 бит, но два значения забиты под специальные состояния, поэтому экспонента может быть от -126 до +127. В 64-битных (double) размер мантиссы и экспоненты 52+1 и 11 соответственно. Максимальные и минимальные значения можешь посчитать примерно как 2минимальная или максимальная экспонента, плюс существуют еще денормализованные значения с плавающей точкой для представления очень маленьких чисел.

>>1099542
> Использовать уебищные костыли, когда можно нативно
Твой нативный код развернется абсолютно в те же инструкции, что и сишный. Не вижу никаких костылей: COM - это ничего больше, чем просто указатели на функции, а указатели на функции в Си широко используются.

> Для пруфоф можешь зайти на любой геймдев форум
Зашел, там юнити с додиезами и JS. Составил впечатление, что геймдев - это додиез. Правильно?
Аноним 28/11/17 Втр 20:10:36 #121 №1099715 
>>1099709
> Не вижу никаких костылей
Твои проблемы.

>Правильно?
Нет.
Аноним 28/11/17 Втр 23:20:10 #122 №1099813 
Вообще не могу дупля отбить с этими рекурсиями. Они же должны как зеркало бесконечно отражаться, и виснуть в этих циклах. Как они вообще из них выходят?
Аноним 28/11/17 Втр 23:20:19 #123 №1099815 
>>1098633
хм, интересно, в сбертехе все на явке новое же пишется..
Аноним 28/11/17 Втр 23:21:15 #124 №1099817 
>>1099813
>и виснуть в этих циклах
и виснут
>Как они вообще из них выходя
по условию
Аноним 28/11/17 Втр 23:35:22 #125 №1099829 
>>1099817
А есть какой-нибудь простой пример реального использования?
Аноним 28/11/17 Втр 23:41:34 #126 №1099833 
>>1099829
Ну, например, обход директорий в файловой системе): функция обработает файлы в указанной директории, и, если в директории есть дочерние директории, вызовет себя же для их обработки, иначе НЕ вызовет, и эта ветка рекурсии закончится. Очевидно, что момент, когда вложенных директорий не будет, когда-нибудь обязательно настанет на самом деле, не совсем правда: есть всякие символические ссылки, которые могут ссылаться куда-нибудь выше текущей папки, и программа зависнет, если не знает об их существовании.
Аноним 28/11/17 Втр 23:48:16 #127 №1099838 
>>1099833
Теперь стало немного понятнее.

А промежуточные результаты оно в оперативку пинает?
Аноним 28/11/17 Втр 23:48:29 #128 №1099839 
>>1099833
> когда вложенных директорий не будет
if (child == NULL) return

а по ссылкам в линупсе не ходютъ
Аноним 28/11/17 Втр 23:49:31 #129 №1099840 
>>1099839
этому вот >>1099838
Аноним 29/11/17 Срд 14:09:00 #130 №1100052 
float var = 5.0;

void func(int i) { ... }
...
func((int)var);
------------------------
float var = 5.0;

void func() { int i = (int)var; ... }
...
func();


Будет ли разница в скорости выполнения?
Аноним 29/11/17 Срд 15:15:19 #131 №1100078 
1506783311219.jpg
О мудрецы, наставьте на путь истинный ИТТ.

Что общего и в чём различие языков C++, Visual C++ и C#, кроме названий?
Аноним 29/11/17 Срд 15:30:15 #132 №1100081 
>>1100078
>Что общего и в чём различие языков C++, Visual C++ и C#, кроме названий?
>пидарасы
>пидарасы
>пидарасы
Аноним 29/11/17 Срд 16:50:11 #133 №1100112 
Как разделить число на два целочисленных значения?
С двойкой все понятно: 2 / 2 = 1, то есть 1 и 1 будет.
Тройка: 3 / 2 = 1.5, а после каста к инту 1, то есть будет 1 и 1, а должно быть 2 и 1, или 1 и 2.

Думаю задача ясна. Необходимо самое быстродейственное решение.
Аноним 29/11/17 Срд 17:01:41 #134 №1100122 
>>1100052
Нет.

>>1100112
int n1 = (foo / 2);
int n2 = foo - n1;
Охуеть, правда?
Аноним 29/11/17 Срд 17:17:47 #135 №1100133 
>>1100122
> Охуеть, правда?
А то! Я бы условия хуячил. Спасибки.
Аноним 30/11/17 Чтв 06:15:29 #136 №1100385 
>>1100122
>Охуеть, правда
ебать ты маг
Аноним 30/11/17 Чтв 11:57:40 #137 №1100424 
>>1100081
Это понятно, а ещё?
Аноним 30/11/17 Чтв 14:48:19 #138 №1100494 
подскажите конструкцию автоматического дополнительного выделения памяти при заполнении массива текстом
типа если память заканчивается то реаллок еще скока-то
Аноним 30/11/17 Чтв 17:32:08 #139 №1100571 
>>1100494
Тебе куда-нибудь в менеджед языки. В Си ты решаешь вопросы памяти, язык за тебя ничего делать не будет. И тем более он никак не может узнать, что у тебя "память заканчивается". А вот сам ты можешь сделать функцию типа array_put, которая и будет заниматься мемори-менеджментом, если очередной элемент/элементы ей положить будет некуда.
Есть частные/частичные решения: например, в винде ты можешь зарезервировать большой кусок адресного пространства (память не тратится почти), в конец своего массива ставить страницу с PAGE_GUARD, отлавливать исключения и выделять еще памяти. Но это извращение с очень узкими юзкейсами.
Аноним 30/11/17 Чтв 21:20:08 #140 №1100691 
>>1100494
Это можно сделать, например, через связный список, выделяя память для узлов по мере надобности. При malloc еще нужно делать проверку на NULL, чтобы программа нормально завершилась при исчерпании памяти компа.
Аноним 30/11/17 Чтв 23:15:37 #141 №1100763 
Сап /pr. Помоги сделать задачку (на чистом C).
Данные о работниках хранятся в некоторой структуре. Одно из полей структуры имеет тип enum { ENGINEER, MANAGER, CEO} , размер структуры - size, а смещение поля enum относительно начала структуры равно off. Напишите функцию void apply_manager (void employees, int n, size_t size, size_t off, void (apply)(void*)) , которая по массиву сотрудников employees с кол-вом элементов n вызывает переданную в качестве параметра функцию apply , для каждого эл-та массива, описывающего сотрудника-менеджера. Элемент массива имеет тип описанной структуры, параметром функции apply является указатель на структуру.
Аноним 30/11/17 Чтв 23:33:43 #142 №1100768 
>>1100078
> C++
Гавно
> Visual C++
Блевотина
> C#
НИНУЖЕН
Аноним 01/12/17 Птн 14:39:06 #143 №1100980 
>>1100691
- пишешь функцию, в ней цикл
- гугли, как передать функции указатель на другую функцию
- в цикле вызываешь другую функцию по указателю на неё
Аноним 01/12/17 Птн 14:39:46 #144 №1100981 
Вот это:
>>1100980
Ответ на это:
>>1100763
Аноним 01/12/17 Птн 17:34:13 #145 №1101089 
Имеет ли смысл делать free непосредственно перед выходом из программы? Или пусть ОС сама разбирается?
Аноним 01/12/17 Птн 18:25:10 #146 №1101109 
>>1101089
Имеет. Наличие автоматического освобождения памяти зависит от конкретной ОС. Да и норм пацаны тебя будут считать жаба-макакой, который пишет говнокод.
Аноним 01/12/17 Птн 18:30:49 #147 №1101112 
>>1099421
Скорость и управляемость С и кое-какие инструменты для построения абстракций (классы, темплейты/стл) для ускорения разработки и структурирования больших объёмов кода. Типа на двух стульях усидеть пытаются.
Аноним 01/12/17 Птн 18:35:22 #148 №1101119 
>>1101089
Открой для себя https://phoxis.org/2011/04/27/c-language-constructors-and-destructors-with-gcc/
Аноним 01/12/17 Птн 19:06:39 #149 №1101136 
Аноны, пожалуйста, помогите. Вот пример кода:
int main () {
double value = 57.250000;
char val_str [100];
sprintf (val_str, "%f", value);
printf ("dlina stroki = %d\n", strlen (val_str));
return 0;
}

То есть, имеется число типа double. Перевожу его в строку с помощью функции sprintf. У меня, соответственно, переводится все это число, поэтому, когда я вывожу длину строки, то получаю dlina stroki = 9. Однако мне нужно сделать так, чтобы функция sprintf переводила в строку не 57.250000, а 57.25. Тогда будет dlina stroki = 5. Т.е. мне нужно сделать так, чтобы в строку переводились только значащие цифры, без лишних нулей в дробной части. Как это можно сделать? Писать отдельную функцию для удаления лишних нулей из строки не хочется.
Аноним 01/12/17 Птн 19:17:05 #150 №1101140 
>>1101109
Окей, спасибо.

>>1101119
У меня и не gcc, и я для питона расширение пишу, так что сомневаюсь, что это корректно работало бы.
Аноним 01/12/17 Птн 20:20:20 #151 №1101167 
>>1101089
>>1101109
Делать free() при выходе - это распространенная плохая практика: при free() куче приходится вытаскивать из свопа всякие давно забытые служебные данные, обрабатывать их, реорганизовывать кучу и делать множество других ненужных вещей, поэтому программа, выделяющая много небольших блоков памяти, будет тормозить при выходе, если делать "правильную" очистку. В то же время, если free() при выходе не делать, ОС может просто пометить соответствующие страницы памяти как пустые и завершить программу мгновенно.

Алсо, если у тебя короткоживущий процесс, который запускают для обработки чего-нибудь, есть смысл вообще никогда не делать free() для небольших блоков памяти, а когда обработка закончится - ОС за тобой приберет.

>>1101136
Простой способ: используй %g, укажи точность побольше (%.20g). Сложный способ: используй %g, вытащи из double экспоненту и посчитай, какая нужна точность, чтобы оно не переключилось на %e. Ну или нули обрезай, да.
Аноним 01/12/17 Птн 20:24:55 #152 №1101172 
>>1101136
> g — форматирует число с плавающей запятой в десятичной или десятичной экспоненциальной форме в зависимости от значения и точности
http://ru.cppreference.com/w/cpp/io/c/fprintf
Аноним 01/12/17 Птн 20:29:35 #153 №1101175 
>>1101167
>будет тормозить при выходе
С-с
ей богу, такая проблема. для больших программ более важно исполнение, а не запуск/терминейт.

а с боковой стороны, это ещё одна возможность проверить правильность своего кода.
Аноним 01/12/17 Птн 20:32:02 #154 №1101177 
>>1101175
Да-да, всегда очень сложно заставить себя переосмыслить что-то, вдолбленное на этапе обучения как best-practice.
Аноним 01/12/17 Птн 20:47:27 #155 №1101182 
>>1101177
да-да, так сложно заставить себя перестать компенсировать в интернете на незнакомых людях.
Аноним 01/12/17 Птн 21:57:30 #156 №1101238 
>>1101167
>при free() куче приходится вытаскивать из свопа
Где-то в 2k18 остался своп?
Аноним 01/12/17 Птн 22:11:31 #157 №1101251 
>>1101238
А куда он денется?
Аноним 01/12/17 Птн 23:13:56 #158 №1101291 
screen43.png
Хули оно в терминал срёт?

"&> /dev/null" же.
Аноним 01/12/17 Птн 23:20:19 #159 №1101297 
>>1101291
"2> /dev/null"

Вопрос снят.
Аноним 02/12/17 Суб 00:27:17 #160 №1101342 
Анончики, написал прогу по переводу из одной системы счисления в другую. Поддерживается диапазон систем счисления от 2 до 16. Максимально на ввод можно подавать строку из 13 символов. Вот исходник: https://github.com/Digitalvalues/num-sys/blob/master/source0
Если у кого-то есть время, пожалуйста, гляньте, скажите, что можно улучшить в плане памяти. То есть, в каких местах можно поработать с динамическим выделением памяти. А то я просто написал массивы, типа, char array[100]. Чтобы строка уж точно влезла. Так ведь неправильно делать? Нужно как-то через malloc? Я просто с этим еще толком не разбирался. Поэтому буду благодарен, если кто-то приведет хотя бы 1-2 примера переписанных строк моего исходника.
P.S. Если в коде почти ничего не понятно - могу закомментить его. Только попросите.
Аноним 02/12/17 Суб 01:41:50 #161 №1101368 
>>1101342
глядя на твой код, память это последнее, о чём тебе надо беспокоиться
Аноним 02/12/17 Суб 01:54:08 #162 №1101377 
>>1101342
Для начала разбей код, сделай больше функций. Эти простыни читать невозможно.
Аноним 02/12/17 Суб 14:18:10 #163 №1101520 
>>1101377
Можно поконкретнее? В основной части программы идет только проверка наличия точки в записи числа, а затем уже вызов нужных функций для перевода. Что подразумевается под словом "простыни"?
Аноним 02/12/17 Суб 16:42:50 #164 №1101585 
>>1101520
вроде не плохо , я сам тоже учу си , а про malloc
int a // указатель на будущий массив
n = 10// кол-во эл в массиве
a =(int
)malloc(nsizeof(int)); //выдляем памяти на 10 элементов по 4байта для каждой переменной типа int
for(size_t i=0; i<10;i++)
(a+i) =rand();
Аноним 02/12/17 Суб 16:44:16 #165 №1101587 
>>1101585
>>1101585
https://pastebin.com/pa5PPrgj
c непохереными указателями
Аноним 02/12/17 Суб 18:30:11 #166 №1101651 
>>1101587
Не понял смысл 3-ей строки. Там nsizeof? Нельзя же просто так переменную n перед функцией sizeof написать
Аноним 02/12/17 Суб 18:34:47 #167 №1101655 
>>1101651
Он умножение забыл, очевидно же. Но лучше приучиться делать malloc(n ∗ sizeof(∗a)), тогда, если вдруг захочется какой-нибудь long long в массиве хранить, не придется мучительно искать, где ты забыл поправить sizeof.
Аноним 02/12/17 Суб 18:54:17 #168 №1101666 
>>1101655
Хорошо. А как мы в этой строке a =(int )malloc(nsizeof(int)); преобразуем память в указатель? Вот, выделили мы 40 байт памяти. Как в указатель на int она конвертируется?
Аноним 02/12/17 Суб 18:58:01 #169 №1101667 
И еще вопрос: допустим, возьмем мою программу по переводу из одной системы счисления в другую. И попробуем перевести из 16 системы в 10 число 0.FF. Когда программа выполняется, я получаю ответ 0.996094. Хотя на самом деле должно быть 0.99609375. То есть в double типе после точки может быть только 6 цифр. Поэтому компилятор автоматически округляет 0.99609375 до 0.996094. Что делать? Как в дробной части можно получать больше, чем 6 цифр?
Аноним 02/12/17 Суб 19:01:51 #170 №1101674 
>>1101666
Там звездочки проебались. Хотя вроде итак понятно
Аноним 02/12/17 Суб 19:13:01 #171 №1101684 
>>1101667
Точность для %g указывай. Это ведь ты спрашивал? Или руками преобразовывай.
Аноним 02/12/17 Суб 19:26:53 #172 №1101691 
>>1101684
Я не понял. Причем тут %g? И как преобразовывать руками?
Повторюсь: допустим есть переменная double value.
И у меня написано
value = 15(1/16)+15(1/256);
printf ("value = %f\n", value);
Вывод будет 0.996094
Как получить 0.99609375?
Аноним 02/12/17 Суб 19:31:29 #173 №1101692 
>>1101691
Повторюсь: укажи блять точность! А %g у тебя или %f - не имеет значения.
printf ("value = %.72f\n", value);
Аноним 02/12/17 Суб 19:36:49 #174 №1101694 
>>1101692
А, понял, спасибо. Хотя странно, что это не делается автоматически. А сколько максимально может быть цифр в дробной части?
Аноним 02/12/17 Суб 19:44:52 #175 №1101701 
>>1101692
И еще, вот указал я точность %.72f. Он мне вывел 72 цифры после точки. Т.е. 0.9960937500000000000... Как сделать так, чтобы выводило только то количество цифр в дробной части, которые будут значащими. То есть если value = 0.1, то будет выводить 0.1, а если value = 0.11111111111, то будет выводить 0.11111111111
Аноним 02/12/17 Суб 19:49:58 #176 №1101702 
>>1101701
Находи остатки от деления на 10^x, где x-порядок интересующего разряда (целое).
И пока они не ноль, выводи остаток, умноженный на 10^-x, приведённый к целому типу)0000)))00000
sageАноним 02/12/17 Суб 20:00:10 #177 №1101707 
>>1101701
Вот буквально вчера говорилось: >>1101167 Это ведь ты и спрашивал?
Аноним 02/12/17 Суб 20:10:52 #178 №1101708 
>>1101707
Аааа, спасибо. Да это я и спрашивал. Но там был вопрос немного в другом - как от ненужных нулей избавиться. Поэтому просто написал %g вместо %f. Однако сегодня столкнулся с проблемой того, что если в дробной части больше 6 цифр, то %g так же, как и %f, округляет до 6 цифр после запятой. Сейчас еще раз перечитал тот пост и сделал по первому способу. (Т.е., например %.100g). Тогда у меня все работает, как надо. Спасибо еще раз, и сорян, если помучал вас тут вопросами
Аноним 02/12/17 Суб 20:12:27 #179 №1101709 
>>1101702
Спасибо, но подсказали еще получше альтернативный способ. %.100g
Аноним 02/12/17 Суб 20:25:38 #180 №1101715 
>>1101342
>Если в коде почти ничего не понятно
, значит его надо переписать, раз даже у написавшего его тебя появляются такие мысли.
Аноним 02/12/17 Суб 20:43:01 #181 №1101732 
>>1101715
Ну, я не знаю, как выглядят большие проекты. Но если посидеть минут 30 над моим исходником, то можно все понять
sageАноним 02/12/17 Суб 21:01:43 #182 №1101749 
>>1101708
Ну это на самом деле костыльный способ, потому что текстовое представление double может быть очень длинным (denormals, да и просто большие числа). Наслаждайся: https://ideone.com/JyE5Qp
Аноним 02/12/17 Суб 21:09:01 #183 №1101754 
>>1101732
Ох лол, ты больших проектов не видел. Больше читай исходников, набирайся опыта, как пишут другие.
Аноним 02/12/17 Суб 23:28:49 #184 №1101855 
>>1101749
да, я понимаю, что способ костыльный. Но ведь если double будет очень длинным. (очень маленькое число, как в твоем примере), то можно просто написать %.10000000000g. Мы ведь от этого ничего не потеряем? Ну, если число будет маленьким, то лишние нули он уберет, а если число будет очень маленьким (много цифр в дробной части), то оно все равно влезет в такой диапазон.
sageАноним 02/12/17 Суб 23:54:57 #185 №1101866 
>>1101855
> %.10000000000g
4000 с хуем символов - это минимум, который по стандарту должен поддерживаться всеми. Для double хватит (длиннее, чем в >>1101749 не сделать), а вот для long double уже нет.
Аноним 03/12/17 Вск 20:38:12 #186 №1102388 
Подскажите, почему double x = 14.000000000000 конвертируется в 13, а не в 14, при записи int(x)?
Аноним 03/12/17 Вск 20:47:02 #187 №1102400 
>>1102388
вопрос снят
Аноним 04/12/17 Пнд 01:36:49 #188 №1102553 
>>1095677 (OP)
почему sizeof(char) =1 byte, а sizeof(указатель на char) =4 byte& И вопрос как система понимает язык программирования что мы определяем переменную типа int и называем ее i ,так вот как это i связано с реальной памятью и что можно почитать на этот счет
sageАноним 04/12/17 Пнд 01:46:48 #189 №1102560 
>>1102553
> почему sizeof(char) =1 byte, а sizeof(указатель на char) =4 byte
Потому что один байт может принимать всего 256 значений, поэтому если указатель занимает один байт - он может адресовать лишь 256 байтов памяти. Если тебе нужно 4 гига, тебе понадобится больше байтов в указателе, чтобы хранить больше знеачений.

> система понимает язык программирования что мы определяем переменную типа int и называем ее i
Никак. Информация о типах по большей части теряется на этапе компиляции (остаются размеры), имена тоже теряются, вместо них компилятор выбирает позицию в памяти (или позицию относительно начала кадра стека), чтобы хранить переменную.
> что можно почитать на этот счет
"Код" Петцольда, потом Танненбаум, если осилишь.
Аноним 04/12/17 Пнд 01:50:33 #190 №1102561 
>>1102553
>почему sizeof(char) =1 byte
По стандарту. Вообще sizeof возвращает не в байтах, а в char-х, потому sizeof(char) всегда 1. Размер указателя диктуется архитектурой процессора.
char, по сути, это минимальный адресуемый кусок памяти. Название не очень удачное, но что поделать.

> И вопрос как система понимает язык программирования что мы определяем переменную типа int и называем ее i ,так вот как это i связано с реальной памятью и что можно почитать на этот счет

Компилятор компилирует машинный код, который содержит понятные для компьютера "инструкции". Если интересно что дальше читай Таненбаум "Архитектура компьютера".
Аноним 04/12/17 Пнд 01:51:12 #191 №1102562 
>>1102561
>Компилятор компилирует код программы в машинный код
быстрофикс
Аноним 04/12/17 Пнд 02:12:45 #192 №1102568 
>>1102553
>почему sizeof(char) =1 byte, а sizeof(указатель на char) =4 byte&
Тебя наверное смущает, что нет смысле передавать в функцию указатель на char, если тебя интересует только значение этого char'a? Ну да, не имеет, но указатели используются не только для экономии на копировании при передаче в функцию. Иногда, например, в функции нужно поменять в памяти значение char'a, не возвращая его из функции, тогда передают указатель на него. Но чаще указатель на char это указатель на начало большого куска памяти, т.е. на целую кучу этих char'ов, которые идут непрерывно в памяти, начиная с переданного указателя. Например, так указатели на строки передают.
Аноним 04/12/17 Пнд 23:37:29 #193 №1103197 
Как реализован макрос NULL в stdlib.h? Чекнул вики, но не совсем все понял. В вики сказано, что NULL - это целочисленное нулевое значение. Т.е. я спокойно могу написать свой собственный NULL? #define MYNULL 0 Будет ли это аналогично дефайну стандартного NULL?
Аноним 04/12/17 Пнд 23:39:04 #194 №1103198 
>>1103197

да
Аноним 04/12/17 Пнд 23:42:23 #195 №1103201 
>>1103198
Тогда почему инициализация указателей NULL'ом считается нормальным действием? Ведь в адресе 0 могут хранится какие-то данные. Например, часть переменной. С тем же успехом можно инициализировать указатели значением 3211351, вместо NULL
sageАноним 04/12/17 Пнд 23:46:07 #196 №1103204 
>>1103201
> Ведь в адресе 0 могут хранится какие-то данные
Не могут (запрещено стандартом). В винде, например, специально из-за этой особенности сишечки запрещает выделять первые 4к виртуальной памяти.

> С тем же успехом можно инициализировать указатели значением 3211351, вместо NULL
Можно. Но проверять на ноль дешевле, чем на 3211351.
Аноним 04/12/17 Пнд 23:52:59 #197 №1103206 
>>1103204
> запрещает выделять первые 4к виртуальной памяти
А что значит "4к". 4Кб? Сорян за возможно глупый вопрос.
>Можно
Тогда уж нельзя. Ведь если в 0 точно не может быть никаких данных, то по адресу 3211351 они могут быть

Аноним 05/12/17 Втр 00:02:45 #198 №1103212 
>>1103206
Хотя было бы странно запрещать выделять целые 4Кб памяти - слишком много. Но я все равно не понял, что подразумевается под "4к"
sageАноним 05/12/17 Втр 01:31:11 #199 №1103243 
>>1103201
NULL это не "нулевой адрес".
sageАноним 05/12/17 Втр 03:02:23 #200 №1103256 
>>1103243
Да, стандарт разрешает и другие представления нулевого указателя, но в реальности оно практически везде ноль.

>>1103212
> слишком много
Лол, у тебя гигабайты на компе. 4 килобайта - это ровно страница. Управлять доступом к объектам размером меньше страницы нельзя.
Аноним 05/12/17 Втр 08:12:20 #201 №1103302 
Анончик, помоги закрыть предмет. Мне нужно написать алгоритм крускала через систему непересекающихся множеств. Я написал disjoint set, но не знаю как написать к нему крускала. Можешь помочь? Могу скинуть пару баксов на пейпал если поможешь дописать (или пару кусков битка)
sageАноним 05/12/17 Втр 09:12:33 #202 №1103315 
>>1103201
>Тогда почему инициализация указателей NULL'ом считается нормальным действием?

Как раз потому что указателя NULL = 0 быть не может и это можно использовать как признак, что данных нет, например. В то время как другая хуитка - это, в зависимости от архитектуры - может быть вполне нормальным адресом.
Аноним 05/12/17 Втр 15:53:06 #203 №1103474 
Указатель содержит адрес только на первый байт блока памяти или на весь блок? Или же вообще на начало и конец блока?
int *p;
int main () {
p = malloc(40);
return 0;
}
В этом коде видно, что мы выделили блок памяти в куче размером 40 байт, и (как написано в интернете) функция malloc возвращает адрес на начало этого блока указателю p. То есть, если так можно выразиться, указатель лишь знает адрес первого байта (или бита?) всего этого блока, верно? Но в указателе, вернее, в адресе, который в нем хранится, нет никакой инфы о том, когда этот блок заканчивается, так?
Аноним 05/12/17 Втр 16:05:32 #204 №1103483 
>>1103474
Только на первый байт. (Языком стандарта будет точнее сказать, что на первый char.)

> То есть, если так можно выразиться, указатель лишь знает адрес первого байта (или бита?) всего этого блока, верно?
Верно. Не бита, на минимальный адресуемый кусок памяти на твоей машине, которым по стандарту является char. Обычно это 1 байт.
> Но в указателе, вернее, в адресе, который в нем хранится, нет никакой инфы о том, когда этот блок заканчивается, так?
Да, так. Так что размер блока нужно либо хранить отдельно, либо помечать в конце блока памяти его конец (так делается со строками, например, в конце ставится '\0', он же 0).
Аноним 05/12/17 Втр 16:38:51 #205 №1103494 
>>1103483
Если указатель хранит адрес только на первый байт всего блока, то как тогда функция free() высвобождает всю выделенную память блока? Возьмем опять же такой код и добавим free
int *p;
int main () {
p = malloc(40);
free(p);
p = NULL;
return 0;
}
Как ф-ия free понимает, что ей нужно освободить 40 байт памяти, а не 1? Ведь p содержит адрес только на начало первого байта всего блока.
Аноним 05/12/17 Втр 17:04:05 #206 №1103511 
>>1103494
Это проблемы ОС, она хранит инфу о том что кому выделено, из кода эту инфу в большинстве случаев получить нельзя (потому что управление памятью нетривиальная задача, разные ОС решают её по разаному).
Аноним 05/12/17 Втр 17:26:12 #207 №1103521 
>>1103511
Хорошо, спасибо
Аноним 05/12/17 Втр 18:13:33 #208 №1103546 
>>1103511
> Это проблемы ОС, она хранит инфу о том что кому выделено
В данном случае, это проблемы стандартный либы, в которой malloc и free реализованы, ОС тут ни при чём.
Аноним 05/12/17 Втр 18:25:02 #209 №1103549 
>>1103546
https://en.wikibooks.org/wiki/The_Linux_Kernel/Memory
Для примера.
Аноним 05/12/17 Втр 18:31:45 #210 №1103550 
>>1103546
Ну строго говоря да, ты прав, наверное. Конкретно тут libc рулит, не зазглядывал в сорс. libc сорт оф ассоциирую с самой ОС.
Аноним 05/12/17 Втр 20:49:04 #211 №1103604 
>>1103494
Тебе это знать не положено.
Аноним 05/12/17 Втр 20:55:11 #212 №1103609 
>>1103494
В K&R есть одна из реализаций malloc.
У неё есть размеры выделенных кусков кучи, указатели на начала, она ещё пытается интеллектуально выделять
Аноним 06/12/17 Срд 10:10:35 #213 №1103806 
>>1103494
Куча (heap) устроена как двусвязный список.

Если вычесть из твоего указателя 8 или 16 байт, нетрудно найти заголовок области в куче. А оттуда получить указатели на предыдущую/следующую области.

Алсо, там ещё и флажки есть.
Аноним 06/12/17 Срд 10:23:06 #214 №1103810 
>>1103806
>Куча (heap) устроена как двусвязный список.
Ты нам из 70-х пишешь?
sageАноним 06/12/17 Срд 11:09:16 #215 №1103840 
>>1103810
Да на каком-нибудь микроконтроллере и сейчас можно найти подобное без проблем. Вполне себе нормальное решение, если на скорость поиска свободных блоков и на фрагментацию похуй.
Аноним 06/12/17 Срд 14:56:35 #216 №1103953 
http://www.agner.org/optimize/calling_conventions.pdf
Аноним 06/12/17 Срд 16:13:57 #217 №1103990 
void func(int @p) { int i = 5; p = &i; }
...
int @p;
func(p);
printf("%d\n", @p) // -421423441 (мусор)

В данном случае функция "func" работает с локальной копией указателя, правильно? А передать в функцию сам указатель нельзя?
Аноним 06/12/17 Срд 16:17:39 #218 №1103992 
>>1103990
Можно, передай указатель на указатель. void func(int p) ...
Аноним 06/12/17 Срд 16:19:45 #219 №1103993 
>>1103990
void func(int✡✡ p)
быстрофикс
>>1103992-няша
Аноним 06/12/17 Срд 16:25:16 #220 №1103998 
>>1103993
О как круто! Спасибо.
Аноним 06/12/17 Срд 17:19:09 #221 №1104027 
>>1103993
Я хотел еще один вопрос задать, на счет закомментированного кода по ссылке, но в ideone даже так не работает, нолик выдает. Почему?
https://ideone.com/esDAHP

На хосте такой код прекрасно работает, а вот закоментированный - сегфолтит. Тот же вопрос, почему?
Очень путаюсь в указателях.
Аноним 06/12/17 Срд 17:42:00 #222 №1104045 
>>1104027
А хотя я все понял. Ты же мне и так дал ответ - указатель на указатель.

https://ideone.com/0kJObR Нормально? На хосте функционирует прекрасно, хотя тут почему-то все равно не работает.
Аноним 06/12/17 Срд 17:46:02 #223 №1104053 
>>1104027
int i = 5;
✡p = &i;

в ✡p теперь указатель на кусок памяти, аллоцированный на стеке в функции. После того как функция выполнилась её память уже может содержать что угодно. В общем это ошибка так писать код. На ideone стек зануляется видимо, потому и выводит 0.

Самое близкое по смыслу это было бы выделить память в функции:

void func(int ✡✡pp) // переименовал, чтобы было понятно, что это указатель на указатель, меньше путаться будешь
{
int ✡i = malloc(sizeof(int)); // выделяем память
✡pp = &i;
}

int main(void)
{
int ✡p;
func(&p);

printf("p: %d\n", ✡p);

free(p); // освобождаем

return 0;
}

Закомментированный код сегфолит, потому что ты передаешь ✡gp в функцию (printf("gp:%d\n", ✡gp);), что означает "взять значение по указателю gp и передать это значение в функцию", дальше компилятор без спроса приводит типы и интепретирует это значение как указатель на указатель. Тут может упасть аж в двух местах, если gp действительно куда-то указывает (gp != 0), то упадёт при попытке доступа на запись в этот кусок памяти (если, конечно, не случилось чудо и твой передайнный в функу int не нумерует какой-то твой кусок памяти, в этом случае прочитаются какие-то левые данные). Если gp = 0 (что вполне возможно для глобальных переменных, не помню точно зануляются ли глобальные переменные по стандарту), то упадёт прямо при вызове функции, т.к. ты пытаешься нулевой указатель разыменовать (это термин такой, "разыменовать указатель — получить значение из памяти, куда указывает указатель").
Аноним 06/12/17 Срд 17:47:50 #224 №1104054 
>>1104053
>✡pp = &i;
Надо только ✡pp = i; вот так, раз i теперь не int, а указатель на int.

оередной быстрофикс
Аноним 06/12/17 Срд 17:50:52 #225 №1104057 
>>1104054
void func(int ✡✡pp) // переименовал, чтобы было понятно, что это указатель на указатель, меньше путаться будешь
{
int ✡i = malloc(sizeof(int)); // выделяем память
✡i = 5;
✡pp = &i;
}

Точнее вот так, извините за спам. :(
Аноним 06/12/17 Срд 17:54:20 #226 №1104059 
>>1104057
void func(int ✡✡pp) // переименовал, чтобы было понятно, что это указатель на указатель, меньше путаться будешь
{
int ✡i = malloc(sizeof(int)); // выделяем память
✡i = 5;
✡pp = i;
}

последний фикс, обещаю
Аноним 06/12/17 Срд 17:56:13 #227 №1104063 
>>1104059
Спасибо, стало понятнее.

Теперь тут все правильно, верно? https://ideone.com/lJGQsm
Аноним 06/12/17 Срд 18:05:28 #228 №1104071 
>>1104063
Ну в целом да, только free забыл, не забывай про free, а то память терять будешь.

Ну и лишний код (я так понимаю ты просто играешься для понимания):

int ✡✡p;
p = &gp;
func(&*p);

можно поменять на

int ✡p;
func(&p);

и обойтись без gp.
Аноним 06/12/17 Срд 18:08:08 #229 №1104072 
>>1104071
Нет, мне именно с gp нужно. Пытаюсь на простом примере понять, как сделать нечто похожее в основном программе. В принципе понял.
Аноним 06/12/17 Срд 18:10:55 #230 №1104074 
>>1104072
Тогда так:
func(&gp);
Аноним 06/12/17 Срд 18:29:11 #231 №1104083 
>>1104074
У меня там именно гора указателей на указатели, указывающие на указатели на указатели, указывающие на указатели.

Вот как раз еще один вопрос в связи с этим. Я в таких дебрях не понимаю ничего.
Есть указатель на указатель - var1, который указывает на var2 - тоже указатель на указатель, который указывает на var3 - обычный указатель на int.
Как мне обращаясь к var1 проверить NULL ли var3 или не NULL?

Просто if(var1 == NULL), как я понимаю, не то выдает.
Аноним 06/12/17 Срд 18:54:08 #232 №1104094 
nyanc.png
>>1104083
Аноним 06/12/17 Срд 18:56:35 #233 №1104097 
nyanc.png
>>1104094
ДА БЛЯТЬ пофиксил картинку
Аноним 06/12/17 Срд 19:14:50 #234 №1104118 
>>1104097
Всё ясно, ещё раз спасибо. Схоронил себе пикчу, буду поглядывать.
Аноним 06/12/17 Срд 19:24:50 #235 №1104124 
>>1095677 (OP)
А Си уже скоро ВСЁ? Всё-таки есть Rust, GO или хотя бы C++.. Может не стоит его даже учить?
Аноним 06/12/17 Срд 19:30:44 #236 №1104130 
>>1104124
Не скоро.

Плюс стоит учить, даже если не будешь активно писать на нём, чтобы понять как современные компьютеры и ОС работают (указатели, стек, куча, cache & locality).
Аноним 06/12/17 Срд 20:25:34 #237 №1104179 
5432342134312.png
Еще вопрос на счет указателей, не могу гуглу его сформулировать нормально.

Как обратиться к переменной "i" через "var"? Которая в функции. Компилятор говорит, что тип "type_ *" не структура, нельзя к нему мол через "->".
Аноним 06/12/17 Срд 20:48:18 #238 №1104196 
>>1104179

-> автоматический разыменовывает указатель, а . нет

typedef struct {
int i;
} type_;

int main(int argc, char const *argv[])
{
type_ t;
type_✡ pt = &t;

// это всё одно и то же
t.i = 6;
pt->i = 3;
(&t)->i = 1;

return 0;
}

И у тебя код упадёт как пофиксишь ->. Потому что ты определил указатель на структуру, но этот указатель никуда не указывает. Надо или определять структуру на стеке (как я сделал выше) или выделить самому память через malloc (+free не забудь): type_ ✡var = malloc(sizeof(type_))

Ваще почитай книжки из шапки или ты чёто хочешь руками починить просто?
Аноним 06/12/17 Срд 21:06:24 #239 №1104217 
412412341.png
>>1104196
Погоди, ты же на вопрос не ответил. К var->i в мейне я обратиться могу, а к вот к var->i в "func" - нет, потому что в "func" var это указатель на указатель, в мейне же var - просто указатель. Или я что-то недопонял?

> Потому что ты определил указатель на структуру, но этот указатель никуда не указывает.
Это понятно, по-быстрому примерчик написал, не учёл. У меня код не компилируется, в этом проблема.

> Ваще почитай книжки из шапки
А где именно в полной мере объясняется про работу с указателями? Базовый уровень, так скажем, мне понятен, но как только ситуация становится относительно сложной, вроде той что на пикче выше, как я теряюсь. Появилась вот структура и мне совершенно непонятно как с ней работать в контексте указателей.
sageАноним 06/12/17 Срд 21:10:56 #240 №1104220 
>>1104217
>К var->i в мейне я обратиться могу, а к вот к var->i в "func" - нет, потому что в "func" var это указатель на указатель, в мейне же var - просто указатель.
Зделай в func из указателя на указатель просто указатель и сможешь обратиться.
Аноним 06/12/17 Срд 21:18:06 #241 №1104226 
>>1104220
Но в таком случае в func отправится локальная копия указателя, а не сам указатель. Разве нет?
Путаюсь очень, извини.
Аноним 06/12/17 Срд 21:21:17 #242 №1104228 
>>1104226
Из-за очерёдности применения операторов. (✡var)-> сделай
Аноним 06/12/17 Срд 21:36:51 #243 №1104244 
>>1104228
Именно это я и хотел услышать, спасибо.

Но мне все равно не понятно как именно нужно указатели в функции передавать.
Как я понимаю этот >>1103990 код не работал из-за того, что я манипулировал с памятью непосредственно во вторичной функции "func". Если бы в мейне, сразу после объявления "int @p" я сделал "= malloc(sizeof(int));" и отправил в func уже инициализированный указатель, то все бы успешно ему присвоилось, потому что память эта выделена в мейне, в основной программе.

То есть, в принципе, можно обойтись без указателей на указатели - обычные указатели использовать. Но считается ли это хорошим стилем? Может лучше приучить себя использовать указатели на указатели везде, где этого требует подразумеваемая логика?
Аноним 06/12/17 Срд 21:50:11 #244 №1104251 
>>1104244
Указатели на указатели используются если в функции нужно выделить память. Такой стиль некоторые ругают и говорят, что пары malloc+free лучше держать на одном уровне в коде. Ну некоторым функции выделять память норм и много есть таких API. Я лично сильного мнения по этому вопросу не имею, не пишу на С особо. Почитай книжки по Сишечке, вполне возможно в каких-то этот вопрос обсуждается.

Ну и вот линк глянь: https://stackoverflow.com/questions/13442375/best-practice-for-allocating-memory-for-use-by-a-function-malloc-inside-or-out

Есть свои плюсы и минусы в обоих подходах. Например если функция выделяет память, то в main не надо знать размер данных заранее и т.п.
Аноним 06/12/17 Срд 22:38:09 #245 №1104271 
>>1104244
> То есть, в принципе, можно обойтись без указателей на указатели - обычные указатели использовать. Но считается ли это хорошим стилем?
При чём тут стиль? Это зависит от того, что тебе нужно. Если тебе надо, чтобы функция вернула указатель, то какие проблемы. Алсо, она может вернуть его через return, а не через аргументы, и тебе не надо передавать указатель на указатель.
Аноним 06/12/17 Срд 22:47:48 #246 №1104278 
>>1104251
Можно использовать оба подхода в одной функции. Если переданный указатель указывает на NULL, то память аллоцируется. Если не NULL, то не алллоцируется. Так getline() работает, например. https://linux.die.net/man/3/getline
Аноним 07/12/17 Чтв 01:14:26 #247 №1104331 
>>1103810
Я знаю как она здесь устроена, видел исходные тексты.
Аноним 07/12/17 Чтв 01:17:27 #248 №1104334 
>>1104124
Только что с собеседования, типа им нужен спецiалист со знанием C++11.

Ага, счас... начали с устройства энторнетов и эthернетов, дошли до вычислений на списках, и тут я им видимо понравился и они объявили, что «C++11» это типа замануха была. ЧИСТЫЙ СИ И ТОЛЬКО ОН и какие-то свои стандарты кодирования.

Ну, я с готовностью согласился.
Аноним 07/12/17 Чтв 14:40:36 #249 №1104524 
>>1104334
устройства интернетов это сети и дальше? Кст поздравляю надеюсь работа понравится
Аноним 07/12/17 Чтв 21:26:00 #250 №1104752 
>>1104524
Да, первый том Ричарда Стивенса и всё то, что уровнем выше.
Аноним 07/12/17 Чтв 22:36:41 #251 №1104779 
Как можно вычислить максимальное значение типа int, если sizeof(int) = 4?
Написал я
int max;
max = int(pow (2, sizeof(int)8)-1);
printf("max = %d\n", max);

Но при возведении двойки в восьмую степень идет переполнение типа на единицу. Соответственно, если даже потом делаю -1, все равно вижу мусор в результате. Возможно ли высчитать максимальное значение int, используя переменную signed int?
И еще, попробовал сделать через unsigned int, а именно:
unsigned int max;
max = unsigned int(pow (2, sizeof(int)
8)-1);
printf("max = %d\n", max);

Казалось бы, простая задача в 3 строки, но при практическом выполнении возникают трудности
Аноним 07/12/17 Чтв 22:37:59 #252 №1104780 
>>1104779
Фикс

Там, где нужно умножение (символ "звездочка") оно есть, просто двач не отображает
Аноним 07/12/17 Чтв 22:46:00 #253 №1104786 
>>1104780
не знаю что ты там написал. пользуйся сдвигами да и всё. 1L<<31 | (1L<<31)-1L
Аноним 07/12/17 Чтв 22:58:34 #254 №1104787 
>>1104786
Даже сдвиги не нужны.

https://pastebin.com/Sf7vgcVi
Аноним 07/12/17 Чтв 23:03:48 #255 №1104789 
>>1104787
я думал ему нужен знаковый - хуй поймёшь.
Аноним 07/12/17 Чтв 23:05:00 #256 №1104790 
>>1104789
>знаковый
а, или тогда я не правильно выдал. это у меня из каких-то макросов... я там ещё проверяю множественными сдвигами разрядность типов...
Аноним 07/12/17 Чтв 23:05:08 #257 №1104791 
>>1104786
Я ошибся с первой частью. Так норм работает, переполнения нет.
int max;
max = int((pow(2, sizeof(int)8-1) - 1));
Однако, все же остался вопрос. Почему в таком коде получаю просто 0 в консоли?
unsigned int max;
max = unsigned int(pow(2, sizeof(int)
8));
С побитовыми сдвигами еще не разбирался. Понимаю, что принцип несложный, но даже сам оператор << вижу впервые.
Аноним 07/12/17 Чтв 23:09:02 #258 №1104792 
>>1104787
Лол, спасибо. Так тоже прикольно. Не знал, что можно printf'ить тип.
Аноним 07/12/17 Чтв 23:12:23 #259 №1104794 
Все, разобрался со всей своей фигней. Сорян, что тупил, у меня уже поздно, да и ел мало сегодня. Через pow все-таки все удалось сделать. И signed и unsigned. Однако еще узнал, что можно сделать это через битовые сдвиги (почитаю про них) и просто printf нужного типа. Так что еще раз спасибо
Аноним 07/12/17 Чтв 23:14:02 #260 №1104795 
>>1104791
>int((pow
Чё за int блядь? Это функция? У меня твоё говно не компилируется.
Аноним 07/12/17 Чтв 23:22:57 #261 №1104797 
>>1104795
Не компилится, потому что двач не отображает символ звездочки (умножение) в постах. Вот фул тогда https://pastebin.com/8Xht7fU4
Аноним 07/12/17 Чтв 23:30:53 #262 №1104798 
>>1104797
> Не компилится, потому что двач не отображает символ звездочки (умножение) в постах.
Nope. Я спалил звёздочку. Не в ней была проблема.

https://pastebin.com/LUT7fzhw
Аноним 07/12/17 Чтв 23:40:30 #263 №1104803 
>>1104798
Не компилится, потому что это крестопарашный синтаксис, а не сишный.
Аноним 07/12/17 Чтв 23:53:43 #264 №1104808 
>>1104798
Действительно, проверил в другом компиляторе (онли Си) там выдает ошибку.
>>1104803
Как тогда в Си писать преобразование в тип?
Аноним 08/12/17 Птн 00:10:17 #265 №1104809 
>>1104808
Методом тыка обнаружил, что правильно преобразовать типы в Си надо так: (int)(a), а не int(a). Потому что в таком случае int(a) компилятор ожидает декларирования новой переменной, отсюда и ошибки.
Аноним 08/12/17 Птн 05:48:23 #266 №1104860 
Есть задание: напишите двоичное представление числа -117 типа signed char в дополнительном коде. Что это значит и какое будет представление?
Аноним 08/12/17 Птн 06:41:18 #267 №1104866 
>>1104860
Ухади
Аноним 08/12/17 Птн 07:06:19 #268 №1104869 
>>1104866
Нет, серьезно. -117 в двоичную систему я перевести могу. Но что значит дополнительный код?
Аноним 08/12/17 Птн 07:09:08 #269 №1104870 
>>1104869
При записи числа в дополнительном коде старший разряд является знаковым.

сказать где я это нашел?
Аноним 08/12/17 Птн 07:13:23 #270 №1104872 
>>1104870
Ты не совсем прав.
Чтобы число записать в дополнительном коде надо все его биты инвертировать и прибавить единицу. Учите основы аноны, это важно.
Аноним 08/12/17 Птн 07:18:00 #271 №1104873 
>>1104872
>инвертировать и прибавить единицу.
зачем? хуйня какая то
00000001 - 11111110 -> 00000001
Аноним 08/12/17 Птн 07:37:15 #272 №1104875 
>>1104873
вобщем почитал, вопрос снимается.
Аноним 08/12/17 Птн 08:00:53 #273 №1104882 
>>1103494
>Если указатель хранит адрес только на первый байт всего блока, то как тогда функция free() высвобождает всю выделенную память блока? Возьмем опять же такой код и добавим free
>int *p;
>int main () {
>p = malloc(40);
>free(p);
>p = NULL;
>return 0;
>}
>Как ф-ия free понимает, что ей нужно освободить 40 байт памяти, а не 1? Ведь p содержит адрес только на начало первого байта всего блока.

https://github.com/lattera/glibc/blob/master/malloc/malloc.c
Аноним 08/12/17 Птн 14:10:40 #274 №1104984 
>>1104882
слишком многа букаф, ниасилил
Аноним 08/12/17 Птн 14:42:44 #275 №1105003 
>>1104882
os знает сколько байт по начальному адресу чанк занимает
Аноним 08/12/17 Птн 20:39:41 #276 №1105152 
>>1105003
>os знает
Да нихуя она не знает.
Аноним 09/12/17 Суб 08:24:37 #277 №1105303 
>>1105152
>Да нихуя она не знает
а кто память выделяет, а, мамка твоя?
Аноним 09/12/17 Суб 14:07:51 #278 №1105349 
http://www.opennet.ru/docs/RUS/zlp/002.html

Тут чуваки поясняют за мультифайловое программирование (в главе 2.2). Их код у меня не компилится ибо файл с main'ом не видит функции, которые он вызывает. Я конечно мог бы объявить функции в том же файле с main'ом, а реализацию уже в другой, но почему у меня их код не работает? или он и не должен?
Аноним 09/12/17 Суб 14:20:50 #279 №1105355 
Пытаюсь распарсить json по этому гайду
https://kt48.wordpress.com/2015/03/03/basic-tutorial-on-json-glib-for-tizen/
С файлом из гайда все парсится, а с моим не работает. Выдает
Json-CRITICAL : json_object_get_object_member: assertion 'JSON_NODE_HOLDS_OBJECT (node) || JSON_NODE_HOLDS_NULL (node)' failed
Что не так то?
Аноним 09/12/17 Суб 14:49:25 #280 №1105362 
>>1105349
C99 требует прототип функций. Гайд старый, писался под C90

Олсо, мейк-файл там идиотский.
sageАноним 09/12/17 Суб 20:00:35 #281 №1105592 
>>1105355
Ну тебе же написали: ты вызываешь json_object_get_object_member() на том, что не является JSON-объектом (на массиве, например) или вообще пихаешь туда NULL.
Аноним 09/12/17 Суб 21:23:55 #282 №1105621 
>>1105592
Действительно там массив, только не пойму чо делать если внутрь массива напиханы объекты.
Аноним 09/12/17 Суб 21:28:45 #283 №1105624 
>>1105621
json_node_get_array()
json_array_get_length()
json_array_get_element()
Аноним 09/12/17 Суб 22:59:48 #284 №1105656 
>>1105624
Разобрался.
Аноним 09/12/17 Суб 23:37:22 #285 №1105669 
Не туда пишу, наверное, но пох
Писал в школе проги на паскале, решил вкатиться в си, поставил code::blocks и mingw. Охуел с того, что нельзя запускать отладчик для файлов, только для проекта. Насколько понял, в проекте есть только один сурс(в котором, собсна, и находится единственная main), в который подключаются функции, описанные в куче хедеров.
Я правильно понял, или как? Мне что, каждое упражнение из K&R в отдельный хедер ну или в один писать функцией, а его в main.c подключать, а там инициализировать свои проги в виде функций? Или а каждую прогу уровня "подсчитайте строки" новый проект создавать? Что за бред?
Короче, разъясните дауну, шо це проект, и как с ним работать.
Аноним 10/12/17 Вск 00:28:54 #286 №1105680 
>>1105669
> Насколько понял, в проекте есть только один сурс
Ты неправильно понял. В проекте может быть сколько угодно исходников и сколько угодно хедеров. Но одна main(), да. В любом из этих исходников. Еще у проекта есть куча настроек (директории, ключи компилятору, подключаемые либы), поэтому многие IDE и хотят проект для компиляции.

> Мне что, каждое упражнение из K&R в отдельный хедер
В K&R большинство упражнений не требует нескольких файлов, поэтому и декларации можешь делать не в хедере, а вверху файла. Если тебе лениво создавать один проект на программу, можешь создавать каждый раз новый .c-файл, класть его в проект, а старый удалять из проекта (можешь придумать кучу вариций: ничего не удалять, а делать #if (EXERCISE==1) ... #endif вокруг функций упражнения, и, соответствено, где нибудь выше делать #define EXERCISE 1; можешь даже диспетчер упражнений наговнокодить, который будет вызывать exerciseN_main, можешь просто такие мелкие вещи компилять из командной строки).
Аноним 10/12/17 Вск 10:53:44 #287 №1105751 
>>1105680
Добра тебе
ушёл курить структуру программы на си
Аноним 10/12/17 Вск 12:50:03 #288 №1105794 
>>1105680
а ещё он может не пользоваться IDE и его проблема исчезнет
Аноним 10/12/17 Вск 13:14:12 #289 №1105799 
Что делать, если вылетает на строчке
char prefix = malloc(512);
пишет:
malloc(): memory corruption: 0x0000561162c24df0

Aborted
Аноним 10/12/17 Вск 15:14:07 #290 №1105828 
>>1105799
добавить звездочку
Аноним 10/12/17 Вск 15:49:49 #291 №1105839 
>>1105828
Да есть звездочка, это макаба сожрала.
Аноним 10/12/17 Вск 17:41:58 #292 №1105885 
>>1105794
на самом деле бесит это, все эти проекты, лишние файлы - сам когда-то ебался с кодблоксом. и естественно переход на емакс всё решил по итогу.

но теперь я не очень понимаю нахуя мейкфайлы, иногда сборка такая сложная, что проще шелл скрипт прописать. хотя я так и не изучил структуру мейкфайлов... просто набрасываю в одной опции строки с командами да и всё.
Аноним 10/12/17 Вск 19:44:16 #293 №1105949 
>>1105885
> просто набрасываю в одной опции строки с командами да и всё
Ну вот когда тебе заебется безусловно перекомпилировать все файлы в большом проекте при изменении какой-нибудь ни на что не влияющей константы, ты осилишь makefiles или cmake, гарантирую. А насчет мелочи соглашусь, проще сделать cc *.c и не думать.
Аноним 10/12/17 Вск 19:45:50 #294 №1105950 
>>1105799
> вылетает на строчке
> malloc
Смотреть, кто повредил кучу ДО этого вызова. Очень помогает gcc или clang с ключиком -fsanitize=address.
Аноним 10/12/17 Вск 21:10:29 #295 №1106027 
>>1105949
потому что он что, проверят тамстемпы перед компиляцией? что в принципе не мешает сделать на шелле, муторно, да. но дело же не в этом, не всегда сборка это создание файлов. например тесты, или когда тебе нужно что-то генерировать через свои же программы - тупо же хранить бинарники - то есть нужно если их нет, скомпилировать их, а потом заиспользовать.

может это и через мекфайл можно - не знаю, не вижу смысла, возможно пока.
comments powered by Disqus