man2D Опубликовано 7 ноября, 2003 Жалоба Поделиться Опубликовано 7 ноября, 2003 Народ, подскажите пожалуйста, зачем нужны указатели! Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Тролль Опубликовано 7 ноября, 2003 Жалоба Поделиться Опубликовано 7 ноября, 2003 Указатель - это объект, в котором хранится адрес чего-то. У этого объекта есть некоторые свойства, например, он помнит размер блока памяти, адрес которого он хранит. Он знает и другие вещи, например, можно ли изменять содержимое блока памяти, на который он ссылается. Указатель часто используется для работы с массивами, так как к содержимому указателя надо прибавить смещение, чтобы получить адрес нужного элемента массива. Но очень полезен, как посредник, и для работы с другими объектами. Пример использования указателя для работы с динамическим массивом: Создаем указатель на блок памяти, предназначенный для хранения целого, выделяем память для хранения 50-ти целых и помещаем адрес начала этого блока памяти в указатель: int *p; p=new int[50]; Теперь с этим массивом можно работать: p[2]=8; или, что то же самое, *(p+2)=8 (тут мы прибавили к указателю два размера блоков памяти, соответствующих типу указателя, взяли ячейку с этим адресом (операция *) и поместили нее 8 ). Когда этот массив больше не нужен, память можно освободить: delete [] p; Можно создавать и массивы указателей, в том числе динамические, и т.д. Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Ray Опубликовано 8 ноября, 2003 Жалоба Поделиться Опубликовано 8 ноября, 2003 Кстати, об указателях, а точнее о массивах в С++ Знаю один прикол, не имеющий, правда практического прменения... К ячейке массива мы обращаемся обычно как например p[10]==3 Если написать 10[p]==3 то это тоже будет работать! Связано это то ли с предпроцессором С++ то ли с компиляцией, написание p[10] преобразуется в форму p+10, и поэтому 10[p] будет выглядеть как 10+p то есть тоже верно... Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Smagl Опубликовано 8 ноября, 2003 Жалоба Поделиться Опубликовано 8 ноября, 2003 Маленькие дополнения. 1. При использовании указателей снимается ограничении на размер массива. Можно задать массив хоть из 10 млрд. элементов. Обычным способом так сделать нельзя. 2. Обращение по адресу работает быстрее, чем просто обращение к элементу массива. Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
man2D Опубликовано 9 ноября, 2003 Автор Жалоба Поделиться Опубликовано 9 ноября, 2003 А как создать массив с размерами, которые задаёт юзер? Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Ray Опубликовано 9 ноября, 2003 Жалоба Поделиться Опубликовано 9 ноября, 2003 Тебе Тролль все прекрасно написал... Создаем указатель на блок памяти, предназначенный для хранения целого, выделяем память для хранения 50-ти целых и помещаем адрес начала этого блока памяти в указатель: int *p; p=new int[50]; На тебе прмерный кусок программы: int size=0; cout << "Enter size of array: "; cin >> size; int *p = new int; for (int i=0;i<size;i++) { p=i+1; cout << p << ' '; } delete [] p; Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
man2D Опубликовано 9 ноября, 2003 Автор Жалоба Поделиться Опубликовано 9 ноября, 2003 Огромное спасибо. Наверное, это книжка тупая попалась... Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Smagl Опубликовано 9 ноября, 2003 Жалоба Поделиться Опубликовано 9 ноября, 2003 Огромное спасибо. Наверное, это книжка тупая попалась... Да, мало хороших книг Вот человек - хорошая книга ;) А форум - целая библиотека хороших книг :D Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
man2D Опубликовано 10 ноября, 2003 Автор Жалоба Поделиться Опубликовано 10 ноября, 2003 Smagl Ну да, а есть ведь ещё чаты, аськи и т.п. Так что интернетом можно назвать бесконечное множество книг Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Alex1010 Опубликовано 29 декабря, 2003 Жалоба Поделиться Опубликовано 29 декабря, 2003 А как создать массив с размерами, которые задаёт юзер? Для этого существуют структуры данных, именуемые связанными списками. Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Тролль Опубликовано 29 декабря, 2003 Жалоба Поделиться Опубликовано 29 декабря, 2003 Alex1010 Массив и связанный список - разные вещи. В массиве ты получаешь нужный элемент сразу вычислением его положения с помощью индекса, а в связанном списке ты должен пробежаться по всей цепочке элементов, чтобы добраться до нужного. Зато внутрь списка легко включать элементы, как и исключать их из списка, а раздвинуть массив далеко не так легко. Можно моделировать массив связанным списком или связанный список массивом, но в любом из этих случае это будет очень нерационально. Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Alex1010 Опубликовано 29 декабря, 2003 Жалоба Поделиться Опубликовано 29 декабря, 2003 Совершенно верно! А на вопрос "А как создать массив с размерами, которые задаёт юзер? " Вы как ответите? Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Тролль Опубликовано 30 декабря, 2003 Жалоба Поделиться Опубликовано 30 декабря, 2003 Alex1010 Сошлюсь на программу, которую написал Ray и поместил в этой же теме несколькими сообщениями выше, она прекрасно показывает создание такого массива на работающем примере. Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Архимаг Опубликовано 28 сентября, 2009 Жалоба Поделиться Опубликовано 28 сентября, 2009 Возник вопрос касательно указателя и выделения памяти динамически: Известно, что в результате неправильного манипулирования паматью можно получить ее утечку. К примеру: int *p = new int;*p=10;p=new int;*p=15; В чем проблема приведенного кода ? В строке 1 выделяется память для значения int. В строке два, в эту область записывается значение 10. Далее указателю присваивается адрес другой области, в которую записывается число 15. Таким образом, первый участок памяти с числом 10, оказался недоступен. И нельзя ни использовать ни освободить его... Пример взят из Либерти... Идя дальше по книге, наткнулся на такую программу. class Mammal{ public: Mammal():itsAge(1) {cout << "Mammal constructor...\n";} virtual ~Mammal() {cout << "Mammal destructor...\n";} virtual void Speak () const {cout << "Mammal speak!\n";} protected: int itsAge;};class Dog: public Mammal{ public: void Speak()const {cout << "Woof!\n";}};class Cat: public Mammal{ public: void Speak()const {cout << "Meow!\n";}};class Horse: public Mammal{public: void Speak() const {cout << "Winnie!\n";}};int main(){Mammal *theArray[3];Mammal *ptr;int choice, i;for(i=0; i<3; i++) { cout << "(1)dog (2)cat (3)horse: "; cin >> choice; switch(choice) { case 1: ptr = new Dog; break; case 2: ptr = new Cat; break; case 3: ptr = new Horse; break; } theArray[i] = ptr;}for(i=0; i<3; i++) theArray[i]->Speak();return 0;} Если заглянуть в функцию main, в первый цикл, в тело оператора switch, то разве там нельзя наблюдать упомянутую в предыдущем примере утечку ? Цикл содержит 3 итерации, в каждой из которых указателю ptr присваивается адрес новой области, без предварительного освобождения... Или автор делает скидку на скорое завершение программы, т.к. при этом память освободиться автоматически ? Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Тролль Опубликовано 28 сентября, 2009 Жалоба Поделиться Опубликовано 28 сентября, 2009 Архимаг: for(i=0; i<3; i++) { cout << "(1)dog (2)cat (3)horse: "; cin >> choice; switch(choice) { case 1: ptr = new Dog; break; case 2: ptr = new Cat; break; case 3: ptr = new Horse; break; } theArray = ptr; } ptr действительно присваивается каждый раз адрес новой области, но он тут же передается в theArray = ptr;Все эти области нужны, они становятся содержанием массива theArray, поэтому отдавать обратно отведенную для них память нельзя, ptr тут - просто необязательное передаточное звено для адреса. Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Архимаг Опубликовано 28 сентября, 2009 Жалоба Поделиться Опубликовано 28 сентября, 2009 Архимаг: ptr действительно присваивается каждый раз адрес новой области, но он тут же передается в theArray = ptr; Все эти области нужны, они становятся содержанием массива theArray, поэтому отдавать обратно отведенную для них память нельзя, ptr тут - просто необязательное передаточное звено для адреса. Т.е. если взять два указателя: int *p1 = new int; int *p2 = p1; Они будут содержать адрес одной и той же области. Если освободить указатель p1: delete p1; то работа с указателем p2 будет невозможно ? Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Тролль Опубликовано 28 сентября, 2009 Жалоба Поделиться Опубликовано 28 сентября, 2009 (изменено) Присвоить ему новый адрес можно. А по старому адресу, на который он ссылается, может уже лежать все, что угодно. Фактически мы освобождаем для любых других применений не указатель p1, а область памяти, на которую он указывал. Адрес в указателе p2 остается прежним, но в квартире по указанному адресу могут быть уже другие жильцы, чаще всего ноли, но это зависит от компилятора. Изменено 28 сентября, 2009 пользователем Тролль Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.