Пятница, 19 Апреля 2024, 20:01

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

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 4 из 5
  • «
  • 1
  • 2
  • 3
  • 4
  • 5
  • »
Форум игроделов » Программирование » C/C++ » Нубский ворпос. (Помогите пожалуйста.)
Нубский ворпос.
KornivalДата: Пятница, 14 Января 2011, 20:40 | Сообщение # 61
The Witcher
Сейчас нет на сайте
Да я уже разобрался, буду пользоваться связанными списками. Спасибо всем.

Сообщение отредактировал Kornival - Пятница, 14 Января 2011, 20:42
shnaketДата: Вторник, 01 Февраля 2011, 14:55 | Сообщение # 62
частый гость
Сейчас нет на сайте
В общем, не стал заводить новую тему, спрошу в этой. Допустим, есть структура. Она объявлена в хэдере. А как заполнить её поля в .cpp-файле, не создавая отдельных функций?

ArchidoДата: Вторник, 01 Февраля 2011, 16:13 | Сообщение # 63
Сэнсэй
Сейчас нет на сайте
Quote (shnaket)
В общем, не стал заводить новую тему, спрошу в этой. Допустим, есть структура. Она объявлена в хэдере. А как заполнить её поля в .cpp-файле, не создавая отдельных функций?

Никак. Нужен как минимум конструктор.

Quote (Kornival)
Тогда допустим я не знаю сколько мне понадобится памяти, как можно постоянно динамически выделять память и как к ней потом обращаться. Нужно сделать что-то вроде vector`a. Ну в общем как выделять память понятно, но как сделать "итератор"?

Так, наверное, это все уже давно не актуально, но я все таки кое что скажу =). Вероятно, я слишком бегло прочитал тему и не до конца понял мысль, но меня смущают несколько моментов.

Если все таки нужен аля "вектор", то зачем юзать связные списки? Их правильно (т.е. удобно и эффективно) юзать, когда выполняется большинство из данных критериев:
- очень частое добавление\удаление элементов, при чем не пропорциональное (скажем добавляется в два раза больше, чем удаляется. Иначе гораздо эффективнее вырулит "обычный дин. массив". Либо частые добавления\удаления в середине).

- требуется "обходить" все элементы последовательно вообще или частично, пока не будет найден какой-то определенный элемент. Никаких "обращений по индексам", иначе большущий fail.
В случае двусвязного списка, на хранение элемента требуется +8 байт (х86), жирновато. На односвязный +4, пережить можно. Но если потребуется обратиться (как угодно) к предпоследнему элементу скажем, придеться "пройти" весь список :D.

Также существует очень большая вероятность не попасть в кэш, т.к. память на элемент будет выделяться хаотично, никакой последовательности. К тому же дергать new\delete на каждый "push\pop" не очень красивая затея, потребуется как минимум некоторый Pool. Иначе fail.
Вообщем я хотел сказать, что для "вектора" списки сильно не подходят, медленно. QSort из > 10 тыс. элементов на таком векторе "уложит" любой современный процессор biggrin

Вектор, собссна, это обычный динамический массив со встроенным Pool'ом :).
Т.е. ты в начале выделяешь определенный кусок памяти, скажем 4К. Используя malloc, например.
Далее занимаешься удалением\добавлением, и проверяешь не превысили ли элементы твой Пул, если да, то вызываешь realloc, и выделяешь в два раза больше памяти, 8К.
При этом все старые элементы скопируются в новую область памяти (если потребуется). И можно дальше продолжать добавлять элементы :). Память будет выделяться очень редко.
Как-то так, если в кратце cool

Добавлено (01.02.2011, 16:13)
---------------------------------------------

Quote (Matou)
а для этого лучше использовать классы, а не структуры, ну и в последних, но не в последнюю очередь, не зачем изобретать велосипед, все это уже реализовано в STL

Кстати, чем то класс от структуры отличается? biggrin
Аргументы про "велосипед" никогда не понимал. Т.е. использовать "черный ящик" всегда это хорошо? Работает, да и ладно.
А если потребуется дописать чуток? Модифицированный stl vector весьма частая практика.
Да и вообще, человек учится, а не занимается разработкой коммерческого АА проекта в сильно ужатые сроки. Имхо.


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

Сообщение отредактировал Archido - Вторник, 01 Февраля 2011, 16:05
KornivalДата: Вторник, 01 Февраля 2011, 19:04 | Сообщение # 64
The Witcher
Сейчас нет на сайте
Что такое пул?
ArchidoДата: Вторник, 01 Февраля 2011, 20:23 | Сообщение # 65
Сэнсэй
Сейчас нет на сайте
Kornival, ну Бассейн, вестимо biggrin

А если серьезно), то я смысл его примерно описал в прошлом посте. Ща подробнее опишу.
Вообще, сущность "динамического массива" весьма абстрактна, все без исключения оперируют блоками памяти.
Так вот, собственно, "идея": Выделять не фиксированный конкретный размер под примерное количество элементов, а в разы больше (можно специально в N раз больше, чем кол-во элементов, либо кратное страницы памяти 4K, etc). И работать с ними, пока весь "блок" не закончится. Это как бе и есть пул.

А далее просто выделяется другой блок в памяти, в два раза больше чем предыдущий. Половину нового блока займет старый (все скопируется), а остальная половина пойдет под свои нужды smile и так до бесконечности biggrin . Вот это все и имется в виду под сущностью "динамический массив", аля чуть навороченный "вектор".

Таким образом ОЧЕНЬ сильно повышается быстродействие, нужно правда, удачно подбирать размер пула под конкретный случай (чтобы выжать весь максимум =), но это не обязательно), т.к. редко дергаются ф-ции выделения памяти, которые в свою очередь довольно "тяжелые".


C++ - он особенный. С помощью него можно не только выстрелить себе в ногу, но и повеситься в пустой комнате:)
KornivalДата: Вторник, 01 Февраля 2011, 20:32 | Сообщение # 66
The Witcher
Сейчас нет на сайте
Ну все, ясно, спасибо. Только в моем случае память нужно было выделять максимум для пары десятков объектов.
zodiakДата: Вторник, 01 Февраля 2011, 23:01 | Сообщение # 67
постоянный участник
Сейчас нет на сайте
shnaket,
Quote
Допустим, есть структура. Она объявлена в хэдере. А как заполнить её поля в .cpp-файле, не создавая отдельных функций?

Archido,

Quote
Никак. Нужен как минимум конструктор.

Не нужен конструктор.

Code

struct test
{
    int a;  
    int b;
    char c;
    float f;
};

test t = {1,2,'a',4.6f}; // заполнение структуры при объявлении

Поля заполняются в порядке объявления.
Читайте Страуструпа.


Точка зору окремо взятого індивіда завжди суб'єктивна!

Взломщик
Battle City.Net
SlavecДата: Вторник, 01 Февраля 2011, 23:12 | Сообщение # 68
GameDev - площадка для творчества
Сейчас нет на сайте
Обращаюсь за помощью.
Изучал классы в C++ и посмотрел упражнения. Там упражнение по созданию банковского счета, где надо снимать и класть деньги.
(debit, credit, getBalance) - функции.
Написал ерунду, нечто похожее, но с ошибками. Помогите доработать, очень хочу понять принцип работы классов.

Code
#include <iostream>
#include <string>
using namespace std;
int vibor,balance=0;
class Account
{
public:
  void debit()
  {
   int debit;
   cout <<"Введите сумму, которую вы хотите положить на счет";
   cin  >>debit;
   balance=balance+debit;
  };
  void credit()
  {
   int credit;
   cout <<"Введите сумму, которую вы хотите снять со счета";
   cin  >>credit;
   if (credit<balance)
   {
    cout<<"Запрашиваемая сумма превышает баланс счета";
   }
   balance=balance-credit;
  }
};
int main()
{
Account myAccout;
int vibor;
cout<<"Выберите операцию\n";
cout<<"(1)Положить деньги на счет\n";
cout<<"(2)Снять деньги со счета\n";
cin >>vibor;
if (vibor=1)
{
  myAccout.debit();
}
if (vibor=2)
{
  myAccout.credit();
}
system("Pause");
return 0;
}
ArchidoДата: Среда, 02 Февраля 2011, 00:02 | Сообщение # 69
Сэнсэй
Сейчас нет на сайте
Quote (Kornival)
Ну все, ясно, спасибо. Только в моем случае память нужно было выделять максимум для пары десятков объектов.

Так и выделял бы сразу два десятка smile . Точно также можно выделить пул в два десятка, и если вдруг все таки окажется больше, то не будет никаких проблем, иначе AV. Но я как понял оно тебе тут не надо =)

zodiak
Чорт, я нуп, пошел читать Страуструпа... biggrin
Хотя честно, не знал. Но вообще пакостный способ, два десятка разнообразных полей и жизнь хороша (не дай бог в случае рефакторинга кто-то чуток(или "случайно") перепутает пару членов структуры smile ).

Так как-то православнее, имхо:

Code

struct Test {
      int fX;
      char* fY;

      Test(int X, char* Y): fX(X), fY(Y) {}
};

Test Var(15, "cool");

В случае "косяков" компилятор сразу даст знать.

Slavec
Переменную "balance" можно внести под класс.
"vibor=1" это fail, хотя ошибка у начинающих популярная.
В языках Си равенство проверяется оператором "==", а просто "=" это присваивание.

Code

#include <iostream>
#include <string>

using namespace std;

class Account {
private:

int balance; //переменная в классе, в Private секции (извне к ней никто не сможет обратиться)

public:

Account() {
balance = 0; //инициализируем ее
}

void debit() {
int debit;
cout << "Введите сумму, которую вы хотите положить на счет";
cin >> debit;
balance = balance + debit;
};

void credit() {
int credit;
cout << "Введите сумму, которую вы хотите снять со счета";
cin >> credit;

if (credit < balance) {
cout << "Запрашиваемая сумма превышает баланс счета";
}
balance = balance-credit;
}
};

int main() {
Account myAccout;
int vibor;

cout << "Выберите операцию\n";
cout << "(1)Положить деньги на счет\n";
cout << "(2)Снять деньги со счета\n";

cin >> vibor;

if (vibor == 1) myAccout.debit(); // ==
if (vibor == 2) myAccout.credit();

system("Pause");
return 0;
}


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

Сообщение отредактировал Archido - Среда, 02 Февраля 2011, 00:04
BOOMДата: Среда, 02 Февраля 2011, 10:15 | Сообщение # 70
I am the creator of ADE
Сейчас нет на сайте
Я тут почитал, и немного не понял. Проблема в чём: в скорости при выполнении инициализации памяти под объект, или "я не могу понять, как это действует", как то так?
В общем, на вторую часть, Archido, ответил, раскладывая всё по полочкам.
А первая часть - используй пакетное выделение памяти. Ну, выделяешь десять ячеек памяти под десять объектов, в случае, если пишется одиннадцатый объект, создаётся ещё десять, и так далее. Ускоряется код от 10, до 60%, чем выделять для каждой записи отдельную ячейку памяти. Отдельно замечу недостаток: обычно, такая система потребует на от 5, до 20% больше памяти, в зависимости от реализации.


______________________________
Я вернулся, и это чудо.
______________________________
SlavecДата: Среда, 02 Февраля 2011, 10:33 | Сообщение # 71
GameDev - площадка для творчества
Сейчас нет на сайте
Archido
Теперь понятно) дело в том, что в задании требуется еще и выводить баланс с помощью getBalance функции. А программа между тем завершается.
И последний вопрос. Допустим, мы положили деньги на счет. Как вернуться и снова это сделать? В обратное меню.
Было например денег 0, положили 2000, вышли и положили еще 2000. Стало 4000.
ArchidoДата: Среда, 02 Февраля 2011, 10:53 | Сообщение # 72
Сэнсэй
Сейчас нет на сайте
Slavec
Ну тут все довольно просто, пробуй больше смотреть простых примеров и разбираться, хорошо помогает.

Для "вывода баланса" нужно добавить в класс простую фукнцию, а в меню "определить" бесконечный цикл, примерно так:

Code

class Account {  
private:  

int balance;

  ...

   int getBalance() const {
      return balance;
   }
}

...

int main() {  
Account myAccout;  
int vibor;  

while (true) { //бесконечный цикл, наше меню

    cout << "Выберите операцию\n";  
    cout << "(1)Положить деньги на счет\n";  
    cout << "(2)Снять деньги со счета\n";  
    cout << "(3)Вывести баланс\n";  
    cout << "(4)Выйти...\n";  

    cin >> vibor;  

    if (vibor == 1) myAccout.debit(); // ==  
    if (vibor == 2) myAccout.credit();  
    if (vibor == 3) cout << "Баланс: " << myAccout.getBalance() << "\n\n"; \\Выводим баланс

    if (vibor == 4) break; //прерываем цикл и выходим из меню

    system("Pause");  
}

return 0;  
}

В ф-ции 'getBalance()' используется модификатор const, что в данном случае означает, что ф-ция не изменяет поля нашего класса (в данном случае 'balance'), а просто читает его содержимое. Это делать не обязательно, но это как минимум хороший тон, которому стоит придерживаться.

Еще тут можно заменить кучи операторов 'if' на switch/case, опять таки не обязательно, просто код станет чуть удобнее и читабельнее.


C++ - он особенный. С помощью него можно не только выстрелить себе в ногу, но и повеситься в пустой комнате:)
SlavecДата: Среда, 02 Февраля 2011, 13:50 | Сообщение # 73
GameDev - площадка для творчества
Сейчас нет на сайте
Archido Большое спасибо.
----------------------------------------
Очень сильно помогли) буду изучать язык. Кстати, не стал мучиться с функцией returnBalance. Я сделал вывод суммы просто с помощью cout


Сообщение отредактировал Slavec - Среда, 02 Февраля 2011, 22:40
KornivalДата: Среда, 02 Февраля 2011, 16:07 | Сообщение # 74
The Witcher
Сейчас нет на сайте
Так, кажется я начал сходить с ума. Теперь у меня компилятор орет об ошибке на следующей строчке:
Code

float Variable = 0.1;

Вот что говорит:
Code

1>.\Source\Main.cpp(30) : error C2220: warning treated as error - no 'object' file generated
1>.\Source\Main.cpp(30) : warning C4305: 'initializing' : truncation from 'double' to 'float'

Если поменять на
Code

float Variable = 0;

ошибок нет.

Добавлено (02.02.2011, 16:07)
---------------------------------------------
Все, сорри. Оказалось проблема в настройках проекта.

XakepДата: Среда, 02 Февраля 2011, 16:55 | Сообщение # 75
めちゃくちゃちゃ
Сейчас нет на сайте
2Kornival, советую прочитать основы C/C++ а потом уже задавать глупые вопросы, если они будут...

Сообщение отредактировал Xakep - Среда, 02 Февраля 2011, 16:57
KornivalДата: Среда, 02 Февраля 2011, 17:39 | Сообщение # 76
The Witcher
Сейчас нет на сайте
Quote (Xakep)
2Kornival, советую прочитать основы C/C++ а потом уже задавать глупые вопросы, если они будут...

Причем здесь основы С++? Я же сказал, дело было в настройках компилятора dry
XakepДата: Среда, 02 Февраля 2011, 18:54 | Сообщение # 77
めちゃくちゃちゃ
Сейчас нет на сайте
просто прочитал все сообщения в теме, вот и говорю, было бы полезно выучить основы
shnaketДата: Четверг, 10 Февраля 2011, 13:35 | Сообщение # 78
частый гость
Сейчас нет на сайте
Подскажите пожалуйста, как называется стиль кнопки, используемый в Windows XP SP3?

ezhickovichДата: Четверг, 10 Февраля 2011, 14:03 | Сообщение # 79
[Великий и могучий хозяинъ]
Сейчас нет на сайте
Quote (shnaket)
Подскажите пожалуйста, как называется стиль кнопки, используемый в Windows XP SP3?

Нуууу... Очень информативно...
WinAPI/WinForms/Wx/Qt/GTK or What???



Я: О великий повелитель этой ничтожной вселенной - сокращённо ЁЖ!
shnaketДата: Четверг, 10 Февраля 2011, 14:15 | Сообщение # 80
частый гость
Сейчас нет на сайте
WinAPI.
сосбственно говоря, вот в чем проблема:

Как первой дать стиль второй.




Сообщение отредактировал shnaket - Четверг, 10 Февраля 2011, 14:21
Форум игроделов » Программирование » C/C++ » Нубский ворпос. (Помогите пожалуйста.)
  • Страница 4 из 5
  • «
  • 1
  • 2
  • 3
  • 4
  • 5
  • »
Поиск:

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