
- •Основы алгоритмизации и программирования, язык Си
- •Введение
- •Блок-схема алгоритма Общие требования к блок-схеме алгоритма
- •Линейные и разветвляющиеся процессы
- •Циклические процессы
- •Итерационные процессы
- •Комментарии
- •Типы данных
- •Данные целого типа
- •Данные вещественного типа
- •Модификатор const
- •Переменные перечисляемого типа
- •Константы
- •Описание переменных
- •Локальные переменные
- •Операции и выражения
- •Операция присваивания
- •Арифметические операции
- •Операции поразрядной арифметики
- •Логические операции
- •Операции отношения
- •Инкрементные и декрементные операции
- •Операция sizeof
- •Порядок выполнения операций
- •Приоритет операций
- •Преобразование типов
- •Операция приведения
- •Операция запятая
- •Ввод и вывод информации
- •Директивы препроцессора Директива #include
- •Директива #define
- •Понятие пустого и составного операторов
- •Условные операторы
- •Операторы организации цикла
- •Оператор цикла for
- •Оператор цикла while
- •Оператор цикла do … while
- •Вложенные циклы
- •Операторы перехода (break, continue, return, goto)
- •Примеры программ
- •Массивы Одномерные массивы
- •Примеры программ
- •Многомерные массивы (матрицы)
- •Примеры программ
- •Указатели Понятие указателя
- •Описание указателей
- •Операции с указателями
- •Связь между указателями и массивами
- •Массивы указателей
- •Многоуровневые указатели
- •Примеры программ
- •Символьные строки
- •Ввод/вывод строк.
- •Функции работы со строками.
- •Примеры программ
- •Функции
- •Прототип функции.
- •Определение функции.
- •Параметры функции
- •Параметры по умолчанию
- •Передача массива в функцию
- •Inline функции
- •Класс памяти
- •Автоматические переменные
- •Статические переменные
- •Регистровые переменные
- •Блочная структура
- •Примеры программ
- •Указатели на функции
- •Примеры программ
- •Рекурсия
- •Примеры программ
- •Аргументы в командной строке
- •Функции с переменным числом параметров
- •Примеры программ
- •Сортировка
- •Пузырьковая сортировка.
- •Шейкер сортировка
- •Сортировка вставкой
- •Сортировка выбором
- •Метод Шелла
- •Метод Хора
- •Структуры
- •Доступ к элементам структуры
- •Инициализация структур
- •Указатели на структуры.
- •Структуры и функции
- •Примеры программ
- •Поля бит
- •Объединения
- •Переменные с изменяемой структурой
- •Примеры программ
- •Организация списков и их обработка
- •Операции со списками при связном хранении
- •Построение обратной польской записи
- •Односвязный линейный список, очередь
- •Двусвязный линейный список
- •Циклический список, кольцо
- •Двусвязный циклический список
- •Примеры программ
- •Деревья
- •Потоки и файлы
- •Файлы Основные сведения о файловой системе
- •Организация посимвольного ввода и вывода
- •Определение конца файла feof()
- •Организация ввода и вывода строк
- •Удаление файлов
- •Дозапись потока
- •Позиционирование в файле
- •Текстовые и двоичные файлы
- •Функции fread() и fwrite()
- •Примеры программ
- •Хеширование
- •Схемы хеширования
- •Метод открытой адресации с линейным опробыванием
- •Метод цепочек
- •Машинное представление графов
- •Примеры программ
- •Литература
Доступ к элементам структуры
Доступ к полям структуры осуществляется с помощью оператора «точка» - при непосредственной работе со структурой и «->» - при использовании указателей на структуру. Возможны три вида спецификации доступа к элементам структуры:
имя_переменной_структуры . имя_поля;
имя_указателя_на_структуру -> имя_поля;
(*имя_указателя_на_структуру) . имя_поля;
Например:
struct str
{ int i;
float j;
} st1, st2[3],*st3,*st4[5];
а) Прямой доступ к элементу
st1.i=12; // используется операция « . »
st2[1].j= .52;
б) Доступ по указателю.
st3->i=12; // используется операция « -> »
(st4+1)->j=1.23;
(*st3).j=23; // используется операция « * »
*(st4[2]).i=123;
*st3.j=23; // ошибка, « . » имеет больший приоритет чем « * »
Можно определить указатель на элементы имеющие тип структуры и проинициализировать его. Например:
st3=&st1;
st3->i=5; // аналогично (*st3).i=5
Объявление структуры в качестве одного из полей не может содержать переменные своего типа, т.е. неверным будет следующее объявление шаблона:
struct str
{ char pole_1;
double pole_2;
str pole_3; // ошибка
};
Однако в объявлении структуры могут включаться элементы, являющиеся указателями на эту же структуру, например:
struct str
{ char pole_1;
double pole_2;
str *pole_3; // верно
};
Инициализация структур
Ранее мы уже рассматривали процедуру инициализации переменных и массивов. Как и обычные переменные, элементы, входящие в состав структуры (определяющие структурную переменную), могут быть инициализированы. При этом можно инициализировать, как все элементы, определяющие структурную переменную при ее декларировании:
struct st
{ char c;
int i1,i2;
};
struct st a={‘a’,105,25};
так и некоторые из них в процессе работы с ними:
a.c=‘a’;
a.i2=25;
При выполнении инициализации структурных переменных необходимо следовать некоторым правилам:
- присваиваемые значения должны совпадать по типу с соответствующими полями структуры;
- можно объявлять меньшее количество присваиваемых значений, чем количество полей. В этом случае остальным полям структуры будут присвоены нулевые значения;
- список инициализации последовательно присваивает значения полям структуры вложенных структур и массивов.
Например:
struct comp
{ char nazv[20];
float speed;
int cena;
} cp[3]={ {“Celeron”,0.6,525},
{“Duron”,1.0,547},
{“Atlon”,1.4,610}
};
Так же как и массив, структура может быть введена поэлементно. Например, для описанной выше структуры st
gets(a.c);
scanf(”% d % f”, &a.i1, &a.i2);
Как отмечалось выше, структуры могут быть вложены дуг в друга:
struct FIO
{ char F[15], I[10], O[12];
} person;
struct rab
{ struct FIO fio;
int tab;
float zarpl;
} rb;
Структура rab содержит структуру FIO. Доступ к элементам структуры FIO и rab осуществляется следующим образом:
person. F=''Петров'';
person.I ='' '';
rb.fio.O= "Иванович'';
Единственно возможные операции над структурами - это их копирование, присваивание, взятие адреса с помощью & и осуществление доступа к ее элементам (полям). Следует отметить, что оператор присваивания выполняет то, что называется поверхностной копией в применении к структурам-переменным. Поверхностная копия представляет собой копирование бит за битом значений полей переменной-источника в соответствующие поля переменной-приемника. При этом может возникнуть проблема с такими полями, как указатели, поэтому использовать поверхностное копирование структур надо осторожно.
Копирование всех полей одной структуры в другую может быть выполнено как поэлементно, так и целиком, как это показано ниже:
#include <stdio.h>
struct book
{ char avt[10];
int izd;
} st1,st2;
void main(void)
{ gets(st1.avt); // ввод структуры st1
scanf("%d",&st1.izd);
st2=st1; // копия всех полей структуры st1 в st2
}
Необходимо отметить, что копирование структур (st2=st1) допустимо, только если st1 и st2 являются структурными переменными соответствующими одному структурному типу.
Структуры нельзя сравнивать, то есть выражение if(st1==st2) неверно. Сравнение структур требуется выполнять поэлементно.
Если данные, объединенные в структуры, должны содержать информацию не об одном объекте, а о некотором их множестве, например, каталог библиотеки, телефонный справочник и т.д., то удобно использовать массивы структур.