Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
2014_2015 / LECT7_new1.pptx
Скачиваний:
9
Добавлен:
27.12.2015
Размер:
1.12 Mб
Скачать

Ссылка на поле структурной переменной через

указатель обладает всеми свойствами обычной переменной: если поле – это массив символов, то ptr_patient -> Diagnosis – это указатель-константа на первый элемент массива.

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

Вообще говоря, ссылка на поле через указатель – синоним ссылки на это поле через операцию *. Например, если описан шаблон Patient и сделано описание данных:

struct Patient *ptr_patient, first_patient, second_patient; ptr_patient = &first_patient;

то ссылка (*ptr_patient).year эквивалентна ссылке first_patient.year и ссылке ptr. patient-> year.

Доступ к полям вложенной структуры: сначала используют операцию ->, а затем ссылку на поле

вложенной структуры операцией '.':

Используя указатель на структурную переменную,

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

Массивы структурных переменных

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

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

обычных переменных.

Пример: typedef struct

{

int PatientID;

char * PatientFamily; char * PatientName; char * PatientSecName; int year;

char * Diagnosis; int DiagnosisID;

} Patient;

. . .

Patient P_database[20];

Доступ к элементам массива может выполняться с использованием индекса или через указатель- константу, которым является имя массива. Например, доступ к полю year i-ro элемента:

P_database[i].year = 1968; или

(*(P_database +i)).year=1968; или

А если описать рабочий указатель и

инициализировать его адресом первого элемента массива

Patient P_database[20], *ptr= P_database;

то для доступа к полям i-ro элемента массива структурных переменных можно использовать указатель ptr:

(ptr+i)->year=1978;

Продвижение указателя ptr операцией ++ или - - соответственно увеличивает или уменьшает его на размер типа Patient, т. е. устанавливает на следующий элемент массива структурных переменных вперед или назад. Это удобно при последовательном доступе к элементам массива.

Выделение оперативной памяти структурной

переменной осуществляется по шаблону, интерпретируемому слева направо. При этом учитывается дополнительный фактор - выравнивание структуры (Structure Alignement).

Выравнивание задается либо как опция среды BC (Options-> Compiller->Code Generation -> Word Alignement), либо опцией компилятора командной строки. Можно задать выравнивание структурной

переменной на границе слова ( х Word Alignement в среде ВС, или соответствующая опция компилятора

командной строки) или на границе байта ( Word

Alignement в среде ВС, или соответствующая опция компилятора командной строки; принимается по умолчанию).

При выравнивании структурной переменной на границе байта отдельные ее поля в памяти располагаются без "зазоров". Начинаться переменная будет с любого

При выравнивании на границе слова компилятор при

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

1)отдельная структурная переменная (элемент массива структурных переменных) начинается на границе слова, т. е. с четного адреса;

2)любое поле, тип которого не совпадает с типом char, будет начинаться с четного адреса (имеет четное смещение от начала структурной переменной);

3)при необходимости в конце структурной переменной добавляется еще один байт так, чтобы число байтов переменной было четным.

Выравнивание сказывается критическим образом при переносе структурных переменных между диском и

памятью.

Передача структур функции: по значению и по адресу.

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

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

переменную.

При передаче адреса структуры не происходит ни

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

Вообще-то передать в функцию структуру можно и по ссылке.

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

функции) и значения полей этой переменной.

struct names

{

char * P_Family; char * P_Name; char * P_SecName;

}; /*Прототип функции инициализации*/

void Init(names *, char*, char*, char*); /*Определим функцию Init()*/

void Init(names * pm, char* f, char* n, char* ns,)

{

pm-> P_Family =f ; pm-> P_Name = n; pm-> P_SecName = ns;

}//Возвращать ничего не требуется

names patient1; //Создание переменной по имени // Создание переменной посредством указателя names * patient2=new names;

/*Вызов ф-и инициализации*/

БИТОВЫЕ ПОЛЯ В СТРУКТУРАХ

Язык C++ (С) допускает использование в структурах особого типа полей – битовых полей. Их использование делает возможным доступ к отдельным битам более крупных объектов, например

байтов или слов.

Общий синтаксис описания битового поля: тип [имя ]: ширина; [ ] выделены необязательные элементы.

Битовое поле состоит из некоторого числа бит, специфицированных константным выражением - «ширина». Для битового поля спецификатор типа «тип» должен специфицировать беззнаковый целый тип, а константное выражение должно быть неотрицательной целой величиной. Массивы битовых полей, указатели на битовые поля и функции, возвращающие битовые поля не допускаются, а структуры - можно использовать. Идентификатор «имя» именует битовое поле и является

Соседние файлы в папке 2014_2015