Нубский ворпос.
| |
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 тыс. элементов на таком векторе "уложит" любой современный процессор Вектор, собссна, это обычный динамический массив со встроенным Pool'ом :). Т.е. ты в начале выделяешь определенный кусок памяти, скажем 4К. Используя malloc, например. Далее занимаешься удалением\добавлением, и проверяешь не превысили ли элементы твой Пул, если да, то вызываешь realloc, и выделяешь в два раза больше памяти, 8К. При этом все старые элементы скопируются в новую область памяти (если потребуется). И можно дальше продолжать добавлять элементы :). Память будет выделяться очень редко. Как-то так, если в кратце Добавлено (01.02.2011, 16:13) ---------------------------------------------
Quote (Matou) а для этого лучше использовать классы, а не структуры, ну и в последних, но не в последнюю очередь, не зачем изобретать велосипед, все это уже реализовано в STL Кстати, чем то класс от структуры отличается? Аргументы про "велосипед" никогда не понимал. Т.е. использовать "черный ящик" всегда это хорошо? Работает, да и ладно. А если потребуется дописать чуток? Модифицированный stl vector весьма частая практика. Да и вообще, человек учится, а не занимается разработкой коммерческого АА проекта в сильно ужатые сроки. Имхо.
C++ - он особенный. С помощью него можно не только выстрелить себе в ногу, но и повеситься в пустой комнате:)
Сообщение отредактировал Archido - Вторник, 01 Февраля 2011, 16:05 |
|
| |
Kornival | Дата: Вторник, 01 Февраля 2011, 19:04 | Сообщение # 64 |
The Witcher
Сейчас нет на сайте
| Что такое пул?
|
|
| |
Archido | Дата: Вторник, 01 Февраля 2011, 20:23 | Сообщение # 65 |
Сэнсэй
Сейчас нет на сайте
| Kornival, ну Бассейн, вестимо А если серьезно), то я смысл его примерно описал в прошлом посте. Ща подробнее опишу. Вообще, сущность "динамического массива" весьма абстрактна, все без исключения оперируют блоками памяти. Так вот, собственно, "идея": Выделять не фиксированный конкретный размер под примерное количество элементов, а в разы больше (можно специально в N раз больше, чем кол-во элементов, либо кратное страницы памяти 4K, etc). И работать с ними, пока весь "блок" не закончится. Это как бе и есть пул. А далее просто выделяется другой блок в памяти, в два раза больше чем предыдущий. Половину нового блока займет старый (все скопируется), а остальная половина пойдет под свои нужды и так до бесконечности . Вот это все и имется в виду под сущностью "динамический массив", аля чуть навороченный "вектор". Таким образом ОЧЕНЬ сильно повышается быстродействие, нужно правда, удачно подбирать размер пула под конкретный случай (чтобы выжать весь максимум =), но это не обязательно), т.к. редко дергаются ф-ции выделения памяти, которые в свою очередь довольно "тяжелые".
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) Ну все, ясно, спасибо. Только в моем случае память нужно было выделять максимум для пары десятков объектов. Так и выделял бы сразу два десятка . Точно также можно выделить пул в два десятка, и если вдруг все таки окажется больше, то не будет никаких проблем, иначе AV. Но я как понял оно тебе тут не надо =) zodiak Чорт, я нуп, пошел читать Страуструпа... Хотя честно, не знал. Но вообще пакостный способ, два десятка разнообразных полей и жизнь хороша (не дай бог в случае рефакторинга кто-то чуток(или "случайно") перепутает пару членов структуры ). Так как-то православнее, имхо: 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' Если поменять на ошибок нет.Добавлено (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++ а потом уже задавать глупые вопросы, если они будут... Причем здесь основы С++? Я же сказал, дело было в настройках компилятора
|
|
| |
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 |
|
| |
|