Указатели? Это просто! С++ #2

Доброго дня всем.

Итак, сейчас я продолжу рассказ о указателях, который начал вот в этой статье.

Допустим, мы объявили целочисленную переменную и присвоили ей значение 10:

int a=10;

В результате данных манипуляций процессор выделил ячейку в памяти размером 4 байта и присвоил ей некий адрес. И обратится к ней мы можем двумя способами:

  1. По адресу в памяти — прямая адресация.
  2. По идентификатору (имени переменной) — косвенная адресация.

Первый способ нонче не в чести, так как является очень неудобным (хотя в языке ассемблера без этого никуда).

В языках высокого уровня (языки, которые далеки от машинного кода) повсеместно используется косвенная адресация — это намного удобнее.

Все, теперь поговорим, собственно, о указателях (не может быть!).

Указатели — это обычные переменные, которые созданы для хранения адресов других переменных. Для них точно так же выделяется ячейка памяти (в неё помещается какой-либо адрес вместо значения, как в случае обычных переменных) и этой ячейке присваивается шестнадцатеричный адрес, как и всем другим переменным . Стоит отметить, что размер этой ячейки зависит от архитектуру ОС, т.е., если система 32-х разрядная, то для  того, чтобы в указатель могли поместится любые адреса, нужно 4 байта (4 байт = 32 бит), а в случае 64-х разрядной системы потребуется уже 8 байт. Такие вот пирожки с котятами.

Для объявления указателя в С++ используется оператор  «звездочка» — «*».  И делается это вот таким макаром:

int *pointer;

В результате мы получили указатель на целочисленную переменную. Тип указателя очень важен! Если мы объявили указатель как целочисленный, то мы можем помещать в него адреса только переменных типа int. Т.е., если объявили указатель типа float (тип с плавающей точкой), то и адреса туда можно помещать только переменных типа float. «Зачем это нужно? Ведь все указатели и так будут занимать одно и то же количество памяти» — спросите вы. На ваш логичный (и очень правильный!) вопрос я отвечу чуть позже (там будет все просто, как и всегда :)).

Мы объявили указатель, но он ни на что не указывает! Как же быть?

А вот для этого, есть еще один оператор — «&» (амперса́нд). Он называется оператором взятия адреса (еще он служит для создания ссылок, но это тема для отдельной статьи). Далее пример:

int variable=10; //Объявили обычную переменную и присвоили ей значение
int *pointer;   // Объявили указатель типа int
pointer=&variable; // (&variable) - это мы взяли адрес переменной variable
                   //и записали его в указатель

Теперь в указателе хранится адрес переменной variable. И если мы выведем значение указателя вот таким образом:

cout<<pointer<<endl;

То получим что-то такое:

addr

0032F9DC — это адрес переменной variable в оперативной памяти.

Теперь очень важный момент (сосредоточиться!). «*» служит не только для объявления указателя, но и является оператором для обращения по адресу хранящемуся в указателе (звездочка работает в этом ключе только с указателями).

Например, cout<<*pointer; равносильно cout<<variable;

Для наглядности скомпилируем этот код:

system("chcp 1251"); int variable=10; int *pointer; pointer=&variable; cout<<"Обращаем к variable через указатель : "<<*pointer<<endl; cout<<"Обращаемся непосредственно к variable : "<<variable<<endl; system("pause"); Читать дальше

Указатели? Это просто! С++ #1

Так. С вами снова Алексей. Вы думаете, что я буду рассказывать о бинарных деревьях (обещал в прошлой статье)? А вот и нет! Что все структуры да структуры — скучно…

Сегодня я вам расскажу, не побоюсь это слова, самой интересной вещи в С++ — о указателях. Указатели являются краеугольным камнем С++, без них невозможно написание ни одной серьезной программы (даже злосчастные списки реализованы с помощью указателей). Но, к сожалению, при изучении указателей начинающих берет оторопь. И зря! Указатели — это просто! Читать дальше