- •Ю.А Петров Программирование на языке высокого уровня
- •Часть 1
- •Введение
- •Задание
- •Комментарии
- •Идентификаторы
- •Ключевые слова
- •Константы
- •Управляющие последовательности
- •Строковые литералы
- •Константные выражения
- •Пунктуаторы
- •Операции
- •Задание на лабораторную работу 2 разработка программы линейной структуры Цель работы
- •Отчет по лабораторной работе должен содержать:
- •Задание
- •Замечания
- •Варианты заданий
- •Классификация ошибок
- •Ошибки, не обнаруженные компилятором
- •Ситуации, возникающие при неверных результатах
- •Отладка программы
- •Предупреждения
- •Первое сообщение об ошибке
- •Использование команд Find и Replace
- •Быстрое обнаружение ошибочных строк
- •Продолжение отладки
- •Использование встроенного отладчика
- •Разница между командами Step Into и Step Over
- •Дополнительные средства отладки
- •Работа с точками останова
- •Краткая характеристика объектов
- •Формат 1:
- •Стиль программирования
- •Задание на лабораторную работу 4 объекты и их характеристики Цель работы
- •В отчете по лабораторной работе следует представить:
- •5 Структурное программирование
- •Пример1
- •Пример 2
- •Задание на лабораторную работу 5 разработка программы со структурой «развилка» Цель работы
- •Задание:
- •Варианты задания
- •Задание на лабораторную работу 6 создание цикловых программ с фиксированным числом повторений Цель работы
- •Задание
- •Варианты задания
- •Задание на лабораторную работу 7 создание программ с итерационными циклами Цель работы
- •Задание
- •Варианты задания
- •Пояснения к выполнению лабораторной работы 7
- •6 Агрегаты данных
- •Структура
- •Объединения
- •Перечисления
- •Int array[3]; // Объявление определения;
- •Многомерные массивы
- •Вывод в файловый поток
- •Чтение из входного файлового потока
- •Чтение целой строки файлового ввода
- •Определение конца файла
- •Проверка ошибок при выполнении файловых операций
- •Закрытие файла
- •Управление открытием файла
- •Выполнение операций чтения и записи
- •Задание на ргз 1 использование структур данных при решении задач Цель работы
- •Задание
- •Варианты задания
- •7 Модульное программирование
- •Задание на ргз 2 использование модульного программирования при решении задач
- •Перемещаемые панели инструментов
- •Меню File
- •Меню Edit
- •Меню View
- •Меню Insert
- •Меню Project
- •Меню Build
- •Меню Tools
- •Меню Window
- •Список открытых окон
- •Меню Help
- •Приложение 2 Некоторые функции языка с
- •Используемая литература
- •Оглавление
- •5 Структурное программирование 53
6 Агрегаты данных
В алгоритмическом языке С/С++ имеется возможность создавать следующие типы данных пользователя: структуры, объединения, перечисления, массивы, классы (рис. 6.1).
Структура
Структура – это тип данных, представляющий собой определяемый пользователем набор именованных членов (компонентов). Эти компоненты могут быть любых типов, как встроенных (например, int, char, long, float, double и т.д.), так и созданных пользователем, записанные в любой последовательности. Кроме того, компонента структуры может иметь тип битового поля. Тип структуры в языке С/C++ позволяет обрабатывать сложные структуры данных так же легко, как и простые переменные.
Структуры объявляются при помощи ключевого слова struct. Например:
struct mystruct { ... }; // mystruct – это тег структуры, т.е. имя типа,
// созданного пользователем.
Тогда объект с типом данной структуры будет создан объявлением
struct mystruct s, *ps, arrs[10]; /* s имеет тип структуры mystruct;
ps это указатель на тип struct mystruct,
arrs – это массив из 10 стpуктуp типа mystruct */
Если тег структуры опущен, то имеется безтеговая структура. Такую структуру можно использовать для объявления идентификаторов в разделяемом запятыми списке идентификаторов структуры как имеющих данный тип структуры, но нельзя объявлять объекты этого типа где-нибудь еще. Например:
struct { ...} s, *ps, arrs[10]; // безтеговая структура
При объявлении структуры с тегом или без него, можно использовать ключевое слово typedef. Например:
typedef struct { ... } MYSTRUCT;
MYSTRUCT s, *ps, arrs[10]; // то же, что и struct mystruct s и т.д.
typedef struct { ... } YRSTRUCT;
YRSTRUCT y, *yp, arry[20];
Список объявления компонентов в фигурных скобках объявляет типы и имена компонентов структуры. Компоненты структуры могут быть любого типа, за двумя исключениями:
Первое исключение – тип компонента не может быть тот же, что и объявляемая в текущий момент структура, например:
struct mystruct { mystruct s } s1, s2; // так нельзя
Тем не менее, тег структуры может быть указателем на объявляемую структуру. Например:
struct mystruct { mystruct *ps } s1, s2; // так можно
Кроме того, структура может содержать ранее объявленные типы структур (в языке С++ можно опускать ключевое слово struct).
Второе исключение – компонент структуры нигде не может иметь тип "функция, возвращающая ...", кроме языка С++, но тип "указатель на функцию, возвращающую ..." допустим. В языке С++ ключевое слово struct может иметь компоненты-функции.
Доступ к компонентам структур и объединений выполняется операторами выбора (.) и (->). Операция (.) называется прямым выбором компонента структуры; операция (->) называется косвенным выбором компонента (или указателем) структуры. Например:
struct mystruct
{
int i;
char str[21];
double d;
} s, *sptr=&s;
...
s.i = 3; // присвоение члену i структуры mystruct s;
sptr->d = 1.23; // присвоение компоненту d структуры mystruct s;
Если структура B содержит поле, тип которого есть структура A, то доступ к компонентам A выполняется через два одновременно задаваемых выбора компонента структуры. Например:
struct A
{
int j;
double x;
};
struct B
{
int i;
struct A a;
double d;
} s, *sptr;
...
s.i = 3; // присвоение компоненту i структуры B
s.a.j = 2; // присвоение компоненту j структуры A
sptr->d = 1.23; // присвоение компоненту d структуры B
(sptr->).x = 3.14 // присвоение компоненту x структуры A
Каждое объявление структуры вводит уникальный тип, поэтому в структуре:
struct A
{
int i,j;
double d;
} a, a1;
struct B
{
int i,j;
double d;
} b;
объекты a и a1 оба имеют тип struct A, но объекты a и b имеют различные типы структуры.
Структурам могут присваиваться значения только в том случае, если и исходная структура, и структура назначения имеют один и тот же тип. Например:
a = a1; // так можно; тип один и тот же, поэтому может быть
// выполнено покомпонентное присвоение структур;
a = b; // так нельзя; различные типы;
a.1 = b.1; a.j = b.j; a.d = b.d; // такое присваивание на
// уровне компонентов структуры можно выполнять;
Память распределяется в структуре покомпонентно, слева направо, от младшего к старшему адресу памяти. В следующем примере:
struct mystruct {
int i;
char str[21];
double d;
} s;
объект s занимает достаточное количество памяти для размещения целочисленного значения типа int, 21-байтовой строки и 8-байтового значения типа double.
Имена тегов структур разделяют общее пространство имен с тегами объединений и перечислений (однако в языке С++ имена входящих в структуру перечислений находятся в другом адресном пространстве). Это означает, что в пределах одного контекста такие теги должны иметь уникальные имена. Тем не менее, имена тегов не обязаны отличаться от идентификаторов, находящихся в трех других адресных пространствах: пространстве имен меток, пространстве имен компонентов и едином адресном пространстве.
Имена компонентов в пределах данной структуры или объединения обязаны быть уникальными, но среди разных структур или объединений они могут совпадать. Например:
goto s;
...
s: struct s { // так можно; теги и имена меток находятся в разных адресных пространствах;
int s // так можно; теги, имена меток и имена компонентов находятся в разных адресных пространствах;
float s; // так нельзя: повторение имени компонентов структур;
} s; /* так можно; пространства имен переменных различны. В языке С++ это допустимо только если s не имеет конструктора */
union s { // так нельзя: повторение имен в пространстве тегов;
int s; // так можно: новое пространство компонентов;
float f;
} f; // так можно: пространство имен переменных;
struct t {
int s; // так можно: следующее пространство имен компонентов;
...
} s; // так нельзя: повторение имен переменных
Указатель на структуру типа А допустим в объявлении другой структуры В до объявления структуры А. Например:
struct A; // неполное объявление;
struct B { struct A *pa };
struct A { struct B *pb };
Первое объявление А называется неполным, поскольку в этой точке отсутствует определение А. В данной ситуации неполное объявление допустимо, поскольку в объявлении В размер А необязателен.
Структура может содержать любые комбинации битовых полей с данными других типов.
Целочисленные компоненты типа signed или unsigned можно объявить битовыми полями шириной от 1 до 16 бит. Ширина битового поля и его опциональный идентификатор задаются следующим образом:
Спецификатор_типа <идентификатор-битового поля>:ширина;
где спецификатор_типа это char, unsigned char, int или unsigned int. Битовые поля располагаются, начиная с младшего и кончая старшим битом слова. Выражение "ширина" должно быть задано и должно давать целочисленную константу со значением в диапазоне от 1 до 16.
Если идентификатор битового поля опущен, то число битов, заданное выражением "ширина", распределяется в памяти, но поле при этом остается недоступным программе. Это позволяет создавать битовые шаблоны для, например, аппаратных регистров компьютера, в которых некоторые биты не используются. Например, структура
struct mystruct {
int i:2;
unsigned j:5;
int :4;
int k:1;
unsigned m:4;
} a, b, c;
создает следующее распределение памяти:
Для битового поля типа int (например, signed) старший бит интерпретируется как знаковый бит. Битовое поле шириной 2, содержащее двоичное 11, будет, следовательно, в случае типа unsigned интерпретироваться как 3, а в случае int как -1. В данном примере выражение a.i = 6 поместит в a.i двоичное 10 = -0, не выдавая каких-либо предупреждений. Поле k типа signed int шириной 1 может содержать только значения 1 и 0, так как битовый шаблон 1 будет интерпретирован как «минус» (-).
Примечание: Битовые поля могут быть объявлены только в структурах, объединениях и классах. Доступ к ним выполняется тем же способом выбоpа компонентов (.) и (->), что и для небитовых компонентов. Битовые поля вызывают некоторые проблемы, когда записывается переносимый код, поскольку организация битов в байтах и байтов в словах зависит от конкретной машины. Выражение &mystruct.x недопустимо, так как x – это идентификатор битового поля, и никакой гарантии, что mystruct.x имеет адрес на границе байта, нет.