- •Массивы структур
- •Структуры – параметры функций
- •Если обработка структуры в функции связана с изменением содержимого полей, то такую структуру необходимо передавать по указателю или по ссылке. Доступ к отдельному биту
- •Структуры
- •9.1.1. Объявление и инициализация структур
- •Структуры – параметры функций
- •9.1.3.Функции, возвращающие структуры
- •9.2. Перечисления
- •9.3. Объединения
Структуры в С++
Структура-это совокупность логически связанных переменных, возможно, различных типов, сгруппированных под одним именем для удобства дальнейшей обработки.
Например, структура может содержать несколько переменных типа int и несколько переменных типа char. Переменные, которые содержаться в структуре называются членами или полями структуры.
Структуры в С++ используются для логического и физического объединения данных произвольных типов, так же как массивы служат для группирования данных одного типа.
Структуры можно определять с помощью ключевого слова struct.
Пример описания структуры:
struct student { char name[50]; int kurs; int age; }; Мы определили структуру в которую входят переменные kurs, age и массив name. В этом описании student является шаблоном структуры, struct student является типом данных. После описания структуры нужно ставить точку с запятой. Чтобы использовать структуру необходимо объявить переменные типа struct student.
Например,
struct student s1, s2;
Переменные s1 и s2 являются переменными типа struct student. Компилятор автоматически выделит память под эти переменные. Под каждую из переменных типа структуры выделяется непрерывный участок памяти.
Для получения доступа к полям структуры используется операция точка. Например,
strcpy(s1.name, "Бардин Павел"); s1.kurs=3; s1.age=20;
В языке С есть возможность объявлять переменные структуры при описании структуры:
struct student { char name[50]; int kurs; int age; } s1, s2;
Переменные s1 и s2 являются переменными типа struct student.
Более того, в объявлении шаблона структуры можно опустить имя шаблона:
struct { char name[50]; int kurs; int age; } s1, s2;
Однако если данная структура должна выступить в качестве параметра какой-либо функции, то и в заголовке этой функции и в ее прототипе без имени шаблона не обойтись.
Элементами или полями структуры могут быть переменные, массивы, ранее определенные структуры. Функции не могут быть полями структуры (В языке Си). В языке С++ функции могут быть полями структуры и такие структуры называются классами. Они определяются с помощью ключевого слова class.
Для переменных s1 и s2 возможно присваивание (s1=s2) так как эти переменные созданы на базе одного шаблона. После такого присваивания поля структуры s1 будут содержать ту же информацию, что и поля s2. Если мы опишем две структуры с одними и теми же полями, но первая структура будет иметь шаблон student1, а вторая student2, то присваивание s1=s2 недопустимо.
Пример программы.
#include <stdio.h> // определение структуры struct student { char name[30]; int kurs; int age; }; void main() { // объявление переменных stud1 и stud2 типа struct student struct student stud1, stud2; printf("Введите имя:"); // ввод имени gets(stud1.name); printf("Введите возраст:"); // ввод возраста scanf("%d", &stud1.age); printf("Введите номер курса:");
// ввод номера курса scanf("%d", &stud1.kurs); // присваивание stud2=stud1 возможно, так как один и тот же шаблон stud2=stud1; // Вывод printf("Студент %sn", stud2.name); printf("Курс %dn", stud2.kurs); printf("Возраст %dn", stud2.age); }
Заметьте, что когда мы делаем вызов scanf("%d", &stud1.age); и scanf("%d", &stud1.kurs); мы ставим знак & перед именем структуры, а не перед именем поля (элемента структуры).
Массивы структур
Структуры могут быть объединены в массивы структур. Объявление массива структур делается аналогично объявлению массива переменных. Например, если нужно хранить информацию о 10 студентах, то объявление массива будет следующим
struct student stud1[10];
Здесь stud1 - имя массива структур, а stud1[0] - это первая структура, stud1[1] - вторая... stud1[9] - десятая структура. Чтобы получить доступ к полю age пятой структуры нужно написать
stud1[4].age
Чтобы получить доступ к полю kurs первой структуры нужно написать
stud1[0].kurs
Пример программы.
#include <stdio.h> struct student // определение структуры { char name[30]; int kurs; int age; }; void main() { struct student stud[10]; // объявление массива на 10 структур int i, n; printf("Количество студентов:"); scanf("%d", &n); // ввод n (число студентов) for(i=0;i<n;i++) { printf("Введите имя:"); scanf("%s", stud[i].name); // ввод имени printf("Введите возраст:"); scanf("%d", &stud[i].age); // ввод возраста printf("Введите номер курса:");
scanf("%d", &stud[i].kurs); // ввод номера курса } // Вывод for(i=0;i<n;i++) { printf("Студент %sn", stud[i].name); printf("Курс %dn", stud[i].kurs); printf("Возраст %dn", stud[i].age); } }
Структуры – параметры функций
Если функция не изменяет структуру, то такую структуру можно передать по значению.
Если обработка структуры в функции связана с изменением содержимого полей, то такую структуру необходимо передавать по указателю или по ссылке. Доступ к отдельному биту
Если некоторые поля структуры принимают только два значения т.е. используются как флаги, то очень удобно пользоваться полями битов. Поля битов это специальный тип членов структуры, в котором определено, из скольких бит состоит каждый элемент.
Основная форма объявления структуры с битовыми полями:
struct имя_структуры { тип имя1: длина_в_битах; тип имя2: длина_в_битах; ... тип имяN: длина_в_битах; }
Здесь тип может быть int, unsigned или signed.
Длина такой структуры всегда кратна восьми. Если определить
struct student { unsigned status: 1; } stud;
то для переменной stud будет выделено 8 бит, а использоваться будет только один первый бит.
Использование структур
Структуры в С++ используются для логической или физической группировки объектов, имеющих общий контекст. Наиболее очевидным использованием является создание пользовательских типов данных, упрощающих написание, понимание и сопровождение программы.
Использование структур при написании собственных типов данных рекомендуется в том случае, если выполняется ряд условий:
Создаваемый тип данных не имеет собственного поведения. То есть объект такого типа рассматривается как пассивный набор данных.
Члены данных создаваемого типа данных не могут находиться во взаимно противоречивом состоянии. То есть любая комбинация значений членов структуры является допустимой.
Для более сложных пользовательских типов данных в языке С++ используются классы.
Структуры позволяют достаточно эффективно решить вопрос возврата множества значений из функции. Если функция должна вернуть несколько значений в качестве результата, то их достаточно поместить в структуру и возвращать значение указанного типа.
Типичные ошибки при разработке структур
Наиболее часто встречающейся ошибкой является включение в структуру взаимозависимых данных. То есть таких членов, значения которых могут быть вычислены на основании других членов структуры.
Например, неправильной структурой будет:
1: 2: 3: |
struct Line { vec3 pt1,pt2; double length; }; |
В данном случае член length может быть вычислен на основании pt1 и pt2. Хранение значение length в структуре нарушает вторую рекомендацию по использованию структур. Кроме расхода памяти для хранения избыточной информации программист получает намного более сложную проблему: необходимость синхронизации данных. При каждом изменении любого из членов структуры придётся пересчитывать значение length.