- •Оглавление
- •1.2. Свойства языков программирования
- •1.3. Основные парадигмы программирования Процедурное программирование
- •Модульное программирование
- •Абстракция данных
- •Объектно-ориентированное программирование
- •Непечатные символы
- •Тема 2 Типы данных
- •2.1. Понятие переменной и объявление переменных
- •Объявление переменных
- •Встроенные типы данных
- •Размер памяти, выделяемой под встроенные типы данных
- •2.2. Константы и перечисления Константные переменные
- •Перечисления
- •2.3. Операции и выражения
- •Мультипликативные операции
- •Операции сравнения
- •Побитовые логические операции
- •Побитовые операции
- •Комментарии
- •Оператор while(пока)
- •Оператор do/while(выполнять/пока)
- •Оператор for(цикл)
- •Оператор множественного выбора switch
- •Операторы breakиcontinue
- •Тема 4 Массивы
- •4.1.Определение, объявление и инициализация массивов
- •Объявления и инициализация массивов в программе
- •4.2. Сортировка массивов Пузырьковая сортировка
- •Сортировка вставками
- •4.3. Поиск в массивах Линейный поиск
- •Двоичный поиск
- •4.4. Многомерные массивы
- •Тема 5 Указатели Объявления и инициализация переменных указателей
- •5.1. Операции над указателями
- •5.2. Выражения и арифметические действия с указателями
- •5.3. Взаимосвязи между указателями и массивами
- •5.4. Массивы указателей
- •5.5. Динамическое выделение памяти под массивы
- •Тема 6 Функции
- •6.2. Определения функций
- •Генерация случайных чисел
- •6.3. Классы памяти и область действия Классы памяти
- •Область действия
- •6.4. Рекурсия
- •6.5. Ссылки и ссылочные параметры
- •Вызов функций по ссылке с аргументами указателями
- •6.6. Использование спецификатораconstс указателями
- •6.7. Перегрузка функций
- •Аргументы по умолчанию
- •6.8. Передача массивов в функции
- •6.9. Указатель на функцию
- •6.10. Командная строка аргументов
- •6.11 Неопределенное количество аргументов
- •Тема 7 Введение в обработку строк
- •7.1. Работа со строками в с
- •Понятие символов и строк в с
- •Функции для работы со строками
- •Определение длины строки
- •Сложение двух строк (конкатенация)
- •Добавление к исходной строке указанного количества символов.
- •Копирование строки в другую строку
- •Сравнение строк
- •Получение строки от пользователя
- •Тема 8 Работа с файлами
- •Открытие файла
- •Чтение из файла символа или строки символов
- •Запись символа или строки символов в файл
- •Смещение внутри файла
- •Значения параметра fromwhereфункцииfseek
- •Закрытие файла
- •Тема 9 Компоновка программ и препроцессор
- •9.1. Компоновка программ
- •Проблема использования общих функций и имен
- •Использование включаемых файлов
- •9.2. Препроцессор
- •Определение макросов
- •Условная компиляция
- •Дополнительные директивы препроцессора
- •Тема 10 Структуры
- •10.1. Определение структур и доступ к элементам
- •Доступ к элементам структур
- •Использование структур
- •10.2. Битовые поля
- •10.3. Объединения
- •10.4. Построение связных списков на основе структур с самоадресацией
- •Создание простого связного списка
- •Очереди
- •Деревья
- •Список рекомендуемой литературы
10.2. Битовые поля
В структуре можно определить размеры атрибута с точностью до бита [10]. Традиционно структуры используются в системном программировании для описания регистров аппаратуры. В них каждый бит имеет свое значение. Не менее важной является возможность экономии памяти – так как минимальный тип атрибута структуры - это байт (char), который занимает 8 битов. До сих пор, несмотря на мегабайты и гигабайты оперативной памяти, используемые в современных компьютерах, существует немало задач, где каждый бит на счету.
Если после описания атрибута структуры поставить двоеточие и затем целое число, то это число задает количество битов, выделенных под данный атрибут структуры. Такие атрибуты называют битовыми полями. Структура на рис. 10.4 хранит в компактной форме дату и время дня с точностью до секунды.
struct TimeAndDate{
unsigned hours :5; // часы от 0 до 24
unsigned mins :6; // минуты от 0 до 60
unsigned secs :6; // секунды от 0 до 60
unsigned weekDay :3; // день недели
unsigned monthDay :6; // день месяца от 1 до 31
unsigned month :5; // месяц от 1 до 12
unsigned year :8; // год от 0 до 100
};
Рис. 10.4. Структура, хранящая дату и время
Одна структура TimeAndDateзанимает 8 байтов (один байт — 8 битов). Битовые поля используются в упакованном виде. Одно машинное слово чаще всего занимает 32 бита (4 байта). Битовая операция может выполняться параллельно над всеми битами слова.
Поля битов можно объявить только для целочисленных типов. Не допускается объявление массива битовых полей.
К полям битов не применима операция взятия адреса &.
10.3. Объединения
Особым видом структур данных является объединение [11] (рис. 10.5). Определение объединения напоминает определение структуры, только вместо ключевого слова structиспользуетсяunion:
union number {
short sx;
long lx;
double dx;
};
Рис. 10.5. Объявление объединения в программе
В отличие от структуры, все атрибуты объединения располагаются по одному адресу. Под объединение выделяется столько памяти, сколько нужно для хранения наибольшего атрибута объединения. Объединения применяются в тех случаях, когда в один момент времени используется только один атрибут объединения и, прежде всего, для экономии памяти. Предположим, что нужно определить структуру, которая хранит "универсальное" число, т.е. число одного из предопределенных типов, и признак типа. Это можно сделать так, как показано на рис. 10.6:
struct Value {
enum NumberType { ShortType, LongType,doubleType };
NumberType type;
short sx; // если type равен ShortType
long lx; // если type равен LongType
double dx; // если type равен DoubleType
};
Рис. 10.6. Объявление структуры для хранения числа любого типа
Атрибут typeсодержит тип хранимого числа, а соответствующий атрибут структуры – значение числа. На рис. 10.7 приведен пример использования этой структуры
Value shortVal;
shortVal.type = Value::ShortType;
shortVal.sx = 15;
Рис. 10.7. Использование структуры для хранения числа любого типа
Хотя память выделяется под все три атрибута sx,lxиdx, реально используется только один из них. Сэкономить память можно, используя объединение (см. рис. 10.8.).
#include <iostream>
using namespace std;
struct Value
{
enum NumberType { ShortType, LongType, DoubleType };
NumberType type;
union number
{
short sx; // если type равен ShortType
long lx; // если type равен LongType
double dx; // если type равен DoubleType
} val;
};
main()
{
Value shortVal;
shortVal.type = Value::ShortType;
shortVal.val.sx= 127000000;
cout<<shortVal.type<<endl;
cout<<shortVal.val.sx<<endl;
return 0;
}
Рис. 10.8. Использование объединения для универсального типа данных
Теперь память выделена только для максимального из этих трех атрибутов (в данном случае dx). Однако и обращаться собъединениемследует осторожно. Поскольку все три атрибута делят одну и ту же область памяти, изменение одного из них означает изменение всех остальных. На рис. 10.9 поясняется выделение памяти подобъединение. В обоих случаях предполагается, чтоструктурарасположена поадресу1000.Объединениерасполагает все три своих атрибута по одному и тому жеадресу.
Рис. 10.9. Выделение памяти под структуру и объединение
Задача. Написать программу, которая позволит увидеть, как хранится в битах число типаfloat.
#include <iostream>
#include <stdlib.h>
using namespace std;
union View
{
float b;
int a;
};
int main()
{
View v;
cout<<"Enter a number:\n";
cin>>v.b;
char str[40];
itoa(v.a, str, 2);
cout<<str<<endl;
cout<<v.a<<endl;
return 0;
}
Рис. 10.10. Просмотр содержимого памяти переменной типа float
Enter a number:
3.14
1000000010010001111010111000011
1078523331
Рис. 10.11. Результат работы программы на рис. 10.10