динамический массив указателей
int *p[10]; //создает массив указателей на int из 10 элементов.
А как забабахать тоже самое, но без заранее известного числа элементов?
int i = 10;
int *p;
Спасибо!
Приветствую!
int *p[10]; //создает массив указателей на int из 10 элементов.
А как забабахать тоже самое, но без заранее известного числа элементов?
int i = 10;
int *p;
Спасибо!
см. Help vector.
На случай если нет help:
vector<T, Allocator> is a type of sequence that supports random access iterators. In addition, it supports amortized constant time insert and erase operations at the end. Insert and erase in the middle take linear time. Storage management is handled automatically. In vector, iterator is a random access iterator referring to T. const_iterator is a constant random access iterator that returns a const T& when dereferenced. A constructor for iterator and const_iterator is guaranteed. size_type is an unsigned integral type. difference_type is a signed integral type.
Any type used for the template parameter T must provide the following (where T is the type, t is a value of T and u is a const value of T):
Copy constructors T(t) and T(u)
Destructor t.~T()
Address of &t and &u yielding T* and const T*
respectively
Assignment t = a where a is a
(possibly const) value of T
Special Case
Vectors of bit values, that is boolean 1/0 values, are handled as a special case by the standard library, so that they can be efficiently packed several elements to a word. The operations for a boolean vector, vector<bool>, are a superset of those for an ordinary vector, only the implementation is more efficient.
Two member functions are available to the boolean vector data type. One is flip(), which inverts all the bits of the vector. Boolean vectors also return as reference an internal value that also supports the flip() member function. The other vector<bool>-specific member function is a second form of the swap() function
Для небольших динамических массивов может подойти
и это:
int p=10;
int * Ptr=new int [x];
...
if(Ptr==234)ShowMessage("bla...bla..");
..
delete[] Ptr;
STL это хрошо, но не единственный способ.
Для небольших динамических массивов может подойти
и это:
int p=10;
int * Ptr=new int [x];
...
if(Ptr==234)ShowMessage("bla...bla..");
..
delete[] Ptr;
Вопрос а как добавить в динамический массив еще один элемент?
Вопрос а как добавить в динамический массив еще один элемент?
В условии задачи этого нет.
Но если очень надо , то можно
использовать либо методы STL, либо TList,
либо просто - самоадресуемые структуры...
Такие вещи нужно чтать в книжках, а не на форумах...
:)
Удачи.
Вопрос а как добавить в динамический массив еще один элемент?
Первое, что приходит на ум, это решение в лоб, т.е.
- создаем массив на единицу большего размера
- копируем в него исходный массив + добавляемый элемент
- удаляем исходный массив
На мой взгляд, этот метод пойдет для массивов стандартных типов.
Первое, что приходит на ум, это решение в лоб, т.е.
- создаем массив на единицу большего размера
- копируем в него исходный массив + добавляемый элемент
- удаляем исходный массив
На мой взгляд, этот метод пойдет для массивов стандартных типов.
При добавлении/удалении элементов лучше всё таки использовать списки. И какое значение имеет стандартный тип или нестандартный ?!
Оценить возможную частоту добавления элемента в массив.
На основании этих соображений выделить новый
массив не на 1 элемент больше , а например на 100
элементов больше.
Нужно добавить в прогр. 2 переменные:
- одна сообщает текущий предельный размер массива,
другая
- номер последнего занятого элемента.
Так мы круто сэкономим вычислительные ресурсы..:)
НО !
ПОСТЕПЕННО дорабатывая и оптимизируя код мы
просто заново напишем то, что уже слелано в
классах STL (и других...)
Хрошо иногда заглянуть в книжки типа
"Жемчужины программирования" и им подобные...
:)
P.S. Absolut - правильно говорит...
ЧИТАЕМ ЗДЕСЬ
И ЗДЕСЬ ИНТЕРЕСНО
При добавлении/удалении элементов лучше всё таки использовать списки.
Вы считаете, что заменить массив int`а (либо указателей на int) списком рационально?!?
И какое значение имеет стандартный тип или нестандартный ?!
Вопрос не понял! Что значит какое значение?! Любой тип может принимать любое значение из своего диапазона значений.
Хрошо иногда заглянуть в книжки типа
"Жемчужины программирования" и им подобные...
:)
P.S. Absolut - правильно говорит...
ЧИТАЕМ ЗДЕСЬ
И ЗДЕСЬ ИНТЕРЕСНО
дайте еще :)!!!
Вы считаете, что заменить массив int`а (либо указателей на int) списком рационально?!?
Если размер этого массива подвергается частым изменениям - то да. Причём это будет самое рациональное ;-) Надеюсь ;-)
Вопрос не понял! Что значит какое значение?! Любой тип может принимать любое значение из своего диапазона значений.
Заучились совсем, технари ;-) Значение, в смысле "разница", какая разница стандартный ли это тип или нестандартный.
POD или не POD вот в чем вопрос... хех) Я слушал про вектора, у меня в книге по Си о них написано, просто думал что может как-то можно про динамические масива. Ладно спасибо.
почитай ещё очереди, векторы и т.п.
они экономичнее, чем массивы... ну пользоваться конечно менее удобно - адресация элементов через "итераторы"
ну пользоваться конечно менее удобно - адресация элементов через "итераторы"
Это у векторов то?
Это у векторов то?
гы! я вообщем-то был уверен, потому что сам только что прогу закончил... но для верности всё же посмотрел в умной книжке, не перепутал ли название....
гы! я вообщем-то был уверен, потому что сам только что прогу закончил... но для верности всё же посмотрел в умной книжке, не перепутал ли название....
Название чего? Вектора, итератора?
Ну и что говорит книжка? Что к элементу вектора можно обратится лишь разыменованием итератора?
Ну а как же разындексирование?
std::vector<int> v(10);
v[0] = 1;
v[1] = 2;
int i = v[1];
Название чего? Вектора, итератора?
Ну и что говорит книжка? Что к элементу вектора можно обратится лишь разыменованием итератора?
Ну а как же разындексирование?
std::vector<int> v(10);
v[0] = 1;
v[1] = 2;
int i = v[1];
у тебя этот код работает?
у тебя этот код работает?
... да и вообще речь шла о векторах как таковых
у тебя этот код работает?
У меня вполне.
у тебя этот код работает?
Работает, чего б ему не работать? :D
... да и вообще речь шла о векторах как таковых
Аналитическая геометрия?
Вектор - отрезок, имеющий направление и точку приложения.
А в STL вектор один - std::vector
Работает, чего б ему не работать? :D
Аналитическая геометрия?
Вектор - отрезок, имеющий направление и точку приложения.
А в STL вектор один - std::vector
ну не знаю... можно конечно работать и со смещениями, но у меня к примеру вектор содержал структуры и адресовал я их через итераторы и foreach ... проблем не было, даже когда я изменил размер стуктуры
ну не знаю... можно конечно работать и со смещениями, но у меня к примеру вектор содержал структуры и адресовал я их через итераторы и foreach ... проблем не было, даже когда я изменил размер стуктуры
Уважаемый, учите С++, тогда не надо будет огород городить.
Это не смещение, а оператор разындексирования.
А при чем тут размер структуры?
Уважаемый, учите С++, тогда не надо будет огород городить.
Это не смещение, а оператор разындексирования.
А при чем тут размер структуры?
почему бы тебе, уважаемый самому не прочесть для разнообразия П.Киммел Borland C++5
там всё доступно написано... для тех кто умеет читать и не считает что знает ВСЁ
Уважаемый, учите С++, тогда не надо будет огород городить.
Это не смещение, а оператор разындексирования.
А при чем тут размер структуры?
а ещё, драгоценнейший, для разнообразия подчитай АССЕМБЛЕР, чтобы лучче понимать процессы, происходящие в памяти компа, потому что твоё "разындексирование" это и есть СМЕЩЕНИЕ-таки относительно начального адреса вектора на количество*РАЗМЕР_элемента_вектора. (к массивам тоже относится)
а ещё, драгоценнейший, для разнообразия подчитай АССЕМБЛЕР, чтобы лучче понимать процессы, происходящие в памяти компа, потому что твоё "разындексирование" это и есть СМЕЩЕНИЕ-таки относительно начального адреса вектора на количество*РАЗМЕР_элемента_вектора. (к массивам тоже относится)
"Спокойствие, только спокойствие", (с)Карлсон, который живет на крыше.
Не возражаешь, если я буду приводить ссылки не на каких-то там П.Киммел, а на стандарт языка С++ ?
Операция разындексирования - в общем случае не есть "СМЕЩЕНИЕ-таки относительно начального адреса", а может быть определена как угодно.
Смотрим стандарт: http://www.csci.csusb.edu/dick/c++std/cd2/over.html#over.sub
Конкретно в векторе (std::vrctor) и очереди с произвольным доступом (std::deque) разындексирование описывается как
*(a.begin() + n)
Смотрим стандарт (пункт 9): http://www.csci.csusb.edu/dick/c++std/cd2/lib-containers.html#lib.sequence.reqmts
Что же касается ассемблера, то если уж ты пишешь на ЯВУ, то не стоит затачиваться на ассемблер, т.к. и реализация STL меняется и разные компиляторы по-разному компилируют один и тот же код, я уж не говорю об оптимизаторах. А вот интерфейс в общем случае остается неизменным и придерживается (кто как может) стандарта.
Операция разындексирования - в общем случае не есть "СМЕЩЕНИЕ-таки относительно начального адреса", а может быть определена как угодно.
Смотрим стандарт: http://www.csci.csusb.edu/dick/c++std/cd2/over.html#over.sub
Конкретно в векторе (std::vrctor) и очереди с произвольным доступом (std::deque) разындексирование описывается как
*(a.begin() + n)
вот ты и описАл ТО САМОЕ СМЕЩЕНИЕ (+n) которое...
Что же касается ассемблера, то если уж ты пишешь на ЯВУ, то не стоит затачиваться на ассемблер, т.к. и реализация STL меняется и разные компиляторы по-разному компилируют один и тот же код, я уж не говорю об оптимизаторах. А вот интерфейс в общем случае остается неизменным и придерживается (кто как может) стандарта.
просто низкоуровневое програмирование помогает не заморачиваться с семантикой... даже если как-то неправильно что-то назвал, всё равно по сути знаешь, что делаешь... в конечном итоге всё переваривается в мышинный код :)
вот ты и описАл ТО САМОЕ СМЕЩЕНИЕ (+n) которое...
Ничего подобного.
*(a.begin() + n)
a.begin() - это не "начальный адрес вектора", а итератор, установленный в начало контейнера;
+n - это не смещение в адресном пространстве, а приращение итератора;
* - это не взятие значения по адресу, а оператор operator* итератора.
Поэтому внутри все значительно сложнее, а вот снаружи все просто - a[n]
просто низкоуровневое програмирование помогает не заморачиваться с семантикой... даже если как-то неправильно что-то назвал, всё равно по сути знаешь, что делаешь... в конечном итоге всё переваривается в мышинный код :)
Для ООП - это несколько неверный подход, т.к. что и как будет реализовано компилятором не всегда представляется возможным. Кроме того, не все превращается в машинный код, некоторое же превращается не на прямую, а по средством довольно таки сложных преобразовний. В данном случае я говорю о шаблонах (template).
Ничего подобного.
*(a.begin() + n)
a.begin() - это не "начальный адрес вектора", а итератор, установленный в начало контейнера;
+n - это не смещение в адресном пространстве, а приращение итератора;
* - это не взятие значения по адресу, а оператор operator* итератора.
Поэтому внутри все значительно сложнее, а вот снаружи все просто - a[n]
я постоянно пытаюсь подтолкнуть тебя к РЕЗУЛЬТАТУ. Вот ты всё это ПРАВИЛЬНО расписал... ну а КАКОВА ЦЕЛЬ? Что получишь в результате выполнения сей команды?
Как говорил Козьма Прутков "Зри в корень!" :)
Для ООП - это несколько неверный подход, т.к. что и как будет реализовано компилятором не всегда представляется возможным. Кроме того, не все превращается в машинный код, некоторое же превращается не на прямую, а по средством довольно таки сложных преобразовний. В данном случае я говорю о шаблонах (template).
всё равно РЕЗУЛЬТАТ! ты можешь ходить сколь угодно долго кругами, процессору в конечном итоге нужны понятные ему команды.
да Бог с ним... и так загадили человеку тему... :)
Я сам боле менее знаю ассемблер и Си++
И такая тема, каким образом в машинных кодах(да и не обязательно, хотя бы уж в асемблерном виде)
Вот, каким образом в ассемблерном виде могут, предстать ШАБЛОНЫ....
просто понять не могу(((
С остальным вроде все ясно...
я постоянно пытаюсь подтолкнуть тебя к РЕЗУЛЬТАТУ. Вот ты всё это ПРАВИЛЬНО расписал... ну а КАКОВА ЦЕЛЬ? Что получишь в результате выполнения сей команды?
Как говорил Козьма Прутков "Зри в корень!" :)
всё равно РЕЗУЛЬТАТ! ты можешь ходить сколь угодно долго кругами, процессору в конечном итоге нужны понятные ему команды.
Программный код на языках программирования пишутся для людей, а не для машины. Поэтому код должен быть максимально простым для понимания.
Теперь давай сравним, что легче для понимания:
{
type val = *it;
// do something
}
или
{
type val = v[ i];
// do something
}
да Бог с ним... и так загадили человеку тему... :)
Да ну брось... Пока никто не ругается, будем флеймить.
Вот, каким образом в ассемблерном виде могут, предстать ШАБЛОНЫ....
просто понять не могу(((
Шаблоны сначала инстанируются конкретными параметрами, а потом уже компилируются в машинный код.
Это приводит к тому, что некоторые манипуляции с шаблонами вообще не попадают в объектный файл, но при этом могут выполнять довольно сложные действия ещё на этапе компиляции. И здесь уж ассемблер никак не поможет, надо знать язык в его стандарте и в тонкостях реализации конкретным компилятором.
С остальным вроде все ясно...
Счастливый человек... :D
Счастливый человек... :D
Ну вроде как я понимаю работоспособность всех других фичей, иных которые не понимаю не встречал...