- •Передача в функции переменного числа параметров
- •Макрос 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 - объединение (куча) - подобно структуре в том,
- •Доступ к полям объединения выполняется через
- •Пример:
Динамически распределяемую память следует использовать в случае если мы заранее (на момент написания программы) не знаем сколько памяти нам понадобится (например, размер массива зависит от того, что введет пользователь во время работы прог-раммы) и при работе с большими объемами данных (например, массив из 1 000 000 int не влезет в стек).
Функции стандартных библиотек для работы с динамической памятью
void *malloc(size_t size); (alloc.h)
В качестве входного параметра функция принимает размер памяти, которую требуется выделить. Возвращаемым значением является указатель на выделенный в куче участок памяти.
Пример: выделение памяти под 1 000 000 int: int * p = malloc(1000000*sizeof(int)); - в С
В С++ нет неявного приведения указателей: int * p = (int *) malloc(1000000*sizeof(int));
Если ОС не смогла выделить память (например, памяти не хватило), то malloc возвращает 0.
После окончания работы с выделенной динамически памятью нужно освободить ее - ф-я free возвращает память под управление ОС.
void free(void *ptr); (alloc.h)
В качестве входного параметра в free нужно передать указатель, значение которого получено из функции malloc. Вызов free на указателях, полученных не из malloc (например, free(p+10)), приведет к неопределенному поведению, т.к. при выделении памяти при помощи malloc в ячейки перед той, на которую указывает возвращаемый функцией указатель операционная система записывает служебную информацию. При вызове free(p+10) информация находящаяся перед ячейкой (p+10) будет трактоваться как служебная.
Пример:
#include<string.h>
#include<stdio.h>
#include<alloc.h> int main(void)
{
char *str;
/* выделить память под строку */ str = malloc(15);
/* скопировать в строку "Student Petrov" */ strcpy(str," Student Petrov ");
/* вывести строку */ printf("Строка: %s\n",str); /* освободить память */ free(str);
return 0;
}
void *calloc(size_t nmemb, size_t size); (alloc.h)
Ф-я работает аналогично malloc, отличается син-таксисом (вместо размера выделяемой памяти нужно задать количество элементов и размер одного элемента) и обнулением выделенной памяти.
Например, после выполнения
int * q = (int *) calloc(1000000, sizeof(int))
q будет указывать на начало массива из миллиона инициализированных нулями чисел типа int.
void *realloc(void *ptr, size_t size); (alloc.h)
Ф-я изменяет размер выделенной памяти (на которую указывает ptr, полученный из вызова malloc, calloc или realloc). Если указанный в параметре size размер больше, чем тот, который был выделен под указатель ptr, то проверяется, есть ли возможность выделить недостающие ячейки памяти подряд с уже выделен-ными. Если места недостаточно, то выделяется новый участок памяти размером size и данные по указателю ptr копируются в начало нового участка. Если ptr является нулевым указателем, realloc работает также как и malloc.
Возвращаемое значение: возвращает адрес блока, который
может отличаться от исходного. Если блок не мо-жет быть выделен или size равно 0, то возвращает NULL. Переносимость: realloc доступна в системах UNIX и поддерживается стандартом ANSI C.
Пример:
#include<stdio.h>
#include<string.h>
#include<alloc.h> int main(void)
{char *str;
str = malloc(10); /* выделить память под строку */ strcpy(str,"Student"); /*скопировать в строку "Student" */ /* вывести строку */
printf("String: %s\n, address: %p\n",str,str); str = realloc(str,20);
printf(" String: %s\n, new address:: %p\n",str,str); free(str); /* освободить память */
return 0;
}
Структуры и объединения – один из примеров
составных типов данных, называемых агрегатными типами.
Структурные переменные (структуры) – это объединение одной или более переменных, возможно, разных типов, в одну область памяти, имеющую одно имя. Отдельные составные части структурной переменной называются полями.
Объединения (кучи) подобны структурам в том, что содержат поля различных типов, но помещаемые в одно и то же место памяти. Фактически объединения
– это доступ к одному и тому же месту памяти, но по- разному.
Термин "структура" в C++ (C) 2м разным понятиям:
1)обозначение места в памяти, где располагается информация; это место называется структурной переменной;
2)правила формирования структурной переменной,
используемые компилятором для выделения ей места в
Как и любая переменная, структурная переменная
должна описываться. Ее описание состоит из 2х шагов:
1)задание шаблона структуры;
2)собственно описание структурной переменной.
Каждый шаблон имеет собственное имя для того, чтобы компилятор мог различать различные шаблоны.
В том случае, если в функции используется единственный шаблон, он может не иметь имя, что задается пропуском имени при описании шаблона.
Имена шаблонов должны быть уникальными в пределах их области определения, и в частности в пределах одной функции может быть только один безымянный шаблон.
Синтаксис задания шаблона таков:
struct имя_шаблона
{
тип_1 имя_поля_1; тип_2 имя_поля_2;
•••
тип_N имя_поля_N;
};
имя_шаблона – имя шаблона, удовлетворяющее правилам задания идентификаторов языка С++ (С); тип_1, тип_2,..., тип_N – любые типы, например int, char, float;
имя_поля_1, имя_поля_2, ..., имя_поля_N – имена полей, удовлетворяющие правилам задания идентификаторов языка С++ (С).
Пример. Структура Patient, которая может
использоваться при каталогизации медицинских карт :
struct Patient
{
int PatientID;
char * PatientFamily; char * PatientName; char * PatientSecName; int year;
char * Diagnosis; int DiagnosisID;
}; Имена полей в одном шаблоне должны быть
уникальными, но в разных шаблонах можно использовать совпадающие имена полей. Кроме того, имена шаблонов проверяются на уникальность друг с другом, а не с метками или именами переменных, т.е. имя шаблона
может и совпадать с именами полей, переменных или
Задание шаблона не связано с резервированием
какой-либо памяти компилятором. Шаблон дает компилятору всю необходимую информацию о полях структурной переменной для резервирования места в памяти и организации доступа к этой памяти при описании структурной переменной и ссылках на отдельные поля структурной переменной.
Фактически шаблон – это задание нового типа struct имя_шаблона. В приведенном примере был введен новый тип struct Patient.
Как и простая переменная, шаблон имеет область определения (видимость). Если шаблон описан внутри блока {}, – это локальный шаблон, видимый только из пределов данного блока, в частности из пределов конкретной функции. Если описание шаблона помещено вне блоков, такой шаблон видим во всех функциях ниже точки описания шаблона до границы файла. Нельзя описать шаблон с реквизитом extern.