Указатели, поясните тупому.
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.
Уважаемые. Прошу помощи! Никак до меня не дойдет великое значение указателей.
Для чего они собственно нужны?
Из урока на этом сайте:
"...играя в тот же Battlefield, геймер в каждый новый момент времени видит различные объекты на экране монитора, например сейчас я стреляю во врага, а через долю секунды он уже падает убитым, создавая вокруг себя множество спецэффектов, таких как пыль, тени, и т.п.
Естественно, все это занимает какое-то место в оперативной памяти компьютера. Если не уничтожать неиспользуемые объекты, очень скоро они заполнят весь объем ресурсов ПК.
По этим причинам, в большинстве языков, в том числе и C/C++, имеется понятие указателя."
Не могу связать одно с другим. Очистку памяти от объектов (переменных) и наличие указателей.
Может автор хотел сказать, что обычные переменные нельзя удалить из памяти и поэтому вводятся указатели?
string a1=«hiya!»;
string sp1 = &a1;
cout << sp1 << endl;
Что должно вывестись на экран? номер ячейки памяти,где хранится а1 или значение переменной а1?
Чем больше читаю и смотрю примеров, тем больше тупею.
(1) Очистка памяти и указатели связаны достаточно косвенно ))
(2) Обычные переменные (автоматические) очень здорово удаляются из памяти. Причём автоматически ))
(3) А самому проверить свой код религия не позволяет? В нём, кстати, ошибка. Должно быть так:
Будет выведен адрес переменной
a1
.Но с типом (точнее говоря, с классом)
string
не всё так просто. Поскольку это не элементарный тип вродеint
илиchar
. Например, фрагментвыведет строку hiya!. А фрагмент
выведет первый символ строки «hiya!», букву h? А вот и нет. Скорее всего будет выведен какой-то другой символ (с вероятностью 255/256). Потому что последовательность байт «hiya!» в объекте типа
string
начинается не с адреса&a1
.Поэтому экспериментировать лучше с элементарными типами.
(4) Указатель — это адрес памяти, по которому располагается значение определённого типа. Тип важен, поскольку в адресной арифметике в С/С++ изменение указателя на единицу изменит адрес, хранящийся в указателе, на размер размер типа данных. Например, увеличение на 1 указателя
char *char_ptr
приведёт к увеличению адреса на 1 (sizeof(char)
), а увеличение на 1 указателяint *int_ptr
приведёт к увеличению адреса на 4 (sizeof(int)
).На указателях в С/С++ базируется работа с массивами. Например, оператор
int array[5]
выделяет участок памяти, достаточный для размещения пяти значений типаint
и присваивает переменнойarray
адрес этого участка памяти. Т.е.array
— это константный указатель наint
. Обращениеarray[0]
эквивалентно*array
, аarray[1]
—*(array + 1)
и т.д.На указателях в С/С++ базируется работа с динамической памятью. Оператор
new
выделяет из кучи (heap) область памяти и возвращает указатель на неё. Операторdelete
получает указатель на выделенную из кучи область памяти и освобождает её (возвращает в кучу). В статье имелся ввиду именно этот случай использования указателей.Указатели могут использоваться для передачи параметров в функцию. При этом внутри функции можно изменить значение фактического параметра.
Спасибо. что-то понял, что-то пока нет. А код свой я проверял. у меня выводилась строка «hiya!». А мне казалось, что должно выводить адрес памяти, куда записано «hiya!». Оказывается надо писать для вывода адреса cout << sp1 << endl; а у меня cout << *sp1 << endl;
Очень сложно все для меня. Сложно все осмыслить. Например. Читаю строку -понятно, читаешь вторую строку — тоже понятно. А посмотришь на две строки вместе — какой-то бред)).
Указателям нужно уделять особое внимание это очень важная и тонкая тема. Если не поймешь сейчас конструкции типа
то дальше ты «ногу сломишь», в конструкциях типа
или при выделении динамической памяти (например, под двумерный массив), ведь ты не сможешь динамически выделить память под двумерный массив таким способом, как показан выше
здесь придется сделать нечто подобное
и это далеко не самые сложные вещи. Ведь библиотека STL практически вся построена на работе с указателями. Так-что не слаживай руки и вперед на покорение, только кажущихся непокоримыми, указателей :)))
Юрий, здесь у тебя звёздочка лишняя:
fitter, обычно, конечно, так
*(*(str + 1) + 7) = "a"
не пишут, а используют нотацию массивов. А вот при реализации динамических структур данных типа стеков, одно- и двусвязных списков, деревьев без указателей не обойтись.Просто надо запомнить, что указатель — это адрес памяти, по которому лежит значение. Доступ к значению — операция разыменования указателя
*ptr
. Если есть переменная, которой присвоено значение, то получить на это значение указатель — операция взятия адресаptr = &var
; в этом случаеvar
и*ptr
будут адресоваться к одной и той же области памяти.Спасибо ребята! Чтоб я без вас делал! Сейчас буду практикой осмысливать выше написанное.
Только разве не надо звездочку ставить около ptr ? «операция взятия адреса ptr = &var»
Не надо. Здесь
ptr
предназначено для хранения адреса, и результат операции&var
— как раз является адресом.А вот в конструкции
звёздочка нужна, поскольку это описание переменной с инициализацией: выражение
int *ptr
описывает переменнуюptr
как указатель наint
, а часть= &var
присваивает адрес переменнойvar
переменнойptr
.Указатель — тип данных для хранения адреса памяти. Для определения указателя на переменную типа
int
используют подстановку*
после названия типа.Т.е., при инициализации указателя, символ
*
определяет именно тип данных, как указатель.Переменная
pointer
может хранить только значение адреса памяти (вернее, его диапазона, размеромsizeof(int)
байт).Чтобы получить значение, которое находится по адресу, на который указывает указатель, используют оператор разыменовывания указателя —
*
. И если в первом случае, при инициализации переменной-указателя, этот символ определял тип данных, то при разыменовывании указателя происходит совсем другая операция.Оператор
&
используется для взятия адреса переменной. Если применить его к указателю, то он вернет адрес самого указателя, который, в свою очередь хранит другой адрес.