Структуры и объединения. Битовые поля
Для полноты изложения основ языка С++ кратко коснёмся структур (struct) и объединений (union). Это сложные типы данных, определяемые разработчиком в программе, обычно, с целью повышения её наглядности и удобства разработки.
Важно отметить, что понятие структуры в языке С++ существенно расширено в соответствии с концепцией объектно-ориентированного программирования. В данном разделе в качестве введения рассмотрим структуры в стиле языка С, поскольку объектно-ориентированному программированию будет посвящена отдельная глава.
Структура – сложный тип данных, который объединяет под общим именем переменные любых типов (они называются полями структуры). Объявляется следующим образом:
struct [имя_типа_структуры]
{
описание поля 1;
описание поля 2;
….
} [переменные_типа_структуры];
Определение структуры завершается точкой с запятой.
Можно опустить имя_типа_структуры или переменные_типа_структуры, но не то и другое сразу. Если переменные типа структуры не объявлены сразу при описании структуры, значит, они будут объявлены где-нибудь позже отдельным оператором. При описании структуру можно инициализировать, как и массив (используя фигурные скобки).
Например:
struct student
{
char name[30]; // фамилия студента
unsigned int mark; // оценка по программированию
};
Мы создали новый тип student, который теперь можно использовать, как и любой другой тип данных. Например, можно создать переменные этого типа:
student x, y={"Попов", 5};//переменные x и y имеют тип student,
// переменная y инициализирована, а x – не инициализирована
Для обращения к элементам структуры используется операция ‘.’:
cout << y.name << " " << <<y.mark << "\n";
При работе со структурами часто используются указатели. Например:
student *py=&y; // указатель на объявленную ранее структуру y
Имеется отдельный синтаксис обращения к элементам структуры через указатель на структуру – использование операции ‘->’. Например:
cout << py->name << " " << <<py->mark << "\n";
Объединение –участок памяти, используемый несколькими разными переменными, которые могут быть различных типов. Объявляется с помощью ключевого слова union:
union [имя_типа_объединения]
{
объявление переменной 1;
объявление переменной 2;
….
} [переменные_объединения];
Например:
union int_char
{
int i;
char ch;
};
Как и для структур, объявлять переменные объединений можно как в конце оператора объявления объединения, так и отдельными операторами.
Доступ к элементам объединений осуществляется так же, как и к элементам структур, как показано в следующем примере:
// Пример 1.15 – выводим байты целого числа, используя union
union int_char
{
int i;
char ch[sizeof(int)];
};
int main(void)
{
int_char t;
t.i = 1;
for(int j=0;j<sizeof(int);j++)
cout << (int)t.ch[j]; //выводим значения отдельных байтов
}
Битовые поля.Язык C++ имеет удобные средства доступа к отдельны битам внутри байтов. Битовые поля могут быть объявлены только в структурах, объединениях и классах. Размер битового поля указывается через двоеточие при определении поля. Пример:
struct emp // структура сотрудник
{
char name[30];
unsigned lay_off: 1; //временно уволен или неактивен
unsigned hourly: 1; //почасовая оплата или оклад
unsigned deductions: 3; //вычеты
};
Здесь три последних поля хранятся в одном байте.
Ограничения на использование битовых полей:
· нельзя получить адрес битового поля
· нельзя создать битовое поле-массив
· нельзя выходить за границы целого
1.10 Функции в С++ – основы
Понятие функции
Понятие функции является фундаментальным при изучении основ С++, поэтому оно было представлено в самом первом разделе пособия (вместе с примером 1.1, демонстрирующим применение вспомогательной функции). В данном разделе уточним некоторые важные моменты, касающиеся описания и использования функций.
Сначала вспомним и систематизируем основы.
Функция – именованная часть программы (единица программного кода), к которой можно обращаться многократно из различных частей программы, а также из других программ. Иногда функцию определяют как операцию, определяемую пользователем. Подход к разработке программного обеспечения, основанный на разбиении программы на отдельные функции, называют процедурно-ориентированным программированием. Имеется и более общий термин – модульное программирование, который включает и процедурно-ориентированный, и объектно-ориентированный подходы.
При разработке программного кода в нашем распоряжении имеется стандартная библиотека С++, которая содержит множество функций универсального назначения, - хорошо отлаженных, протестированных, апробированных.
Тем не менее, подавляющее большинство программных продуктов имеет свою специфическую функциональность, которая не может быть полностью покрыта функциями стандартной библиотеки. Поэтому в языке С++ имеются развитые средства для реализации собственных функций и их последующего многократного использования.
Выделение функций при разработке собственной программы – далеко не простая задача. Для начала напомним основные принципы, которые следует соблюдать. Далее в пособии эта тема будет развиваться.
· Каждая функция должна выполнять завершённое элементарное действие, смысл которого всем понятен. Примеры из стандартной библиотеки: возведение числа в заданную степень, сортировка массива, удаление фрагмента из строки текста. Имя функции должно кратко отображать суть выполняемого действия (pow, sort, erase).
· Функции не должны зависеть друг от друга, чтобы каждую из них можно было отладить по отдельности, а затем использовать в различных ситуациях. При таком подходе программа будет представлять собой совокупность относительно независимых фрагментов, что заметно упростит процесс её разработки и сопровождения.
· Функции должны быть небольшого размера – всего несколько строк программного кода. Если действие, которое выполняет функция, требует написания более объёмного кода, следует подумать о выделении в ней вспомогательных функций. Например, в функции сортировки массива можно использовать функцию сравнения и функцию перестановки элементов, причём каждую из этих функций можно будет использовать и в других ситуациях, поэтому программа от этого только выиграет.
· Не следует смешивать в одной функции обработку и ввод-вывод данных, поскольку это резко снижает универсальность функции и возможности её многократного использования.
· Вообще, при выделении функций следует постоянно помнить о возможности их многократного использования – это не просто сокращает размер программного кода, но и повышает его надёжность и сопровождаемость.
Для того, чтобы научиться реальному воплощению этих принципов, требуется как можно больше практики программирования. Даже в небольшой учебной программе стоит выделять функции – со временем и рука набьётся, и преимущества модульного программирования станут ощутимыми.