
- •Часть 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.Замена всех отрицательных чисел двоичного файла нулями
- •Литература
1.39. Работа со структурами
Структура в языке Си – совокупность логически связанных величин, объединенных одним именем. Компоненты структуры обычно называют полями.
Структуры от массивов отличаются в следующих отношениях:
• отсутствует упорядоченность между компонентами,
• в отличие от массивов компоненты структуры могут иметь разный тип.
• другой способ обращения к компонентам; к компонентам структуры следует обращаться по имени их полей (а не индексу как это имеет место в случае массивов).
В языке Си под этим термином наряду со структурой как типом данных понимают переменную, имеющую тип структуры. Для устранения этой неоднозначности переменную, имеющую тип структуры иногда называют записью.
1.39.1. Объявление структур
Общий формат, позволяющий наряду с типом объявлять и переменные, имеет следующий вид:
struct[<>] {
<> }[γ];
Здесь struct – ключевое слово языка Си, α − необязательный элемент, называемый тегом, − список объявлений полей, γ − список переменных, имеющих тип объявляемой структуры.
Элементы объявления α и γ могут отсутствовать. Список γ подчиняется синтаксису обычных переменных. Инициализация полей во время их объявления недопустима. Переменные, включенные в этот список, могут использоваться только в составе структурной переменной. Определение такого формата выполняет две функции:
• объявляет структуру как тип данных.
• определяет переменные, имеющие этот тип.
Рассмотрим ряд примеров.
Пример 1. Совместное определение типа и переменных
#define MLEN 81
struct person_salary
{
char fio[MLEN];
double salary;
} employee, worker;
Здесь person_salary – тег; fio и salary – поля структуры; employee и worker – переменные, имеющие тип объявленной структуры.
В программе, написанной на языке Си, роль имени типа выполняет конструкция, состоящая из ключевого слова struct и тега (см. ниже).
Пример 2. Раздельное определение типа и переменных
#define MLEN 81
struct person_salary
{
char fio[MLEN];
double salary;
};
//…
struct person_salary employee, worker;
Пример 3. Компонент тег можно опускать
#define MLEN 81
struct
{
char fio[MLEN];
double salary;
} employee, worker;
В этом примере определен так называемый анонимный тип. У этого типа нет тега. Поэтому на него нельзя ссылаться в другом программном коде. Польза от этого кода в определённых здесь двух переменных employee и worker.
Пример 4. Определение типа, переменной и указателя на структуру.
#define MLEN 81
struct person_salary
{
char fio[MLEN];
double salary;
};
//…
struct person_salary employee;
struct person_salary* p = &employee;
Здесь дополнительно объявлен и инициализирован указатель на структуру типа struct person_salary.
1.39.2. Определение структуры в многомодульной программе
Определение типа структуры в многомодульной программе следует размещать в заголовочном файле модуля. При этом следует предусматривать защиту от повторного включения заголовочного файла. В противном случае может возникнуть сообщение об ошибке времени компиляции.
1.39.3. Инициализация структур
Структура может быть инициализирована во время своего определения. Ограничимся примером.
//Файл my_structs.h
#define MLEN 81
struct person_salary
{
char fio[MLEN];
double salary;
};
//Файл main.c
#include “my_structs.h”
int main(void)
{
struct person_salary new_person = {
“Ivanov I.I”,
25000
};
// …
}