Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Философия программирования на C++: введение в указатели


Приветствуем наших подписчиков!

Тема сегодняшнего выпуска - указатели. Мы коротко расскажем об основах, а в дальнейших выпусках вы будете узнавать все больше и больше нового (как и о потоке ввода cin, про который мы рассказали вам в прошлом выпуске).

Итак, начнем. Думаю не нужно объяснять, что все переменные, создаваемые в программе, хранятся в оперативной памяти (и сама программа тоже загружается в нее перед выполнением). Так вот всю память можно представить себе в виде последовательности байтов, каждый из которых имеет уникальный адрес (номер байта). На 32-хбитной системе для адреса требуется 4 байта, на 64-хбитной соответственно 64 бита. В С++ для определения адреса какой-либо переменной используется оператор &. Просто приведем пример его использования:

#include "iostream"
using namespace std;

int main() {
  int j = 20, k = 30;
  cout << "k = " << k << endl;
  cout << "Address of k: " << (long)&k << endl;
  cout << "j = " << j << endl;
  cout << "Address of j: " << (long)&j << endl;
  cout << "Address of function main(): " << (long)&main << endl;
}


Как видно в приведенной выше программе, даже функция main() имеет свой адрес (как и другие функции, но об это позже). Мы использовали приведение типа указателя к long (указываем компилятору, что требуется интерпретировать данное значение как long). Мы это делаем просто для большей наглядности. Если этого не делать, то адреса будут выводиться в шестнадцатеричном виде. Дальше мы всегда будем тоже пользоваться шестнадцатеричным видом для представления значений указателей, поскольку в таком виде их гораздо удобнее использовать.

Для хранения адресов существуют специальные типы данных в C++. Такие типы и называются указателями (они "указывают" на какой-либо участок памяти). Оператором определения указателей является символ '*' (тот же, что используется для оператора умножения). Сначала задаем имя типа данных, а после перед именем переменной ставим символ звездочки (признак указателя).

int* pointer;

Эта запись означает, что pointer указывает на переменную типа int. Сразу приведем пример.

#include "iostream"
using namespace std;

int main() {
  int j = 20, k = 30;
  int* pointer;
  pointer = &j;
  cout << "pointer = " << pointer << endl;
  cout << "Address of j: " << &j << endl;
  cout << "*pointer = " << *pointer << endl;
  cout << "j = " << j << endl;
  j = 200;
  cout << "*pointer = " << *pointer << endl;
  *pointer = 1000;
  cout << "j = " << j << endl;
}

Здесь мы в указатель pointer сохраняем адрес переменной j. Теперь pointer указывает на переменную j. Чтобы получить доступ к значению, на которое указывает указатель, необходимо его разыменовать тем же оператором звездочка. Это сделано в нашем примере в следующих строках:

cout << "*pointer = " << *pointer << endl;
*pointer = 1000;


Сначала мы выводим значение, на которое указывает pointer, а потом и изменяем его оператором присвоения. Как видно, значение, на которое указывает pointer и переменная j меняют значения одновременно. Это потому, что pointer указывает на переменную j и разыменовывая его мы получаем фактически переменную j.

Отметим, что переменная pointer также имеет адрес и тоже хранится в памяти. Можете посмотреть, сколько она занимает памяти в вашей системе с помощью оператора sizeof() (см. о нем предыдущие выпуски).

На этом мы заканчиваем краткое введение в указатели, которое будет продолжено в последующих выпусках. Напоследок советую попробовать указатели на другие типы данных (char, double, bool).

PS. В догонку хотелось бы отметить, что объявление многих переменных типа указателей таким образом:

int* a, b, c;

не будет работать, поскольку синтаксис С++ не поддерживает такое выражение. Вместо этого переменная a будет указателем, а переменные b и c будут целыми. Чтобы объявить все их указателями, необходимо объявлять так:

int *a, *b, *c;

Мы советуем ограничиться объявлением ровно одной переменной на одной строке, чтобы не возникало путаницы.

На этом все, до следующего выпуска!
Наш e-mail: thinkingc@qt-prog.ru - пишите нам, мы всегда рады ответить на ваши вопросы и предложения.

В избранное