- •Основы алгоритмизации и программирования, язык Си
- •Введение
- •Блок-схема алгоритма Общие требования к блок-схеме алгоритма
- •Линейные и разветвляющиеся процессы
- •Циклические процессы
- •Итерационные процессы
- •Комментарии
- •Типы данных
- •Данные целого типа
- •Данные вещественного типа
- •Модификатор const
- •Переменные перечисляемого типа
- •Константы
- •Описание переменных
- •Локальные переменные
- •Операции и выражения
- •Операция присваивания
- •Арифметические операции
- •Операции поразрядной арифметики
- •Логические операции
- •Операции отношения
- •Инкрементные и декрементные операции
- •Операция sizeof
- •Порядок выполнения операций
- •Приоритет операций
- •Преобразование типов
- •Операция приведения
- •Операция запятая
- •Ввод и вывод информации
- •Директивы препроцессора Директива #include
- •Директива #define
- •Понятие пустого и составного операторов
- •Условные операторы
- •Операторы организации цикла
- •Оператор цикла for
- •Оператор цикла while
- •Оператор цикла do … while
- •Вложенные циклы
- •Операторы перехода (break, continue, return, goto)
- •Примеры программ
- •Массивы Одномерные массивы
- •Примеры программ
- •Многомерные массивы (матрицы)
- •Примеры программ
- •Указатели Понятие указателя
- •Описание указателей
- •Операции с указателями
- •Связь между указателями и массивами
- •Массивы указателей
- •Многоуровневые указатели
- •Примеры программ
- •Символьные строки
- •Ввод/вывод строк.
- •Функции работы со строками.
- •Примеры программ
- •Функции
- •Прототип функции.
- •Определение функции.
- •Параметры функции
- •Параметры по умолчанию
- •Передача массива в функцию
- •Inline функции
- •Класс памяти
- •Автоматические переменные
- •Статические переменные
- •Регистровые переменные
- •Блочная структура
- •Примеры программ
- •Указатели на функции
- •Примеры программ
- •Рекурсия
- •Примеры программ
- •Аргументы в командной строке
- •Функции с переменным числом параметров
- •Примеры программ
- •Сортировка
- •Пузырьковая сортировка.
- •Шейкер сортировка
- •Сортировка вставкой
- •Сортировка выбором
- •Метод Шелла
- •Метод Хора
- •Структуры
- •Доступ к элементам структуры
- •Инициализация структур
- •Указатели на структуры.
- •Структуры и функции
- •Примеры программ
- •Поля бит
- •Объединения
- •Переменные с изменяемой структурой
- •Примеры программ
- •Организация списков и их обработка
- •Операции со списками при связном хранении
- •Построение обратной польской записи
- •Односвязный линейный список, очередь
- •Двусвязный линейный список
- •Циклический список, кольцо
- •Двусвязный циклический список
- •Примеры программ
- •Деревья
- •Потоки и файлы
- •Файлы Основные сведения о файловой системе
- •Организация посимвольного ввода и вывода
- •Определение конца файла feof()
- •Организация ввода и вывода строк
- •Удаление файлов
- •Дозапись потока
- •Позиционирование в файле
- •Текстовые и двоичные файлы
- •Функции fread() и fwrite()
- •Примеры программ
- •Хеширование
- •Схемы хеширования
- •Метод открытой адресации с линейным опробыванием
- •Метод цепочек
- •Машинное представление графов
- •Примеры программ
- •Литература
Поля бит
Существует несколько разновидностей структур. Одна из них - это поля бит. Поле представляет собой последовательность соседних двоичных разрядов (бит) внутри одного целого значения. Каждое поле может иметь тип unsigned int или signed int и размещается в машинном слове целиком, а вся группа полей может выходить за пределы машинного слова. Поле бит – особый тип структуры определяющий какую длину имеет каждый ее элемент. Общий вид объявления полей бит имеет вид:
struct имя стуктуры
{ тип имя 1: длина;
. . .
тип имя n : длина;
};
Наиболее распространенный подход к использованию полей можно показать на примере объявления следующей структуры:
struct pole
{ int p1:1;
unsigned p2:2;
int:6;
int p3:4;
} pl;
Объявление такого вида обеспечивает размещение стуктуры (полей бит) в памяти следующим образом. В полях типа signed крайний левый бит является знаковым. Таким образом, поле signed int p:1 может быть использовано для хранения значений -1 и 0, так как любое не нулевое значение поля p будет интерпретироваться как -1. Поле signed int p:2, в отличие от int p:1, может принимать три значения -1,0,1. В объявлении структуры имеется еще два поля (int:6; int p3:4). Первое указывает, что структура содержит 6 неиспользуемых бит, второе предназначено для чисел в диапазоне от –7 до 7.
В Borland С самый левый бит является знаковым. Поля могут не иметь имени; с помощью безымянного поля (задаваемого только двоеточием и шириной) организуется пропуск требуемого количества разрядов. Ширина равная нулю, используется тогда когда необходимо выйти на границу следующего слова.
Все особенности, связанные с использованием полей, например: может ли поле байт перейти границу слова, зависят от аппаратной реализации.
При определенном удобстве работа с полями может повлечь некоторые трудности. Они связаны, например, с тем, что на одних машинах поля размещаются слева направо, на других - справа налево. Это в свою очередь влечет некоторые трудности при перенесении программ. Поля не могут быть массивами и не имеют адресов и, следовательно, операция & к ним не применима.
Объединения
Объединение представляет собой структурированную переменную с несколько иным способом размещения элементов в памяти. Главной их особенностью является, то, что для каждого из объявленных элементов выделяется одна и та же область памяти, то есть они перекрываются. Размерность ее определяется максимальной размерностью элемента объединения. Таким образом, при использовании объединений появляется возможность работы с данными различных типов и размеров в одной и той же области памяти. Хотя доступ к этой области памяти возможен с использованием любого из элементов, элемент для этой цели должен выбираться так, чтобы полученный результат не был бессмысленным.
Формат объявления объединения имеет следующий вид:
union { описание элемента 1;
...
описание элемента n; };
Спецификация доступа к элементам объединения, как и у полей бит, полностью соответствует тому, как это осуществляется у обычных структур:
имя_объединения . имя поля объединения;
или при работе с указателями:
имя_указателя _на_объединение-> имя_поля_объединения;
Рассмотрим пример объявления и некоторых вариантов использования объединения:
union un_type
{ int i; // пример объявления
double d; // шаблона объединения
char c;
};
un_type un; // переменная типа объединения
un_type un_mas[6]; // массив из шести элементов
un_type *pt; // указатель на переменную типа un_type
Первое описание приводит к выделению памяти под одну переменную un. При этом компилятор выделяет достаточно памяти для размещения max из переменных описанных в шаблоне un_type, т.е. 8 байт (тип double). Для массива un_mas[6] выделяется 6х8 байт памяти. Механизм использования объединения может быть рассмотрен на следующем примере:
un.i=14; // 14 записывается в переменную un; исп-ся 2 байта
un.d=3.4; // 14 стирается, 3.4 записывается; исп-ся 8 байтов
un.c=‘k’; // 3,4 стирается, записывается k; используется 1 байт
В каждый момент времени запоминается только одно значение; нельзя записать char и int одновременно в одно объединение даже, если для этого достаточно памяти. Приведенный ниже фрагмент демонстрирует ошибочное использование полей объединения:
un.d=2.4;
un.i=14;
f=5.2*un.d; // ошибка
Ошибка заключается в том, что в момент использования un.d его значение 2.4 затерто оператором un.i=14;
Как отмечалось выше, с объединениями можно использовать операцию -> аналогично, как это делалось со структурами.
pt=&un;
f=pt->d; // аналогично f=un.d
Объединение может быть использовано не только для экономии памяти. Если записать в один элемент объединения некоторое значение, то через другой элемент это же значение можно прочитать уже в другой форме представления Таким образом форму представления данных в памяти можно менять совершенно свободно.