Массивы указателей.

В языках С и C++ можно создавать не только простые массивы и указатели. Их можно объединить в очень полезную конструкцию — массив указателей. Массив указателей — это такой массив, элементы которого являются указателями на другие объекты. Эти объекты, в свою очередь, могут быть указателями. Это означает, что можно иметь массив указателей, которые ссылаются на другие указатели.

Можно создавать массивы указателей. Для объявления массива целочисленных указателей из десяти элементов следует написать:

int *х[10];

Для присвоения адреса целочисленной переменной var третьему элементу массива следует написать:

х[2] = &var;

Для получения значения var следует написать:

*х [2]

void display_array(int *q[]) { int t; for(t=0; t<10; t++) printf ("%d ", *q[t]); }

Если необходимо передать массив указателей в функцию, можно использовать метод, аналогичный передаче обычных массивов. Просто надо вызвать функцию с именем массива без индексов. Например, функция, получающая массив х, должна выглядеть следующим образом:

 


 

 

Надо помнить, что q - это не указатель на целое, а массив указателей на целые. Следовательно, необходимо объявить параметр q как массив целых указателей. Он не может объявиться как простой целочисленный указатель, поскольку он не является им.

void serror(int num) { static char *err[] = { "Cannot Open File\n", "Read Error\n", "Write Error\n", "Media Failure\n" }; printf ("%s", err[num]); }

Типичным использованием массивов указателей является хранение сообщений об ошибках. Можно создать функцию, выводящую сообщение по полученному номеру, как показано ниже:


 

 

Как можно видеть, printf() в serror() вызывается с указателем на символ, указывающим на одно из сообщений, номер которого передается в функцию. Например, если num приняла значение 2, будет выведено сообщение «Write Error».

Интересно заметить, что аргумент командной строки argv является массивом указателей на символы.

 

 

78. Указатели. Ссылочный тип в C++ (reference type). Адрес в качестве возвращаемого значения функции. Передача параметров по ссылке и по значению. Использование встроенного отладчика. Использование ссылочного типа. Использование указателей и ссылок с ключевым

 

Указатель — переменная, содержащая адрес объекта. Указатель не несет информации о содержимом объекта, а содержит сведения о том, где размещен объект.

Память компьютера можно представить в виде последовательности пронумерованных однобайтовых ячеек, с которыми можно работать по отдельности или блоками.

Каждая переменная в памяти имеет свой адрес - номер первой ячейки, где она расположена, а также свое значение. Указатель — это тоже переменная, которая размещается в памяти. Она тоже имеет адрес, а ее значение является адресом некоторой другой переменной. Переменная, объявленная как указатель, занимает 4 байта в оперативной памяти (в случае 32-битной версии компилятора).

Указатель, как и любая переменная, должен быть объявлен.
Общая форма объявления указателя

 

тип *ИмяОбъекта;


Тип указателя— это тип переменной, адрес которой он содержит.

Для работы с указателями в Си определены две операции:

операция * (звездочка) — позволяет получить значение объекта по его адресу - определяет значение переменной, которое содержится по адресу, содержащемуся в указателе;

операция & (амперсанд) — позволяет определить адрес переменной.

Например,

сhar c; // переменная char *p; // указатель p = &c; // p = адрес c  

 

Ссылочный тип в C ++ ( reference type ).

В языке C++ имеется способ вызова по ссылке, который использовать еще проще, чем указатели. Для начала рассмотрим использование ссылочных переменных в C++. Так же, как и в С, в языке C++ можно объявить обычные переменные или переменные-указатели. В первом случае для данных действительно выделяется память; во втором случае память резервируется для адреса объекта, который будет создан в другое время. В C++ имеется третий тип объявлений — ссылки. Так же, как указатель, ссылочная переменная указывает на положение другой переменной, однако, так же как и в случае обычной переменной, для ссылки не требуется специальной операции разыменования. Синтаксис ссылочной переменной понятен:

 

int iresult_a=5;

int& riresult_a=iresult_a; // правильно

int& riresult b; // неправильно: нет начального значения

 

В этом примере определяется ссылочная переменная riresult_a и присваивается существующей переменной iresult_a. После этого адресуемое значение имеет два имени — iresult_a и riresul_a. Поскольку обе переменные указывают на одну и ту же ячейку памяти, они представляют собой, по сути, одну переменную. Любое присваивание, сделанное по отношению к riresult_a, отражается на iresult_a; справедливо и обратное утверждение. Следовательно, при помощи ссылки можно создать нечто подобное псевдониму (alias) переменной.

Ссылки имеют ограничение, позволяющее отличать их от указателей, которые ведут себя очень похоже. Значение ссылочного типа должно быть задано при объявлении и не может меняться в процессе выполнения программы. После инициализации типа при объявлении, ссылка всегда указывает на одну и ту же ячейку памяти. Следовательно, при любом присваивании значения ссылочной переменной изменяются только данные в памяти, а не адрес самой переменной. Другими словами, ссылку можно считать указателем на ячейку памяти с постоянным адресом.