- •Передача в функции переменного числа параметров
- •Макрос va_start имеет синтаксис:
- •Ф-я average, которая рассчитывает среднее значение
- •Функцию average можно было бы организовать иначе,
- •Встраиваемые функции inline - снижение расходов
- •Область действия (имени, параметров, объектов) –
- •Операции разрешения области действия
- •Область видимости (имени, параметров, объектов) –
- •Динамическое распределение памяти 3 вида памяти, которую использует программа :
- •Динамически распределяемую память следует использовать в случае если мы заранее (на момент написания
- •После окончания работы с выделенной динамически памятью нужно освободить ее - ф-я free
- •Пример:
- •void *calloc(size_t nmemb, size_t size); (alloc.h)
- •Возвращаемое значение: возвращает адрес блока, который
- •Структуры и объединения – один из примеров
- •Как и любая переменная, структурная переменная
- •Синтаксис задания шаблона таков:
- •Пример. Структура Patient, которая может
- •Задание шаблона не связано с резервированием
- •Когда задан шаблон, может быть описана
- •Такая ссылка может располагаться в любом месте
- •struct Patient
- •typedef struct Patient
- •Однако использование имени шаблона совсем не
- •Пример - для вложенных структур действуют те же
- •Ссылка на поле вложенной структуры формируется из
- •ограничение на вложение структур состоит в том, что
- •Пример: typedef struct
- •Ссылка на поле структурной переменной через
- •Используя указатель на структурную переменную,
- •Пример: typedef struct
- •А если описать рабочий указатель и
- •Выделение оперативной памяти структурной
- •При выравнивании на границе слова компилятор при
- •Передача структур функции: по значению и по адресу.
- •При передаче адреса структуры не происходит ни
- •struct names
- •БИТОВЫЕ ПОЛЯ В СТРУКТУРАХ
- •Пример объявления битовых полей: unsigned color : 4;
- •struct names
- •При ссылке на поле в выражениях по маске
- •Union - объединение (куча) - подобно структуре в том,
- •Доступ к полям объединения выполняется через
- •Пример:
Ссылка на поле структурной переменной через
указатель обладает всеми свойствами обычной переменной: если поле – это массив символов, то 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++ (С) допускает использование в структурах особого типа полей – битовых полей. Их использование делает возможным доступ к отдельным битам более крупных объектов, например
байтов или слов.
Общий синтаксис описания битового поля: тип [имя ]: ширина; [ ] выделены необязательные элементы.
Битовое поле состоит из некоторого числа бит, специфицированных константным выражением - «ширина». Для битового поля спецификатор типа «тип» должен специфицировать беззнаковый целый тип, а константное выражение должно быть неотрицательной целой величиной. Массивы битовых полей, указатели на битовые поля и функции, возвращающие битовые поля не допускаются, а структуры - можно использовать. Идентификатор «имя» именует битовое поле и является