Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
201112.docx
Скачиваний:
0
Добавлен:
01.03.2025
Размер:
1.95 Mб
Скачать

Int main()

{

using namespace std;

double * p3 = new double [3];

// space for 3 doubles

p3[0] = 0.2;

// treat p3 like an array name

p3[1] = 0.5;

p3[2] = 0.8;

cout << "p3[1] is " << p3[1] << ".\n";

p3 = p3 + 1;

// increment the pointer

cout << "Now p3[0] is " << p3[0] << " and ";

cout << "p3[1] is " << p3[1] << ".\n";

p3 = p3 - 1;

// point back to beginning

delete [] p3;

// free the memory

cin.get();

return 0;

}

Как видите, программа использует указатель рЗ, как если бы он был именем массива: р3 [ 0 ] для первого элемента и т.д. Фундаментальное отличие между именем массива и указателем проявляется в следующей строке:

рЗ = рЗ + 1; // допускается для указателей, но не для имен массивов

Вы не можете изменить значение для имени массива. Но указатель — переменная, а потому ее значение можно изменить. Обратите внимание на эффект от добавления 1 к рЗ. Теперь выражение рЗ [0] ссылается на бывший второй элемент массива. То есть добавление 1 к рЗ заставляет рЗ указывать на второй элемент вместо первого. Вычитание 1 из значения указателя возвращает его назад, в исходное значение, поэтому программа может применить delete [ ] с корректным адресом.

Действительные адреса соседних элементов int отличаются на 2 или 4 байта, поэтому тот факт, что добавление 1 к рЗ дает адрес следующего элемента, говорит о том, что арифметика указателей устроена специальным образом. Так оно и есть на самом деле.

Подведение итогов относительно указателей

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

Объявление указателей

Чтобы объявить указатель на определенный тип, нужно использовать следующую форму:

имяТипа * имяУказателя;

Вот некоторые примеры:

double * рn; // рn может указывать на значение double

char * рс; // рс может указывать на значение char

Здесь рn и рс — указатели, a double * и char * — нотация C++ для представления указателя на double и указателя на char.

Присваивание значений указателям

Указателям должны быть присвоены адреса памяти. Можно применить операцию & к имени переменной, чтобы получить адрес именованной области памяти, либо операцию new, которая возвращает адрес неименованной памяти.

Вот некоторые примеры:

double * рn; // рn может указывать на значение double

double * pa; // так же и ра

char * рс; // рс может указывать на значение char

double bubble = 3.2;

рn = &bubble; // присваивание адреса bubble переменной рn

рс = new char; // присваивание адреса выделенной памяти char

// переменной рс

pa = new double [30] ; // присваивание адреса массива из 30 double переменной ра

Разыменование указателей

Разыменование указателя — это получение значения, на которое он указывает. Для этого к указателю применяется операция разыменования (*). То есть, если рn — указатель на bubble, как в предыдущем примере, то *рn — значение, на которое он указывает, в данном случае — 3.2.

Вот некоторые примеры:

cout << *рn; // вывод значения bubble

*рс = 'S'; // помещение 'S' в область памяти, на которую указывает рс

Нотация массивов — второй способ разыменования указателя; например, рn [ 0 ] — это то же самое, что и *рn. Никогда не следует разыменовывать указатель, который не был инициализирован правильным адресом.

Различие между указателем и указываемым значением

Помните, если pt — указатель на int, то *pt — не указатель на int, а полный эквивалент переменной типа int. Указателем является просто pt.

Вот некоторые примеры:

int * pt = new int; // присваивание адреса переменной pt

*pt = 5; //сохранение 5 по этому адресу

Имена массивов

В большинстве контекстов C++ трактует имя массива как эквивалент адреса его первого элемента.

Вот пример:

int tacos[10]; // теперь tacos - то же самое, что и &tacos[0]

Одно исключение из этого правила связано с применением операции sizeof к имени массива. В этом случае sizeof возвращает размер всего массива в байтах.

Арифметика указателей

C++ позволяет добавлять целые числа к указателю. Результат добавления к указателю единицы равен исходному адресу плюс значение, эквивалентное количеству байт в указываемом объекте. Можно также вычесть один указатель из другого, чтобы получить разницу между двумя указателями. Последняя операция, которая возвращает целочисленное значение, имеет смысл только в случае, когда два указателя указывают на элементы одного и того же массива (указание одной из позиций за границей массива также допускается); при этом результат означает расстояние между элементами массива.

Динамическое и статическое связывание для массивов

Объявление массива можно использовать для создания массива со статическим связыванием — т.е. массива, размер которого фиксирован на этапе компиляции:

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]