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

Int Temp[12] - {2, 4, 7, } ;

Таким образом, элементы Теmр[0], Теmр[1] и Теmр[2] будут проинициализированы, в то время как оставшиеся элементы инициализации не получат.

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

// Выделение в памяти места для хранения

// шести объектов типа int

// (24 байта для 32-разрядной системы)

int Even[] = {0, 2, 4, 6, 8, 10};

Если далее в программе потребуется определить, сколько элементов имеется в массиве, можно воспользоваться следующим выражением:

int Size = sizeof(Even)/sizeof(Even[O]);

Здесь выражение sizeof(Even) определяет общий размер, занимаемый массивом Even в памяти (в байтах), а выражение sizeof (Even[0]) возвращает размер (тоже в байтах) одного элемента массива.

В многомодульном проекте инициализация массива при объявлении производится лишь в одном из модулей. В других модулях получить доступ к элементам массива можно с помощью ключевого слова extern:

// Модуль first.срр

...

char Hello[] = {'Н','е', '1', '1','о'} ;

...

// Модуль second.срр

extern Hello[];

// Модуль n.срр extern Hello[5];

Попытка повторной инициализации вызовет сообщение компилятора об ошибке.

Понятие указателя

Любой объект программы, будь то переменная базового или же производного типа, занимает в памяти определенную область. Местоположение объекта в памяти определяется его адресом. Как уже говорилось, при объявлении переменной для нее резервируется место в памяти, размер которого зависит от типа данной переменной, а для доступа к содержимому объекта служит его имя (идентификатор). Для того чтобы узнать адрес конкретной переменной, служит унарная операция взятия адреса. При этом перед именем переменной ставится знак амперсанда (&). Следующий ниже пример программы выведет на печать сначала значение переменной Vl и V2, а затем ее адрес:

#include <iostream.h>

#define end1 '\n'

Int main ()

{

unsigned int Vl = 40000;

unsigned int V2 = 300;

cout « "Значение1: " « Vl « endl;

cout « "Адрес : " « &Vl « endl;

oout « 3начение2: " « V2 « endl;

cout « "Адрес ; " « &V2 « endl;

return 0;

}

В результате будет выведено:

Значение1: 40000 Адрес : Ox0068feOO

Значение2: 300

Адрес : Ox0068fdfc

Как видно из примера, адреса локальных переменных, размещаемых в стеке, следуют в обратном порядке (стек растет в направлении младших адресов). Результат может отличаться даже при повторном запуске программы, так как невозможно предугадать, по какому адресу начнут размещаться переменные. Важно другое: разница в адресах первой и второй переменной всегда будет одинакова и при четырехбайтном представлении типа int составит 4 байта (см. рис. 4.1).

Рис. 4.1. Размещение переменных в памяти

Мощным средством разработчика программного обеспечения на C++ является возможность непосредственного доступа к памяти. Для этой цели предусматривается специальный тип переменных - указатели.

Указатель (pointer) представляет собой переменную, значение которой является адресом ячейки памяти. Указатель может ссылаться на переменную (базового или производного типа) или функцию. Наибольшая эффективность применения указателей в разработке приложений достигается при использовании их с массивами и символьными строками.

Объявление указателя имеет следующий синтаксис:

тип объекта* идентификатор;

Здесь тип_объекта определяет тип данных, на которые ссылается указатель с именем идентификатор. Символ 'звездочка' (*) сообщает компилятору, что объявленная переменная является указателем и не зависимо от того, сколько памяти требуется отвести под сам объект, для указателя резервируется два или четыре байта в зависимости от используемой модели памяти.

Рис. 4.2. Схема работы указателя

Поскольку указатель представляет собой ссылку на некоторую область памяти, ему может быть присвоен только адрес некоторой переменной (или функции), а не само ее значение. В случае некорректного присвоения компилятор выдаст соответствующее сообщение об ошибке.

Рассмотрим пример объявления и инициализации указателя.

char Symbol = ' Y' ;

char *pSymbol = &Symbol;//Указатель *pSymbol инициализируется

//адресом переменной Symbol

long Capital = 304L;

long* pLong;

pLong = &Capital;

В приведенном фрагменте объявляется символьная переменпая Symbol и инициализируется значением 'Y', затем определяется указатель на символьный тип данных pSymbol, значение которого назначается равным адресу переменной Symbol. Вслед за этим объявляется переменная capital типа long и указатель на этот же тип pLong, после чего производится инициализация указателя адресом переменной Capital.

Соседние файлы в папке ЛекцииКарасева