если извращенский вариант, то while(!pause){} а если, нормальный то system("pause");
system("pause") прокатит только в Windows, если не ошибаюсь. Кстати, ещё можно сделать system("PAUSE >> VOID");, чтобы скрыть надпись "Для продолжения нажмите любую клавишу...".
Есть ещё варианты: ждать нажатия через getch()/getchar(). Ну или если ты знаешь на сколько мс нужна пауза, то ты можешь использовать Sleep(...) из <Windows.h>
Ни в коем случае. Это не "сахар", а реализация первичных ф-ий языка C - как можно ближе к процессору, и как можно мощнее выражения. Например, приведенная "фраза", это не "оператор подобный :=", а выражение, которое имеет значение и может быть присвоено кому-то еще. Да, "a <оп>= b" то же самое, что и "a = a <op> b" на уровне обычного кодинга, но "начинка" совершенно другая (а в C++ ее можно сделать имеющей совершенно иной смысл). Называть "a -=b" сахаром для "a = a - b", это все равно, что называть "a - b" сахаром для "a + -b". Быдлокодеры любят повторять: "логика, убивающая мозг",- когда их пытаются заставить программировать.
Сообщение отредактировал Gudleifr - Воскресенье, 02 Августа 2015, 13:29
"a -= b" это синтаксический сахар для "a = a - b". Реализуется в языках для удобства (меньше повторяемого кода).
Не только сахар. Оператор -= работает только с двумя переменными (объектами). Но в a = a - b все не так просто (особенно если переменные не элементарных типов {ведь выше речь о C#}). При выполнении (a-b) создается новый временный объект со значением результата, а затем выполняется присваивание. При этом присваивание - это не такая простая и быстрая операция, т.к. запускается сборка мусора (старый объект ведь теперь не существует). После присваивания деструктором уничтожается временный объект, который хранил (a-b).
Поэтому a -= b может быть гораздо эффективнее в объектно-ориентированных языках типа С++/C#/...:)
Почему в разделе вопросов по Си вопросы и ответы не по теме? Непорядок!
Итак, новые дилетантские вопросы от Антона (меня, то есть). Как я уже отметил в отдельной теме, я пишу игровой движок на чистом Си и имитирую некоторые ООПшные подходы. Вместо классов у меня структуры и я всячески ими манипулирую. Ну так вот. После создания "класса" через malloc на выходе получалась забитая мусором структура и в "конструкторах" я затирал поля в 0. Потом я подумал, что всё это можно заменить одним простым calloc. А позже наткнулся на эту статью, которая подтверждала правильность решения:
Цитата
Никогда не используйте malloc Привыкайте к calloc. С этой функцией вам не грозит снижение производительности при очистке памяти.
Но также я натыкался на информацию, что malloc выравнивает данные, а calloc нет. И у меня теперь есть некоторые сомнения. На проверяемых компуктерах всё работает исправно, но могут ли быть проблемы на каком-то другом железе или времена процессоров, не умеющих работать с невыравненными значениями, канули в Лету? Теперь второй вопрос. О нулевых указателях - NULL. NULL определен как (void*)0. Это не математический 0, он преобразуется компилятором в указатель на какую-то область памяти, которая на разных платформах - разная. (Читал в какой-то книге в форме вопрос-ответ по Си. Не могу найти, но ссылку предоставлю позднее). Итак сам вопрос. Вот у меня есть структуры, в которых есть указатели. Я создаю их через calloc(1, sizeof(any_struct)), то в указатель попадёт 0. Но ведь 0 попадёт "математический" и в момент исполнения программы. Как быть уверенным, что этот 0 будет нулевым указателем? Или не будет? Опять же вроде работает, но вдруг на каких-то машинах это работать не будет? Вот такие вопросы новичка. (начал изучение Си пару месяцев назад, не пинайте, судари)
Добавлено (02 августа 2017, 05:54) --------------------------------------------- По поводу моего второго вопроса, видимо, на современных компах можно не париться. Я вчера не мог найти, откуда я взял инфу про путаницу с нулевыми указателями, но сегодня нашёл:
Цитата
Программист, который хочет явно различать 0 как целое и 0 как нулевой указатель может использовать NULL в тех местах, где необходим нулевой указатель. Это только стилистическое соглашение; препроцессор преобразует NULL опять в 0, который затем распознается компилятором в соответствующем контексте как нулевой указатель.
Цитата
1.11: Почему так много путаницы связано с нулевыми указателями? Почему так часто возникают вопросы? О: Программисты на С традиционно хотят знать больше, чем это необходимо для программирования, о внутреннем представлении кода. Тот факт, что внутреннее представление нулевых указателей для большинства машин совпадает с их представлением в исходном тексте, т.е. нулем, способствует появлению неверных обобщений.
Цитата
1.14: Ну а если честно, на какой-нибудь реальной машине используются ненулевые внутренние представления нулевых указателей или разные представления для указателей разных типов?
О: Серия Prime 50 использует сегмент 07777, смещение 0 для нулевого указателя, по крайней мере, для PL/I. Более поздние модели используют сегмент 0, смещение 0 для нулевых указателей С, что делает необходимыми новые инструкции, такие как TCNP (проверить нулевой указатель С), которые вводятся для совместимости с уцелевшими скверно написанными С программами, основанными на неверных предположениях. Старые машины Prime с адресацией слов были печально знамениты тем, что указатели на байты (char *) у них были большего размера, чем указатели на слова (int *). Серия Eclipse MV корпорации Data General имеет три аппаратно поддерживаемых типа указателей (указатели на слово, байт и бит), два из которых — char * и void * используются компиляторами С. Указатель word * используется во всех других случаях. Некоторые центральные процессоры Honeywell-Bull используют код 06000 для внутреннего представления нулевых указателей. Серия CDC Cyber 180 использует 48-битные указатели, состоящие из кольца (ring), сегмента и смещения. Большинство пользователей (в кольце 11) имеют в качестве нулевых указателей код 0xB00000000000. Символическая Лисп-машина с теговой архитектурой даже не имеет общеупотребительных указателей; она использует пару <NIL,0> (вообще говоря, несуществующий <объект, смещение> хендл) как нулевой указатель С. В зависимости от модели памяти, процессоры 80*86 (PC) могут использовать либо 16-битные указатели на данные и 32-битные указатели на функции, либо, наоборот, 32-битные указатели на данные и 16-битные — на функции. Старые модели HP 3000 используют различные схемы адресации для байтов и для слов. Указатели на char и на void, имеют, следовательно, другое представление, чем указатели на int (на структуры и т.п.), даже если адрес одинаков.
Сообщение отредактировал Vuvk - Вторник, 01 Августа 2017, 20:25
времена процессоров, не умеющих работать с невыравненными значениями, канули в Лету?
this, но невыровненные данные могут быть прчиной снижения производительности, так что просто можешь создать свою функцию для выделения памяти, которая будет выравнивать данные, либо вообще использовать альтернативные аллокаторы памяти, пара ссылок: https://stackoverflow.com/questio....0 Альтернативные аллокаторы памяти
ЦитатаVuvk ()
Вот у меня есть структуры, в которых есть указатели. Я создаю их через calloc(1, sizeof(any_struct)), то в указатель попадёт 0. Но ведь 0 попадёт "математический" и в момент исполнения программы. Как быть уверенным, что этот 0 будет нулевым указателем? Или не будет?
что-то я не понял ))) у тебя в компьютере все представленно в виде чисел, (void*) 0 - это уже представление компилятора, как он видит это число, в памяти же calloc тебе заполняет просто нулями память, и как уже представлять эти нули уже твое дело, либо ты просто преобразуешь тип в указатель, либо в число либо в символ либо еще как-то.
Сообщение отредактировал Xakep - Среда, 02 Августа 2017, 10:04
type TExample = packed record a : Byte; b : Integer; end;
Берем и выясняем её размер: sizeof(example_s) = 5 байт
А так как, что в маллоке, что в каллоке я указываю размер структуры, а не количество байт, то о каком выравнивании в маллоке и отсутствии его же в каллоке может быть речь? Видимо дезинфо вычитал.
example_s *e = malloc(sizeof(example_s)); и example_s *e = calloc(1, sizeof(example_s)); printf("sizeof = %d\n", sizeof(*e)); дают одинаковые размеры
Сообщение отредактировал Vuvk - Среда, 02 Августа 2017, 14:40
то о каком выравнивании в маллоке и отсутствии его же в каллоке может быть речь? Видимо дезинфо вычитал.
Ну я думаю не совсем, malloc просто выделяет тебе непрерывный кусок памяти, сколько скажешь, столько и выделится, что делать с этой памятью дело уже твое, в твоем примере мы туда засовываем example_s и все его поля, мы знаем сколько нужно нам по факту, но сам malloc тоже должен начать откуда-то выделять память, он тебе как раз и возвращает границу памяти, с которой ты можешь начать читать и записывать данные. Сам по себе как реализован malloc зависит от компилятора и от стандартной библиотеки, к примеру иногда это просто вызов функции mmap - вроде бы системная функция дергается из ядра операционной системы. Один из способов - это разбить на зоны память - 16, 64, 256, 1024 итд, эти зоны уже выровненные и когда мне нужно выделить память под структуру размером 5 байт, то функция вернет адрес свободной зоны в которую структура может поместиться, в нашем случае - это 16, собственно после этого зона становится не свободной, когда же освобождаем память, мы можем просто указываем, что зона, в которой лежала структура, становится снова свободной и туда снова можно выделить память.
Ну я думаю не совсем, malloc просто выделяет тебе непрерывный кусок памяти, сколько скажешь, столько и выделится, что делать с этой памятью дело уже твое
ЦитатаXakep ()
эти зоны уже выровненные и когда мне нужно выделить память под структуру размером 5 байт, то функция вернет адрес свободной зоны в которую структура может поместиться, в нашем случае - это 16
Если бы это было так, то запихав "сжатую" структуру в выровненные 8 байт, я бы при попытке доступа к b (поле в example_s) получал бы адрес последнего её байта вместо первого (смотри под спойлер "типа схема" здесь и в предыдущем моем посте)
Если бы это было так, то запихав "сжатую" структуру в выровненные 8 байт, я бы при попытке доступа к b (поле в example_s) получал бы адрес последнего её байта вместо первого (смотри под спойлер "типа схема" здесь и в предыдущем моем посте)
и почему это? у тебя адрес у b начинается с адреса 1, а не с 4, какя тут связь не вижу, компилятор знает, что у тебя структура сжатая, вот и возвращает тебе смещение b немного по другому. А так у тебя получается примерно так: Зоны по 16 байт к примеру, выравнивание пусть будет по 8 байт:
Код
[abbbb 00000000] [a0000000 bbbb0000]
Первая структура у тебя упакованная, вторая нет, и в любом случае при обращении к s.a или s.b у тебя будет ссылаться на начало, где лежит эта переменная, по сути зоны также выровнены по степени двойки.
Сообщение отредактировал Xakep - Четверг, 03 Августа 2017, 11:18
в любом случае при обращении к s.a или s.b у тебя будет ссылаться на начало, где лежит эта переменная
так я с этим и не спорю, я говорю, что если бы, то. В общем я на свои два вопроса нашёл ответы: 1 на современных машинах нулевые указатели равны 0, так что можно их каллокать. 2 "также я натыкался на информацию, что malloc выравнивает данные, а calloc нет." - фигня.
так я с этим и не спорю, я говорю, что если бы, то.
Просто ты не ответил почему это было бы так, где можно прочитать про подобное поведение, что у упакованной структуры указатель должен оказаться в конце b? как вообще в этом может быть виноват malloc и его способность к выравниванию данных, при том что malloc вообще знать не знает о структуре, под которую ты пытаешься выделить память.
ЦитатаVuvk ()
1 на современных машинах нулевые указатели равны 0, так что можно их каллокать.
Не на современных машинах, а компилятор их так представляет, с таким же успехом в другом яп нулевой указатель может быть предствлен в виде более сложной структуры.
Сообщение отредактировал Xakep - Четверг, 03 Августа 2017, 11:23