
- •Часть 2
- •Содержание
- •1.37.18.5. Несовместимость фактического и формального параметров указателей функции……………………………33
- •1. Основы программирования на языке Си
- •1.30. Цикл, управляемый инструкцией while
- •1.31. Цикл, управляемый инструкцией do while
- •1.32. Цикл с выходом
- •1.33. Вложенные циклы
- •1.34. Перечисление
- •1.35. Функция
- •1.35.1. Назначение функции
- •1.35.2. Определение функции
- •1.35.3. Вызов функции.
- •1.35.4. Прототип функции
- •1.35.5. Способы передача параметров
- •1.35.6. Понятие о встраиваемых (inline) функциях
- •1.36. Организация модулей в языке Си
- •1.36.1. Пример организации модуля
- •1.36.2. Защита от повторного включения заголовочного файла
- •1.37. Массивы и указатели
- •1.37.1. Массивы. Общие сведения
- •1.37.1.1. Классификация массивов
- •1.37.1.2. Определение и инициализация массива
- •1.37.1.3. Операции с массивами
- •1.37.2. Указатели. Общие сведения
- •1.37.2.1. Области применения указателей
- •1.37.2.2. Классификация указателей
- •1.37.2.3. Понятие о нулевом указателе
- •1.37.2.4. Понятие о недействительном указателе
- •1.37.2.5. Определение переменной – указателя
- •1.37.2.6. Операции с указателями
- •1.37.2.6.1. Разыменование указателя. Модель переменной-указателя
- •1.37.2.6.3. Оператор присваивания
- •1.37.2.6.4. Инкремент и декремент указателя
- •1.37.2.6.5. Сложение и вычитание целого числа
- •1.37.2.6.6. Вычитание указателей
- •1.37.2.6.7. Индексирование указателей
- •1.37.2.6.8. Сравнение указателей
- •1.37.2.7. Указатели и динамическая память
- •Функция malloc
- •Функция calloc
- •Функция realloc
- •Функция free
- •1.37.3. Указатели и квалификатор const
- •1.37.4. Указатели и квалификатор restrict
- •1.37.5. Связь между указателями и массивами
- •1.37.6. Указатели – параметры функций
- •1.37.7. Массивы – параметры функций
- •1.37.8. Ошибки при работе с указателями
- •1.37.8.1. Ошибки при объявлении указателей
- •1.37.8.2. Использование неинициализированного указателя
- •1.37.8.3. Присваивание несовместимых указателей
- •1.37.8.4. Разыменование нулевого указателя
- •1.37.18.5. Несовместимость фактического и формального параметров указателей функции
- •1.37.8.6. Возврат из функции указателя на локальную переменную
- •1.37.8.7. Висячий указатель
- •1.37.8.8. Утечка памяти
- •1.37.9. Указатели на функцию
- •1.37.9.1. Выражение указатель на функцию
- •1.37.9.2. Определение указателя переменной на функцию
- •1.37.9.3. Инициализация переменной указатель на функцию
- •1.37.9.4. Операции с указателями на функцию
- •1.38.5.Строковые функции стандарта с11
- •1.38.6. Ввод и вывод строк
- •1.39. Работа со структурами
- •1.39.1. Объявление структур
- •1.39.2. Определение структуры в многомодульной программе
- •1.39.3. Инициализация структур
- •1.39.4. Обращение к полям структуры
- •1.39.5. Операции над структурами
- •1.39.6. Массивы структур
- •1.39.6.1. Объявление массивов структур
- •1.39.6.2. Идентификация элементов массива структур
- •1.40. Работа с внешними устройствами
- •1.40.1. Понятие потока
- •1.40.2. Файлы
- •1.40.2.1. Указатель файла
- •1.40.2.2 Функция fopen
- •1.40.2.9. Построковый ввод-вывод
- •1.40.3.Блоковый ввод-вывод
- •Примеры решенных задач
- •2.4. Итерационные циклы
- •2.5. Вложенные циклы
- •2.6. Работа с функциями
- •2.6.1. Преобразование программы в функцию пользователя
- •2.6.2. Функция как обобщенное решение ряда частных задач
- •2.6.3. Параметры функции или глобальные переменные
- •2.6.4. Указатели в качестве параметров функций
- •2.7. Обработка одномерных массивов
- •2.7.1. Массивы ─ входные и выходные параметры функции
- •2.7.2. Ввод массивов
- •2.7.3. Вывод нескольких массивов в виде таблицы
- •2.7.4. Создание нового массива копированием положительных элементов из исходного массива
- •2.7.5. Значения наибольшего и наименьшего элементов массивов
- •2.8. Обработка двумерных массивов
- •2.8.1. Интерфейс функций, работающих с двумерными массивами.
- •2.8.2. Создание и уничтожение двумерного динамического массива
- •2.8.3. Примеры обработки двумерных массивов
- •2.9. Работа со строками
- •2.9.1. Пользовательские аналоги библиотечных функций
- •2.9.2. Копирование чисел, находящихся в строке, в числовой массив
- •2.9.3. Подсчет количества лексем в строке
- •2.9.4. Массивы строк
- •2.10. Указатели на функцию
- •2.10.1. Использование функции qsort
- •2.10.2. Табулирование произвольной функции одного переменного. Новое решение задачи табулирования
- •2.11. Работа со структурами
- •2.11.1. Структуры, поля которых содержат указатели
- •2.11.2. Работа с массивом структур.
- •2.12. Работа с файлами
- •2.12.1. Работа с текстовыми файлами
- •2.12.2. Работа с двоичными файлами
- •2.12.2.1. Вычисление суммы чисел, содержащихся в двоичном файле.
- •2.12.2.2. Чтение числа из заданной позиции двоичного файла
- •2.12.2.3.Замена всех отрицательных чисел двоичного файла нулями
- •Литература
Функция realloc
Прототип этой функции имеет следующий вид.
#include<stdlib.h> void* realloc(void* ptr, size_t size);
Функция изменяет размер блока памяти, на который установлен указатель ptr, до size байт. Содержимое блока в области памяти, меньшей из двух величин – старой и новой остается неизменным. Функция возвращает указатель на новое положение выделенного участка памяти, который может быть перемещен. При невозможности перераспределить память возвращает NULL. Если ptr равно NULL, рассматриваемая функция ведет себя подобно фукции malloc с аргументом size. Если size равно нулю, а указатель ptr не равен NULL, функция ведет себя подобно функции free(). После завершения работы с выделенной памятью ее следует освободить вызовом функции free().
Функция free
Прототип этой функции имеет следующий вид.
#include<stdlib.h
void free(void* ptr);
Функция освобождает динамическую память, на которую установлен указатель ptr. Если ptr == NULL, то функция ничего не делает. Если ptr не является указателем на динамическую память, то поведение функции не определено. Значение ему после выполнения функции не определенно, поэтому рекомендуется после ее вызова ptr присваивать значение NULL.
1.37.3. Указатели и квалификатор const
Квалификатор const может относиться к объекту, на который установлен указатель, или к самому указателю. Если в определении указателя квалификатор находиться слева от * то константным является объект, а если справа от * – константным будет указатель. В одном определении указателя можно написать два квалификатора const; один слева от символа *, а другой справа. Тогда константными будут как объект, так и указатель.
Пример 1. Указатель на константный объект
int n = 5; const int* pi = &n; // указатель на константный объект типа int
int const * pi = &n; // альтернативное определение // указателя на константный объект типа int
int m = *pi;
//*pi = 10; pi = &m;
Здесь pi – указатель на константный объект. В качестве константного объекта для этого указателя выступает переменная n. При компиляции закомментированной строки появляется сообщение об ошибке. Таким образом, записать новое значение в переменную n, используя указатель, невозможно. С другой стороны, вполне допустимо изменение самого указателя (см. последнюю строку приведенного выше кода).
Пример 2. Константный указатель на неконстантный объект
int n = 5; int* const pi = &n; int m = *pi; *pi = 10; //pi = &m;
Здесь pi – константный указатель на неконстантный объект. С объектом такой указатель работает как обычный указатель. Значение же адреса, которое получено указателем во время обязательной инициализации, изменено быть не может (см. закомментированную строку)
Пример 3. Константный указатель на константный объект.
int n = 5; const int* const pi = &n; //*pi = 20; int m = 10; //pi = &m;
Здесь pi – константный указатель на константный объект. Для такого указателя недопустимы операции изменения, как объекта, так и самого указателя (см. закомментированные строки).