Среда, 27 Ноября 2024, 11:55

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 2
  • 1
  • 2
  • »
Вопрос-Ответ (С)
SaiteiДата: Понедельник, 20 Апреля 2015, 21:39 | Сообщение # 1
старожил
Сейчас нет на сайте
Здесь задаем вопросы и пытаемся ответить на существующие по языку программирования С.

Если у вас возник вопрос по языку программирования С++, то вы можете задать его здесь.
VampalДата: Пятница, 19 Июня 2015, 19:08 | Сообщение # 2
был не раз
Сейчас нет на сайте
Как в С-скрипте поставить паузу?
PoidetLiДата: Пятница, 19 Июня 2015, 19:19 | Сообщение # 3
участник
Сейчас нет на сайте
Цитата Vampal ()
Как в С-скрипте поставить паузу?

если извращенский вариант, то
while(!pause){}
а если, нормальный то system("pause");


в еюдуго прсхлуренц
http://gcup.ru/forum/9-44187-1 мой Project 96
VampalДата: Пятница, 19 Июня 2015, 19:57 | Сообщение # 4
был не раз
Сейчас нет на сайте
PoidetLi, Благодарствую!
SaiteiДата: Вторник, 23 Июня 2015, 15:35 | Сообщение # 5
старожил
Сейчас нет на сайте
Цитата PoidetLi ()
если извращенский вариант, то
while(!pause){}
а если, нормальный то system("pause");

system("pause") прокатит только в Windows, если не ошибаюсь.
Кстати, ещё можно сделать system("PAUSE >> VOID");, чтобы скрыть надпись "Для продолжения нажмите любую клавишу...".

Есть ещё варианты: ждать нажатия через getch()/getchar(). Ну или если ты знаешь на сколько мс нужна пауза, то ты можешь использовать Sleep(...) из <Windows.h>
OpenGOOДата: Вторник, 23 Июня 2015, 19:05 | Сообщение # 6
почти ветеран
Сейчас нет на сайте
Для винды можно ещё и так
Код
while(! _kbhit())
{
     Sleep(100);
}


Мои проекты:
- Свободный и открытый клон World Of Goo
- TrueEngine2D (2D игровой фреймворк основанный на FreeBASIC)

[GameMaker: Studio v1.4.9999]
FumleadДата: Вторник, 23 Июня 2015, 21:02 | Сообщение # 7
участник
Сейчас нет на сайте
Слегка порывшись в гугле, я нашел кроссплатформенный способ (по крайней мере, на Linux работает happy )
Вот он:

Кстати, использовать команды system в продакшине не рекомендуют.

Saitei: iostream - это уже С++. Будьте внимательнее.


Параноик с гениальным планом по захвату мира.
IzaronДата: Вторник, 23 Июня 2015, 21:37 | Сообщение # 8
Rammstein forever
Сейчас нет на сайте
Если включить флаг -c++11 (для C++), то консоль не закрывается до нажатия клавиши. В C11 наверняка так же
dreenlineДата: Воскресенье, 02 Августа 2015, 12:31 | Сообщение # 9
постоянный участник
Сейчас нет на сайте
Почему в C# пишут -=? Например вот здесь lifetime -= Time.deltaTime; ? Что значит этот минус?
YellowAfterlifeДата: Воскресенье, 02 Августа 2015, 12:58 | Сообщение # 10
Сейчас нет на сайте
Цитата dreenline ()
Почему в C# пишут -=? Например вот здесь lifetime -= Time.deltaTime; ? Что значит этот минус?

"a -= b" это синтаксический сахар для "a = a - b". Реализуется в языках для удобства (меньше повторяемого кода).


GudleifrДата: Воскресенье, 02 Августа 2015, 13:26 | Сообщение # 11
почти ветеран
Сейчас нет на сайте
Цитата YellowAfterlife ()
"a -= b" это синтаксический сахар для "a = a - b"
Ни в коем случае. Это не "сахар", а реализация первичных ф-ий языка C - как можно ближе к процессору, и как можно мощнее выражения. Например, приведенная "фраза", это не "оператор подобный :=", а выражение, которое имеет значение и может быть присвоено кому-то еще.
Да, "a <оп>= b" то же самое, что и "a = a <op> b" на уровне обычного кодинга, но "начинка" совершенно другая (а в C++ ее можно сделать имеющей совершенно иной смысл).
Называть "a -=b" сахаром для "a = a - b", это все равно, что называть "a - b" сахаром для "a + -b".


Быдлокодеры любят повторять: "логика, убивающая мозг",- когда их пытаются заставить программировать.

Сообщение отредактировал Gudleifr - Воскресенье, 02 Августа 2015, 13:29
rrrferДата: Воскресенье, 02 Августа 2015, 13:28 | Сообщение # 12
частый гость
Сейчас нет на сайте
Цитата
"a -= b" это синтаксический сахар для "a = a - b". Реализуется в языках для удобства (меньше повторяемого кода).

Не только сахар. Оператор -= работает только с двумя переменными (объектами).
Но в a = a - b все не так просто (особенно если переменные не элементарных типов {ведь выше речь о C#}). При выполнении (a-b) создается новый временный объект со значением результата, а затем выполняется присваивание. При этом присваивание - это не такая простая и быстрая операция, т.к. запускается сборка мусора (старый объект ведь теперь не существует). После присваивания деструктором уничтожается временный объект, который хранил (a-b).

Поэтому a -= b может быть гораздо эффективнее в объектно-ориентированных языках типа С++/C#/...:)
VuvkДата: Среда, 02 Августа 2017, 05:54 | Сообщение # 13
заслуженный участник
Сейчас нет на сайте

Итак, новые дилетантские вопросы от Антона (меня, то есть).
Как я уже отметил в отдельной теме, я пишу игровой движок на чистом Си и имитирую некоторые ООПшные подходы. Вместо классов у меня структуры и я всячески ими манипулирую. Ну так вот. После создания "класса" через malloc на выходе получалась забитая мусором структура и в "конструкторах" я затирал поля в 0. Потом я подумал, что всё это можно заменить одним простым calloc. А позже наткнулся на эту статью, которая подтверждала правильность решения:
Цитата
Никогда не используйте malloc
Привыкайте к calloc. С этой функцией вам не грозит снижение производительности при очистке памяти.

Но также я натыкался на информацию, что malloc выравнивает данные, а calloc нет. И у меня теперь есть некоторые сомнения. На проверяемых компуктерах всё работает исправно, но могут ли быть проблемы на каком-то другом железе или времена процессоров, не умеющих работать с невыравненными значениями, канули в Лету?
Теперь второй вопрос. О нулевых указателях - NULL. NULL определен как (void*)0. Это не математический 0, он преобразуется компилятором в указатель на какую-то область памяти, которая на разных платформах - разная. (Читал в какой-то книге в форме вопрос-ответ по Си. Не могу найти, но ссылку предоставлю позднее). Итак сам вопрос. Вот у меня есть структуры, в которых есть указатели. Я создаю их через calloc(1, sizeof(any_struct)), то в указатель попадёт 0. Но ведь 0 попадёт "математический" и в момент исполнения программы. Как быть уверенным, что этот 0 будет нулевым указателем? Или не будет? Опять же вроде работает, но вдруг на каких-то машинах это работать не будет?
Вот такие вопросы новичка. (начал изучение Си пару месяцев назад, не пинайте, судари)

Добавлено (02 августа 2017, 05:54)
---------------------------------------------
По поводу моего второго вопроса, видимо, на современных компах можно не париться. Я вчера не мог найти, откуда я взял инфу про путаницу с нулевыми указателями, но сегодня нашёл:



Сообщение отредактировал Vuvk - Вторник, 01 Августа 2017, 20:25
XakepДата: Среда, 02 Августа 2017, 10:01 | Сообщение # 14
めちゃくちゃちゃ
Сейчас нет на сайте
Цитата Vuvk ()
времена процессоров, не умеющих работать с невыравненными значениями, канули в Лету?

this, но невыровненные данные могут быть прчиной снижения производительности, так что просто можешь создать свою функцию для выделения памяти, которая будет выравнивать данные, либо вообще использовать альтернативные аллокаторы памяти, пара ссылок:
https://stackoverflow.com/questio....0
Альтернативные аллокаторы памяти
Цитата Vuvk ()
Вот у меня есть структуры, в которых есть указатели. Я создаю их через calloc(1, sizeof(any_struct)), то в указатель попадёт 0. Но ведь 0 попадёт "математический" и в момент исполнения программы. Как быть уверенным, что этот 0 будет нулевым указателем? Или не будет?

что-то я не понял ))) у тебя в компьютере все представленно в виде чисел, (void*) 0 - это уже представление компилятора, как он видит это число, в памяти же calloc тебе заполняет просто нулями память, и как уже представлять эти нули уже твое дело, либо ты просто преобразуешь тип в указатель, либо в число либо в символ либо еще как-то.


Сообщение отредактировал Xakep - Среда, 02 Августа 2017, 10:04
VuvkДата: Среда, 02 Августа 2017, 10:35 | Сообщение # 15
заслуженный участник
Сейчас нет на сайте
Xakep, дык ты прочти цитаты, которые я привел. п.1.14.
Цитата
невыровненные данные могут быть прчиной снижения производительности

Эт я знаю.
За ссылки спасибо.

Сейчас решил сотворить финт ушами. Есть некая структура, к примеру

Берем и выясняем её размер: sizeof(example_s) = 8 байт. Почему? А потому что выравнялись поля в кратное 4 (размер инт):

Потом я говорю компилятору - выравнивание офф!


Берем и выясняем её размер: sizeof(example_s) = 5 байт

А так как, что в маллоке, что в каллоке я указываю размер структуры, а не количество байт, то о каком выравнивании в маллоке и отсутствии его же в каллоке может быть речь? Видимо дезинфо вычитал.


Сообщение отредактировал Vuvk - Среда, 02 Августа 2017, 14:40
XakepДата: Среда, 02 Августа 2017, 17:37 | Сообщение # 16
めちゃくちゃちゃ
Сейчас нет на сайте
Цитата Vuvk ()
то о каком выравнивании в маллоке и отсутствии его же в каллоке может быть речь? Видимо дезинфо вычитал.

Ну я думаю не совсем, malloc просто выделяет тебе непрерывный кусок памяти, сколько скажешь, столько и выделится, что делать с этой памятью дело уже твое, в твоем примере мы туда засовываем example_s и все его поля, мы знаем сколько нужно нам по факту, но сам malloc тоже должен начать откуда-то выделять память, он тебе как раз и возвращает границу памяти, с которой ты можешь начать читать и записывать данные. Сам по себе как реализован malloc зависит от компилятора и от стандартной библиотеки, к примеру иногда это просто вызов функции mmap - вроде бы системная функция дергается из ядра операционной системы. Один из способов - это разбить на зоны память - 16, 64, 256, 1024 итд, эти зоны уже выровненные и когда мне нужно выделить память под структуру размером 5 байт, то функция вернет адрес свободной зоны в которую структура может поместиться, в нашем случае - это 16, собственно после этого зона становится не свободной, когда же освобождаем память, мы можем просто указываем, что зона, в которой лежала структура, становится снова свободной и туда снова можно выделить память.
VuvkДата: Четверг, 03 Августа 2017, 07:02 | Сообщение # 17
заслуженный участник
Сейчас нет на сайте
Цитата Xakep ()
Ну я думаю не совсем, malloc просто выделяет тебе непрерывный кусок памяти, сколько скажешь, столько и выделится, что делать с этой памятью дело уже твое

Цитата Xakep ()
эти зоны уже выровненные и когда мне нужно выделить память под структуру размером 5 байт, то функция вернет адрес свободной зоны в которую структура может поместиться, в нашем случае - это 16

Если бы это было так, то запихав "сжатую" структуру в выровненные 8 байт, я бы при попытке доступа к b (поле в example_s) получал бы адрес последнего её байта вместо первого (смотри под спойлер "типа схема" здесь и в предыдущем моем посте)

А то, как поведет себя аллокатор, сильно зависит от его реализации, ага.
Нарыл тут ещё интересную статейку.


Сообщение отредактировал Vuvk - Четверг, 03 Августа 2017, 07:51
XakepДата: Четверг, 03 Августа 2017, 08:44 | Сообщение # 18
めちゃくちゃちゃ
Сейчас нет на сайте
Цитата Vuvk ()
Если бы это было так, то запихав "сжатую" структуру в выровненные 8 байт, я бы при попытке доступа к b (поле в example_s) получал бы адрес последнего её байта вместо первого (смотри под спойлер "типа схема" здесь и в предыдущем моем посте)

и почему это? у тебя адрес у b начинается с адреса 1, а не с 4, какя тут связь не вижу, компилятор знает, что у тебя структура сжатая, вот и возвращает тебе смещение b немного по другому. А так у тебя получается примерно так:
Зоны по 16 байт к примеру, выравнивание пусть будет по 8 байт:
Код

[abbbb 00000000] [a0000000 bbbb0000]

Первая структура у тебя упакованная, вторая нет, и в любом случае при обращении к s.a или s.b у тебя будет ссылаться на начало, где лежит эта переменная, по сути зоны также выровнены по степени двойки.


Сообщение отредактировал Xakep - Четверг, 03 Августа 2017, 11:18
VuvkДата: Четверг, 03 Августа 2017, 09:23 | Сообщение # 19
заслуженный участник
Сейчас нет на сайте
Цитата Xakep ()
в любом случае при обращении к s.a или s.b у тебя будет ссылаться на начало, где лежит эта переменная

так я с этим и не спорю, я говорю, что если бы, то. В общем я на свои два вопроса нашёл ответы:
1 на современных машинах нулевые указатели равны 0, так что можно их каллокать.
2 "также я натыкался на информацию, что malloc выравнивает данные, а calloc нет." - фигня.
XakepДата: Четверг, 03 Августа 2017, 11:21 | Сообщение # 20
めちゃくちゃちゃ
Сейчас нет на сайте
Цитата Vuvk ()
так я с этим и не спорю, я говорю, что если бы, то.

Просто ты не ответил почему это было бы так, где можно прочитать про подобное поведение, что у упакованной структуры указатель должен оказаться в конце b? как вообще в этом может быть виноват malloc и его способность к выравниванию данных, при том что malloc вообще знать не знает о структуре, под которую ты пытаешься выделить память.

Цитата Vuvk ()
1 на современных машинах нулевые указатели равны 0, так что можно их каллокать.

Не на современных машинах, а компилятор их так представляет, с таким же успехом в другом яп нулевой указатель может быть предствлен в виде более сложной структуры.


Сообщение отредактировал Xakep - Четверг, 03 Августа 2017, 11:23
  • Страница 1 из 2
  • 1
  • 2
  • »
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг