Пятница, 15 Ноября 2024, 22:50

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

[ Новые сообщения · Игроделы · Правила · Поиск ]
Вопрос-Ответ (C++)
KornivalДата: Воскресенье, 04 Сентября 2011, 19:10 | Сообщение # 1
The Witcher
Сейчас нет на сайте
Чтобы не создавать отдельную тему на каждый глупый вопрос, предлагаю задавать их здесь.

Saitei: все вопросы по С задаём в теме Вопрос-Ответ (С). Благодарю за внимание!
MrAkakuyДата: Суббота, 15 Сентября 2012, 09:48 | Сообщение # 661
участник
Сейчас нет на сайте
Здравствуйте товарисчи.
Возник у меня такой вопрос: использую в коде WinApi функцию GetKeyState(). Думаю все знают, что передавать в нее надо ascii-код нужной клавиши. Так же в "WinUser.h" есть заранее объявленные константы клавиш (VK_UP, VK_DOWN, VK_SPACE и др.). Когда я использую эти константы, все работает отлично. Если подставляю вместо них коды из ascii таблицы, то тут и начинается вся проблема. Если отправляю в функцию коды таких клавиш, как пробел например (0x20), то все так же работает. Однако стоит подставить код символа 'w' (0x77), то нихохо не работает. Может подскажите в чем проблема? С меня плюс.

ПИ.СИ.: вызываю GetKeyState() так:
Code
if (GetKeyState(<код клавиши>) & 0x80)
      // тра та та



ArchidoДата: Суббота, 15 Сентября 2012, 10:24 | Сообщение # 662
Сэнсэй
Сейчас нет на сайте
Используй 'W' (большую) и все будет ок wink

C++ - он особенный. С помощью него можно не только выстрелить себе в ногу, но и повеситься в пустой комнате:)
MrAkakuyДата: Суббота, 15 Сентября 2012, 12:31 | Сообщение # 663
участник
Сейчас нет на сайте
Quote (Archido)
Используй 'W' (большую) и все будет ок

Попробую потом, спасибо.



clidiДата: Суббота, 15 Сентября 2012, 13:21 | Сообщение # 664
почетный гость
Сейчас нет на сайте
У меня две структуры. Эти структуры используют друг друга. Например есть функция где возвращается объект типа другой структуры. У меня почему то ошибка и пишет что неопределенный тип данных. До определения в хедер файле задекларировал 2е эти структуры. Помогите пожалуйста.
ArchidoДата: Суббота, 15 Сентября 2012, 13:41 | Сообщение # 665
Сэнсэй
Сейчас нет на сайте
clidi
Неплохо бы листинг с кодом привести, чтобы не гадать на кофейной гуще smile


C++ - он особенный. С помощью него можно не только выстрелить себе в ногу, но и повеситься в пустой комнате:)
Animan2010Дата: Пятница, 21 Сентября 2012, 16:45 | Сообщение # 666
постоянный участник
Сейчас нет на сайте
Никто не знает, как в HGE загружать ресурсы из дополнительных директорий? (К примеру, не "picture.jpg", а "%папка_проекта%/Data/picture.jpg")
А, разобрался, вместо знака \ надо \\ писать (hge->texture_load("Data\\file.jpg");)


Anima Games
Animan Publishing


Сообщение отредактировал Animan2010 - Пятница, 21 Сентября 2012, 16:54
RomanNVKZДата: Пятница, 21 Сентября 2012, 17:02 | Сообщение # 667
участник
Сейчас нет на сайте
Из моей игры:
ball_tex=hge->Texture_Load("resources/textures/Sprites/ball.png");




SWFcreatorДата: Понедельник, 24 Сентября 2012, 19:05 | Сообщение # 668
участник
Сейчас нет на сайте
Всем привет. Вот такой вопрос у меня: при создании массива оператором new[], delete[] точно знает сколько элементов удалить. Откуда??? Где это храниться и как это узнать? В интернете мало что нашел, в основном, что хранится где-то возле массива. На любимый вопрос - зачем тебе надо - сразу отвечу: конкретно низачем, так интересно и может пригодиться.
ArchidoДата: Понедельник, 24 Сентября 2012, 19:21 | Сообщение # 669
Сэнсэй
Сейчас нет на сайте
Где хранить - отдано на откуп тем кто реализовывает данные операторы (писатели компиляторов), насколько я знаю стандартом это не регламентировано. Поэтому может быть как угодно, но хранят обычно прямо перед выделенным блоком 4 байта (Pblock - 4 bytes), там и записано кол-во элементов.

C++ - он особенный. С помощью него можно не только выстрелить себе в ногу, но и повеситься в пустой комнате:)

Сообщение отредактировал Archido - Понедельник, 24 Сентября 2012, 19:22
SWFcreatorДата: Понедельник, 24 Сентября 2012, 19:39 | Сообщение # 670
участник
Сейчас нет на сайте
То есть, я могу просто взять long *, присвоить ему любой дин. массив, приведенный к int *, сместить его назад и узнать размер?

Добавлено (24.09.2012, 19:36)
---------------------------------------------
Не получается, там записано 241 вместо 55 (от фонаря взял массив - 55 интов). Поделил на sizeof(int) - 60, уже ближе. Итак, чувствую, что это он, но почему 60?

Добавлено (24.09.2012, 19:39)
---------------------------------------------
Code

#include <iostream>

int main()
{
int *a = new int[55];
long *b = (long *) a;
b--;
std::cout << *b / sizeof (int) << std::endl;                             //60 != 55
return 0;
}


Сообщение отредактировал SWFcreator - Понедельник, 24 Сентября 2012, 19:40
RUNGOGET2THECHOPAHДата: Понедельник, 24 Сентября 2012, 19:48 | Сообщение # 671
участник
Сейчас нет на сайте
SWFcreator, не b--, а b = b - sizeof(int). Инты не везде имеют единичный размер.
SWFcreatorДата: Понедельник, 24 Сентября 2012, 20:08 | Сообщение # 672
участник
Сейчас нет на сайте
b у меня нарочно long, он везде 4 байта, в отличие от int. Попробовал с разным числом элементов на G++. Странно, число почти всегда выдавало или 8 или 12 при кол-ве элементов от 2 до 11.

Добавлено (24.09.2012, 19:57)
---------------------------------------------
Вроде и не рандомное, но бессмысленное smile . Чувствую себя детективом cool biggrin

Добавлено (24.09.2012, 20:06)
---------------------------------------------
Проверил, я в шоке:
long - 8, int - 4(!!!), short - 2.
теперь использую int - a[-1] == 0.

Добавлено (24.09.2012, 20:08)
---------------------------------------------
от short я этого и ждал, long - пускай, у меня x64, но int вроде как должен совпадать с одним из них.

Сообщение отредактировал SWFcreator - Понедельник, 24 Сентября 2012, 19:59
НохчиДата: Понедельник, 24 Сентября 2012, 21:36 | Сообщение # 673
заслуженный участник
Сейчас нет на сайте
Quote (SWFcreator)
int вроде как должен совпадать с одним из них.

Ничего он никому не должен.
По сабжу, new/delete опирается на системные функции ос. В винде это HeapAlloc/HeapFree. Внутри HeapFree вызывается HeapSize(), который возвращает размер блока памяти выделенной с помощью HeapAlloc.


Многие вопросы по Windows отпадут, если посмотреть тут
ArchidoДата: Вторник, 25 Сентября 2012, 07:34 | Сообщение # 674
Сэнсэй
Сейчас нет на сайте
Quote (SWFcreator)
Проверил, я в шоке: long - 8, int - 4(!!!), short - 2.

У Линуксов (и Mac OS X) размер Long'a зависит от разрядности ОС (32 / 64), int - всегда 4 байта, short 2. В винде long как и int - всегда 4 (даже при 64 ОС).

Конкретно про выделение куска памяти в винде Нохчи правду написал - все сишные ф-ции выделения памяти дергают Win API, в Линуксах API как-бы то и нет happy , и malloc (new использует его) там некоторое нагромождение кода, который всем и занимается. Но в любом случае, около выделенных блоков должна храниться (и хранится) некая служебная информация по которой можно точно идентифицировать необходимый блок (в списке, табличке, etc), например (в простом случае) хранить перед блоком его Id или указатель. Зная его Id, можно сделать выборку из спец. таблички, получить некую структуру данных для данного блока, которая содержит например начало, размер, сылки на соседние блоки, etc и после чего его можно правильно удалить - этим занимается менеджер памяти, в каждой ОС он отличается и деталей реализации никто не знает(в Линуксах правда можно в ядро заглянуть smile )

В #669 я писал конкретно про операторы new[] и delete[], которые кроме простого выделения памяти занимаются еще и вызовом конструкторов \ деструкторов у пачки объектов. Оператор delete[] имеет всего один параметр - указатель на область памяти, но при этом он должен знать у скольких объектов вызывать деструкторы, делается это обычно когда деструкторы нетривиальные (свои собственные, не по умолчанию). Тогда оператор new[] резервирует на 4 байта больше памяти и кладет кол-во выделенных элементов в самом начале блока (т.е. new возвращает указатель на, скажем, массив - pArray, а кол-во элементов будет лежать в pArray - 1), основываясь на которых delete[] правильно вызовет деструкторы. Реализация полностью зависит от компилятора, он может как хранить эти 4 байта, так и нет (когда не объявлены деструкторы), разные компиляторы могут хранить это по-разному.

Например, MSVC, при таком коде хранит количество элементов, как я описал выше:
Code

struct DataType {
       int A;

       ~DataType() {
          A = 0;
       }
};
DataType* pArray = new DataType[20];

int Size = *((int*)pArray - 1); // тут будет 20
std::cout << "Count: " << Size << std::endl;     


C++ - он особенный. С помощью него можно не только выстрелить себе в ногу, но и повеситься в пустой комнате:)

Сообщение отредактировал Archido - Вторник, 25 Сентября 2012, 07:40
SWFcreatorДата: Вторник, 25 Сентября 2012, 14:41 | Сообщение # 675
участник
Сейчас нет на сайте
Нохчи, я с Линуксом играюсь.
Archido, Спасибо. Да, в Линуксе заменил int на long и заработало. Когда меняю тип массива или убираю деструктор - выдает число, которое я получал раньше.

Добавлено (25.09.2012, 14:41)
---------------------------------------------
жаль sad , что нельзя узнать размер любого массива

ArchidoДата: Вторник, 25 Сентября 2012, 15:00 | Сообщение # 676
Сэнсэй
Сейчас нет на сайте
Quote (SWFcreator)
жаль , что нельзя узнать размер любого массива

На это и не стоит рассчитывать smile , т.к. языком это не гарантируется. Т.е. однажды в новой версии компилятора разработчики захотят хранить это не в начале блока, а в конце (ну вот хочется им), и весь написанный код, который использовал данный "хак" работать перестанет.

С++ - это все таки ООП язык и неплохо бы использовать, соответствующие этому, средства, а конструкции вида "int* Array = new int[100]" - это простой Си (ну, за исключением new, но есть malloc), такое использовать смысла нет (почти нет, редко по уму только). Спп'шным массивом является std::vector или аналог, которые являются высокоуровневой оберткой над Си-подобным кодом. Такой массив - динамический, автоматически занимается освобождением \ выделением памяти, знает свой размер biggrin (и нет смысла использовать подобные "хаки" с кол-вом элементов), может осуществлять проверку выхода за границу массива и так далее... Вот таким и надо пользоваться wink


C++ - он особенный. С помощью него можно не только выстрелить себе в ногу, но и повеситься в пустой комнате:)
SWFcreatorДата: Вторник, 25 Сентября 2012, 15:37 | Сообщение # 677
участник
Сейчас нет на сайте
Archido, знаю, я на С++ дальше наследования не зашел, потому фактически использую С и стараюсь компилировать GCC, если не нужны классы. А когда нужны - вот так и делаю.
DracДата: Воскресенье, 30 Сентября 2012, 11:07 | Сообщение # 678
частый гость
Сейчас нет на сайте
Киньте литературу (желательно онлайн) по visual c++, именно по визуальной части.

Всем добра =)
НохчиДата: Воскресенье, 30 Сентября 2012, 12:00 | Сообщение # 679
заслуженный участник
Сейчас нет на сайте
Quote (Drac)
именно по визуальной части.

Что это значит? MFC что ли?


Многие вопросы по Windows отпадут, если посмотреть тут
DracДата: Воскресенье, 30 Сентября 2012, 13:05 | Сообщение # 680
частый гость
Сейчас нет на сайте
Все, что я нашел были уроки по программированию консольных программ, мне нужны окна, кнопки и тому подобное ! Так как азы уже давно позади.

Всем добра =)
Поиск:

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