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 пользователем Тролль Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения
Для публикации сообщений создайте учётную запись или авторизуйтесь
Вы должны быть пользователем, чтобы оставить комментарий
Создать учетную запись
Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!
Регистрация нового пользователяВойти
Уже есть аккаунт? Войти в систему.
Войти