- •Функции.
- •Вызов функции с переменным числом параметров
- •Функция main и её параметры.
- •Директивы препроцессора (прекомпилера).
- •Объявление указателей.
- •Модификатор const.
- •Операции.
- •Указатели на различные типы.
- •Указатель на void.
- •Применение указателей для передачи данных между функциями.
- •Массивы.
- •Индексация массивов.
- •Хранение массива в памяти. Адреса элементов. Хранение массива в памяти.
- •Массивы и константные указатели.
- •Статическое и динамическое выделение памяти.
- •Функции calloc, malloc, free
- •Функция realloc
- •Передача массивов в качестве аргументов функции.
- •Указатели на функции.
- •Библиотеки функций.
- •Функции форматированного ввода-вывода.
- •Функция printf().
- •%[Флаги] [Ширина] [.Точность] [{h | l | I | i32 | i64}]тип
- •Для чего нужен форматированный вывод.
- •Функция scanf().
- •Функции sprintf() и sscanf().
- •Функции fprintf() и fscanf().
- •Функции неформатированного ввода-вывода.
- •Работа со строковыми данными (стрингами). Представление строковых данных в языке c.
- •Функции работы со строками.
- •Потоковый ввод-вывод
- •Функции форматированного ввода-вывода.
- •Функция printf().
- •%[Флаги] [Ширина] [.Точность] [{h | l | I | i32 | i64}]тип
- •Для чего нужен форматированный вывод.
- •Функция scanf().
- •Функции sprintf() и sscanf().
- •Функции fprintf() и fscanf().
- •Функции неформатированного ввода-вывода.
- •Функции работы с файлами.
- •Потоковый ввод-вывод
- •Работа с потоками
- •Курсор.
- •Ввод-вывод отдельных символов и строк.
- •Форматированный ввод-вывод информации в файл.
- •Блочный потоковый ввод-вывод
- •Смена текущей позиции в файле. Проверка конца файла.
- •Функции доступа к файлам нижнего уровня.
- •Методы сортировки данных.
- •Введение
- •Сравнение методов сортировки
- •Программная реализация алгоритмов сортировки
- •Метод пузырька.
- •Метод обмена.
- •Метод вставки.
- •Метод Шелла.
- •Метод кучи (бинарной кучи).
- •Очередь
- •Линейный список
- •Физическое (машинное) представление линейных списков
- •Программные реализации структур данных. Стек. Реализация в виде массива.
- •Стек. Связанное представление.
- •Очереди. Реализация в виде массива.
- •Дерево. Связанное представление.
- •Рекурсивный вызов функций.
- •Структуры. Объединения. Перечисления.
- •Перечисление (enum).
- •Производные типы данных.
- •Структура (struct).
- •Побитовое описание полей структуры.
- •Объявление переменных, реализующих структуру.
- •Доступ к элементам структуры.
- •Объединение (union).
- •Вложенное описание структур и объединений.
- •Описание структур и объединений в виде пользовательского типа.
- •Передача структур и объединений в виде параметров функции.
- •Инициализация структур и объединений.
- •Выгода от использования структур
Статическое и динамическое выделение памяти.
Выделение памяти под переменные и массивы бывает статическим и динамическим.
Статическое выделение памяти – выделение памяти, при котором размер выделяемой памяти известен ещё на этапе компиляции. При статическом выделении памяти операции выделения и освобождения памяти встраиваются в программу компилятором автоматически. Программисту достаточно лишь объявить переменную или массив, в этом же месте программы под неё будет выделена память.
Например,
void func()
{
int i; // здесь выделяется 4 байта под переменную i
char ac[10]; // здесь выделяется 10 байт под массив ac
…
} // конец функции, здесь освобождается память из-под всех
// локальных переменных и массивов
Динамическое выделение памяти – выделение памяти в ходе работы программы, обычно используется в случаях, когда заранее неизвестен объём необходимой памяти. В случае динамического выделения памяти ответственность за выделение и освобождение памяти лежит на программисте. Неправильное выделение или освобождение памяти может привести к серьёзным последствиям вплоть до перезагрузки операционной системы (в некоторых ОС).
Доступ к динамически выделенной памяти осуществляется с помощью указателей. При этом выделенную область часто называют динамическим массивом из-за схожести методов работы с массивами и методов работы с динамически выделенной памятью.
Управление динамическим выделением памяти осуществляется с помощью функций, описанных в файле alloc.h:
calloc
malloc
realloc
free
Функции calloc, malloc, free
Функция void* calloc(size_t nitems, size_t size); динамически выделяет блок памяти размером nitems * size. Блок инициализируется нулями. Функция calloc возвращает указатель на выделенный блок в случае успешного выделения памяти, иначе calloc возвращает NULL ( например, если недостаточно памяти для выделения нового блока или в случае иных ошибок). Прототипы функции описаны в stdlib.h, alloc.h.
Функция void* malloc(size_t size); динамически выделяет блок памяти, размером size байт. Инициализация содержимого блока не производится. Возвращаемое значение полностью аналогично возвращаемому значению функции calloc. Прототипы функции описаны в stdlib.h, alloc.h.
Функция void free(void* block); освобождает блок памяти, выделенный функциями calloc, malloc или realloc. В качестве параметра block ей передаётся указатель на освобождаемый блок памяти.
Пример:
#include <alloc.h>
void main()
{
long *pl;
short *ps;
int i;
//Выделяем память под динамические массивы.
//В calloc передаём количество элементов и размер элемента.
//В malloc передаём полный размер выделяемого блока в
//байтах.
pl=calloc(10,sizeof(long));
ps=malloc(10*sizeof(short));
if(pl && ps) // если оба указателя не равны NULL (0)
{
// память выделена, можем с ней работать
for(i=0;i<10;i++)
{
pl[i]=i*2;
ps[i]=i*2+1;
}
…
// В конце работы освобождаем память,
// на которую указывают pl и ps.
free(pl);
free(ps);
}
else
{
printf("Недостаточно памяти\n");
}
}