Вопрос-Ответ (C++)
| |
Kornival | Дата: Воскресенье, 04 Сентября 2011, 19:10 | Сообщение # 1 |
The Witcher
Сейчас нет на сайте
| Чтобы не создавать отдельную тему на каждый глупый вопрос, предлагаю задавать их здесь.
Saitei: все вопросы по С задаём в теме Вопрос-Ответ (С). Благодарю за внимание!
|
|
| |
Vuvk | Дата: Четверг, 20 Июля 2017, 11:19 | Сообщение # 1521 |
заслуженный участник
Сейчас нет на сайте
| Цитата FlyOfFly ( ) в заголовочный файлах F1, есть подключен заголовочный файл F2, в которых подключен заголовочный файл F1, если в этом, то какой вариант - исправление? попробовать выбросить #pragma once и использовать include guards
Код #ifndef _F1_H #define _F1_H // содержимое хедэра #endif // _F1_H
Сообщение отредактировал Vuvk - Четверг, 20 Июля 2017, 11:28 |
|
| |
puksus | Дата: Четверг, 20 Июля 2017, 12:03 | Сообщение # 1522 |
Пчёлка Зоя
Сейчас нет на сайте
| FlyOfFly, а зачем вам 2 класса, нельзя ли провернуть так, чтобы класс хранил указатели на элементы своего же класса?
Ну а если по теме - то может помочь <не помню точно как называется> предобъявление класса. То есть в файле GameComponent.h удалите строчку #include "GameObject.h" и добавьте вместо неё class GameObject; это даст компилятору инфу о том, что класс геймобджект определён в ином месте, при этом взаимное подключение исчезнет. Но не гарантирую, что поможет. Да и потом могут быть проблемы. Я с таким уже сталкивался, когда писал игру на 12 гамирон. Из-за этого дела потом вылезали очень непонятные ошибки в непонятных местах, когда я что-то где-то чуть-чуть менял. Поэтому следующем проекте просто сделал всё так, чтобы не было нужды в подобных вещах. Ну а ещё, старайтесь в h файлах подключать по-минимуму, а основные подключения делать в cpp файлах.
https://vk.com/beezoya
|
|
| |
Saitei | Дата: Пятница, 21 Июля 2017, 11:09 | Сообщение # 1523 |
старожил
Сейчас нет на сайте
| Цитата puksus ( ) GameComponent.h удалите строчку #include "GameObject.h" и добавьте вместо неё class GameObject; это даст компилятору инфу о том, что класс геймобджект определён в ином месте, +
Это называется forward declaration: https://en.wikipedia.org/wiki/Forward_declaration
На место всех include подставляются исходные коды. В твоем же случае получается своего рода рекурсия, компилятор просто не знает что делать. Поэтому действительно надо просто сослаться на класс с таким-то названием, но не подключать его файл описания
P.S. это работает с ссылками и указателями на класс, а вот просто инстансировать объект ты не сможешь:
Код class Foo; ... Foo a; //wrong! Error!
|
|
| |
FlyOfFly | Дата: Суббота, 22 Июля 2017, 14:41 | Сообщение # 1524 |
заслуженный участник
Сейчас нет на сайте
| Есть массив с указателями на функциями и двухмерный массив, который хранит аргументы(то-есть на каждую функцию - своя строка массива). Я не знаю какие функции храниться и сколько аргументов в массиве, можно ли как-то вызвать функцию такую?По логике, это должно делаться через asm, то-есть отправляем аргументы через push и потом вызываем функции через call, насколько я знаю в vs можно вызвать asm код, вопрос: как передать аргументы и вызвать функцию через asm-вставки Добавлено (22 июля 2017, 14:41) --------------------------------------------- Так, как отправить аргументы - разобрался, другой вопрос: как через asm вызвать функцию объекта
Сообщение отредактировал FlyOfFly - Суббота, 22 Июля 2017, 14:29 |
|
| |
Dmitriy_Zodiak | Дата: Воскресенье, 03 Сентября 2017, 01:05 | Сообщение # 1525 |
частый гость
Сейчас нет на сайте
| zodiak, вот зараза. Я думал такого ника нет.
В ютубе и многих сайтах криво и не информативно рассказанно . Скиньте хороших мануалов плз.
|
|
| |
bodya_WM | Дата: Воскресенье, 03 Сентября 2017, 08:28 | Сообщение # 1526 |
постоянный участник
Сейчас нет на сайте
| FlyOfFly, в методах класса используется конвенция вызовов __thiscall. Тебе нужно получить указатель на функцию в классе(например вот так):
Код class Foo { void Bar(); }; ... Foo* foo = new Foo(); void* bar = Bar; __asm { push foo call bar }
__thiscall практически такой же как и cdecl, только ещё последним параметром добавляется указатель на экземпляр класса. Ответ немного запоздалый но возможно поможет.
Разработчик игрового движка WaveGameEnvironment2D
Сообщение отредактировал bodya_WM - Воскресенье, 03 Сентября 2017, 08:29 |
|
| |
Saitei | Дата: Воскресенье, 03 Сентября 2017, 12:04 | Сообщение # 1527 |
старожил
Сейчас нет на сайте
| Цитата bodya_WM ( ) void* bar = Bar; не думаю, что валидно.
Код typedef void (Foo::*FuncPtr)(); FuncPtr bar = &Foo::Bar;
|
|
| |
CupcakeGames | Дата: Пятница, 24 Ноября 2017, 15:42 | Сообщение # 1528 |
уже был
Сейчас нет на сайте
| Пользователь вводит Hello world! Аргументы: string text = "Hello world!" string separator = " "(разделитель) Результат: string result[0] == "Hello" string result[1] == "world!"
I LOVE GCUP!
|
|
| |
allods | Дата: Вторник, 12 Февраля 2019, 21:27 | Сообщение # 1529 |
почти ветеран
Сейчас нет на сайте
| Ребят помогите Помогите понять этот кусок когда
Код ui16 allowedFactions = reader.readUInt8(); // How many factions will be read from map ui16 totalFactions = GameConstants::F_NUMBER;
if(mapHeader->version != EMapFormat::ROE) allowedFactions += reader.readUInt8() * 256; else totalFactions--; //exclude conflux for ROE
for(int fact = 0; fact < totalFactions; ++fact) { if(!(allowedFactions & (1 << fact))) { mapHeader->players[i].allowedFactions.erase(fact); } }
а именно if(!(allowedFactions & (1 << fact)))
Сообщение отредактировал allods - Вторник, 12 Февраля 2019, 21:29 |
|
| |
drcrack | Дата: Вторник, 12 Февраля 2019, 22:01 | Сообщение # 1530 |
старожил
Сейчас нет на сайте
| (1 << fact) дает число в котором бит номер fact (считая справа с нуля) установлен в 1, остальные в 0 т.е. в двоичной это 1, 10, 100, 1000 и так далее дальше ты применяешь эту маску к allowedFactions, т.е. из этого числа остается только один бит, остальные выставляются в 0 в итоге получается проверка, чему равен определенный бит в allowedFactions если бит был 0, получается 0 (false), если бит был 1, получается не-0, а именно 2 в степени fact (но главное что не 0, т.е. true) и потом это еще отрицается (!) короче, если allowedFactions например 9, т.е. 1001 в двоичной, код выполнится на 2 и 3 итерации, а на 1 и 4 нет
Сообщение отредактировал drcrack - Вторник, 12 Февраля 2019, 22:04 |
|
| |
DivES | Дата: Вторник, 12 Февраля 2019, 22:11 | Сообщение # 1531 |
заслуженный участник
Сейчас нет на сайте
| allods, объяснить в точности не смогу, но "помочь понять", как просишь - постараюсь Начнём с &. Это поразрядная конъюнкция (или умножение). То есть, если взядь два числа, например 110 и 100, то результатом 110 & 100 будет 100. Возьмём 110 и 010, результат 110 & 010 = 10. Результат равен "умножению" чисел. 1*0 = 0, 1*1 = 1, 0*0 = 0 -> получаем 10, так как 0 слева отбрасывается. Объяснил, как смог, в остальном можешь почитать на тему конъюнкции!
Далее идёт <<. Это побитовый сдвиг. Тут понять проще. 01 << 1 = 10 (в двоичной) или 2 (в десятичной). 0010 << 1 = 0100. 0110 << 1 = 1100. 0110 << 2 = 1000. (биты, сдвинуты за пределы - теряются) То есть просто перемещаем битовые значения по разрядам.
Ну а теперь мы подошли к пониманию этой условной конструкции. Она будет срабатывать до тех пор, пока значение во внутренних скобках будет равняться нулю. Ведь только в этом случае значение во внешних скобках будет принимать значение истины. Поправьте, если ошибся Добавлено (12 Февраля 2019, 22:25) --------------------------------------------- (allowedFactions & (1 << fact)) - внутренние скобки; (!(allowedFactions & (1 << fact))) - внешние. Вот что имелось в виду
|
|
| |
allods | Дата: Вторник, 12 Февраля 2019, 22:27 | Сообщение # 1532 |
почти ветеран
Сейчас нет на сайте
| спасибо за ответы , просто я только "скриптю" и там по другому многое пишется. mapHeader->players[i].allowedFactions.erase(fact); здесь как бы стираем часть значения из players[i].allowedFactions ? если fact = 5 то если players[i].allowedFactions == 123456789 то получим 12346789 ?
Код ui16 allowedFactions = reader.readUInt8(); // How many factions will be read from map ui16 totalFactions = GameConstants::F_NUMBER; а здесь почему ui16 ? в чем его фишка
Сообщение отредактировал allods - Вторник, 12 Февраля 2019, 22:29 |
|
| |
DivES | Дата: Вторник, 12 Февраля 2019, 22:38 | Сообщение # 1533 |
заслуженный участник
Сейчас нет на сайте
| allods, 123456789 в двоичной системе это 111010110111100110100010101. Побитовые операции на то и побитовые, что работают с битами То есть числа всегда прежде переводятся в соответствующую систему координат. По поводу 111010110111100110100010101 << 5... результат такой: 11101011011110011010001010100000 (в двоичной) или 3950617248 (в десятичной). Проверил на C++ и через перевод из одной системы в другую. Как видишь, в данном случае всё сдвинулось влево на пять знаков. Но для правильной работы мне пришлось работать с типом long int. В твоём же случае работа идёт с ui16, то есть unsinged int. При этом в двоичной записи там сможет поместиться лишь 16 бит, насколько я понимаю Добавлено (12 Февраля 2019, 22:46) ---------------------------------------------
Цитата allods ( ) а здесь почему ui16 ? в чем его фишка Я уже успел опередить этот вопрос своим ответом, но ещё дополню.
Смотри, 65535 (десятичное) - верхний предел типа unsigned int (ui16). В двоичном виде это 1111111111111111 (их 16). Если мы попытаемся сдвинуть значение переменной этого типа на один влево (<< 1), то получим 1111111111111110, так как биты, сдвинутые за пределы - теряются. 1111111111111111 << 3 = 1111111111111000, 1111111111111111 << 8 = 1111111100000000 (ровно до "половины") и так далее Добавлено (12 Февраля 2019, 22:50) --------------------------------------------- Кстати, сначала меня ввело в заблуждение ui16. Потому что эта аббревеатура означает unsigned int (а он 32-ух битный). В то время как usi16 было бы логичнее - unsigned short int Добавлено (12 Февраля 2019, 22:58) --------------------------------------------- Кстати, ui16 - это просто своего рода псевдоним типа данных. Мы сами можем задать свой псевдоним используя typedef:
Код typedef unsigned short int ui16; - как в твоём случае, например То есть typedef тип имя;
|
|
| |
allods | Дата: Вторник, 12 Февраля 2019, 23:03 | Сообщение # 1534 |
почти ветеран
Сейчас нет на сайте
| в моем случае получается UInt16 allowedFactions = r.ReadByte(); allowedFactions += (UInt16)(r.ReadByte() * 256); и получаю 511 посмотрел это в двоичной системе 111111111 это точно то что мне надо.
собственно для проверки я могу просто разобрать 111111111 в Лист и через цикл проверить 0 или 1 ? я правильно понял ? просто я не знаю как мне переписать
Код if(!(allowedFactions & (1 << fact))) { mapHeader->players[i].allowedFactions.erase(fact); }
players[i].allowedFactions.erase(fact); и еще что такое erase я посмотрел и насколько я понял оно убирает значение == fact ?
вообщем странно немного. С этим кодом что я написал в самом начале. Я получаю не в двоичной системе не 111111111 а 511 в итоге все остальне не работает. Так как я не вижу преобразования 511 в 111111111 В итоге если преобразовать в двоичую систему все сходится. Или я что то не понял
Сообщение отредактировал allods - Вторник, 12 Февраля 2019, 23:14 |
|
| |
DivES | Дата: Вторник, 12 Февраля 2019, 23:14 | Сообщение # 1535 |
заслуженный участник
Сейчас нет на сайте
| Цитата allods ( ) собственно для проверки я могу просто разобрать 111111111 в Лист и через цикл проверить 0 или 1 ? я правильно понял ? Разобрать конечно можно и проверить тоже, если это требуется. Но по идее, двоичный 0 он и в Африке - ноль (в десятичной системе, имеется в виду). То есть, 0 (в десятичной) = 0 (тут и далее - в двоичной) = 00 = 000 = 0000 =... То есть, проверка if (двоичное число) будет срабатывать только в том случае, когда в этом двоичном числе есть хотя бы одна единичка Добавлено (12 Февраля 2019, 23:23) ---------------------------------------------
Цитата allods ( ) players[i].allowedFactions.erase(fact); и еще что такое erase я посмотрел и насколько я понял оно убирает значение == fact ? По этому поводу ничего не скажу, не совсем понимаю, с чем мы работаем. Но судя по названию функции/ метода она и правда "стирает" значение.
Цитата allods ( ) вообщем странно немного. С этим кодом что я написал в самом начале. Я получаю не в двоичной системе не 111111111 а 511 в итоге все остальне не работает. Так как я не вижу преобразования 511 в 111111111 В итоге если преобразовать в двоичую систему все сходится. Или я что то не понял Преобразовывать не нужно, по идее. Раньше ведь всё работало?
|
|
| |
allods | Дата: Вторник, 12 Февраля 2019, 23:27 | Сообщение # 1536 |
почти ветеран
Сейчас нет на сайте
| Цитата DivES ( ) Разобрать конечно можно и проверить тоже, если это требуется. Но по идее, двоичный 0 он и в Африке - ноль (в десятичной системе, имеется в виду). То есть, 0 (в десятичной) = 0 (тут и далее - в двоичной) = 00 = 000 = 0000 =... То есть, проверка if (двоичное число) будет срабатывать только в том случае, когда в этом двоичном числе есть хотя бы одна единичка :)
Хорошо тогда я объясню задачу потому что я что то не уловил.
У меня есть список Замков их 9 в виде bool (либо есть на выбор либо нет) то есть у 1 игрока может быть 1,2,5,7 замок на выбор у другого 1,5,6,8,9 у третьего все 1,2,3,4,5,6,7,8,9 то есть все. они хранятся в таком виде 1 ,2,4,8,16,32,64,128,256 в битах в итоге у первого игрока 1+2+16+64 у второго 1+16+128+256 у третьего в итоге 511 то есть 111111111 то есть все замки true то есть если переделать тот код то можно не убирать 0 и в итоге проверять наличие замка на выбор чере 1 либо 0 не парясь с маской.
Тот код не мой и да он работает это точно . Мне нужно его понять и написать уже свое. Поэтому я и рассказываю тот как я понял и то как я бы сделал. Просто хочу понять правильно в итоге я понял тот код или нет. Конечно благодаря тому что вы мне рассказали про двоичный код и то как работает тот код я смог написать свой. И кстате в итоге то что я теперь уже написал сам работает. Просто немного по другому но в целом получается получить данные и правильно их растолковать!
------------- Точнее код не проверял но судя по двоичному allowedFactions если не стирать нули то все сходится.
Сообщение отредактировал allods - Вторник, 12 Февраля 2019, 23:39 |
|
| |
DivES | Дата: Вторник, 12 Февраля 2019, 23:39 | Сообщение # 1537 |
заслуженный участник
Сейчас нет на сайте
| allods, а как ты преобразовываешь тот код, что уже показывал? Я вот лично пока что не вижу реализации твоей идеи через тот код Добавлено (12 Февраля 2019, 23:40) ---------------------------------------------
Цитата allods ( ) если не стирать нули Где именно стирать?
|
|
| |
allods | Дата: Среда, 13 Февраля 2019, 00:03 | Сообщение # 1538 |
почти ветеран
Сейчас нет на сайте
| Цитата DivES ( ) allods, а как ты преобразовываешь тот код, что уже показывал? Я вот лично пока что не вижу реализации твоей идеи через тот код :(
собственно вот тот код под вопросом
Код for(int fact = 0; fact < totalFactions; ++fact) { if(!(allowedFactions & (1 << fact))) { mapHeader->players[i].allowedFactions.erase(fact); } totalFactions = количество всех замков allowedFactions = биты замков которые я считываю из файла. Всего есть 511 байтов = 111111111. К примеру 510 ровняется замки от 2-9 так как 511-510 = 1. А 1 байт это замок номер 1. то есть 011111111 я знаю что этого замка в списке уже нет. Если 255 то значит 511-255 = 256 а это последний замок. то значит 111111110. значит нет 9го замка.
То есть считав сколько байтов я уже благодаря преобразованию в двоичную систему знаю какие замки доступны.
Что касается той функици Мы смотрим все 1и0 в allowedFactions и если 0 то убираем замок под индексом fact из списка замков оставляя в списке только доступные. то есть в итоге если 110111101 то мы уберем замки под индексом 8 и 3 Благодаря вашим ответам я пришел к этому выводу. Это логично все сходится. Завтра закину вам еще + так как без вас я бы еще сидел щеки надувал
Сообщение отредактировал allods - Среда, 13 Февраля 2019, 00:08 |
|
| |
DivES | Дата: Среда, 13 Февраля 2019, 00:10 | Сообщение # 1539 |
заслуженный участник
Сейчас нет на сайте
| Цитата allods ( ) А 1 байт это замок номер 1. то есть 011111111 я знаю что этого замка в списке уже нет. Если 255 то значит 511-255 = 256 а это последний замок. то значит 111111110. В двоичной системе исчисления самый старший разряд - крайний левый (то есть в 0111 1111 самым старшим является 0, самым младшим - крайняя справа единица). Так что отсутствие замка под номером один (обозначаемого 1 битом) будет выглядеть как 111111110. Так же как и отсутствие десятого замка (256 бит) будет выглядеть как 011111111. Возможно, подтолкнёт на какие-либо мысли. Если, конечно, ещё есть неразрешённые вещи в этом твоём коде
Сообщение отредактировал DivES - Среда, 13 Февраля 2019, 00:13 |
|
| |
allods | Дата: Среда, 13 Февраля 2019, 00:27 | Сообщение # 1540 |
почти ветеран
Сейчас нет на сайте
| Цитата DivES ( ) В двоичной системе исчисления самый старший разряд - крайний левый (то есть в 0111 1111 самым старшим является 0, самым младшим - крайняя справа единица). Так что отсутствие замка под номером один (обозначаемого 1 битом) будет выглядеть как 111111110. Так же как и отсутствие десятого замка (256 бит) будет выглядеть как 011111111.
Да я это учел и просто инвертирую ну или читаю в другую сторону. Хотя я еще не написал код а в процессе. И если мне у меня получится правильно считать данные то вопросов не останется точно =) хотя возможно в дальнейшем будут еще в таком духе =).
Добавлено (13 Февраля 2019, 01:39) --------------------------------------------- В итоге вот мой аналог
Код for (int fact = 0; fact < totalFactions; fact++) { if ((allowedFactions % 2) != 0) this.allowedFactions.Add((Faction)fact); allowedFactions = allowedFactions / 2; }
Спасибо за разъяснения DivES и drcrack
Все работает
Сообщение отредактировал allods - Среда, 13 Февраля 2019, 01:50 |
|
| |
|