Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву
Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Структуры. Объединения. Поля битов в структурахСодержание книги
Поиск на нашем сайте
Лекция 18 Структуры. Объединения. Поля битов в структурах Структура как пользовательский тип и совокупность данных. 1 Определение шаблона структуры и структурной переменной. 1 Расположение структурных переменных в памяти. 5 Инициализация структурных переменных. 7 Вложенные структуры.. 7 Операции над структурными переменными. 8 Массив структур. 10 Структура в качестве аргумента функции. 11 Примеры работы со структурами. 12 Объединение как пользовательский тип и совокупность данных. 15 Определение объединения и переменной объединяющего типа. 15 Примеры использования объединений. 17 Получение внутреннего представления вещественного числа. 17 Использование перечисляемого типа для обращения к полям объединения. 17 Битовые поля структур и объединений. 19 Определение битовых полей. 19 Примеры использования битовых полей. 20 Вывод значений битовых полей. 20 Формирование кода символа с помощью битовых полей объединения. 21 Формирование байта и вывод на экран его двоичного представления. 22 Структура как пользовательский тип и совокупность данных Доступ к полям структурной переменной возможен в виде: имя_структуры. имя_элемента_структуры имя_ссылки_на_структуру. имя_элемента_структуры (*имя_указателя_на_структуру). имя_элемента_структуры В последнем случае скобки обязательны, так как операция разыменования (*) должна относится только к указателю, а не к элементу структуры.
Для доступа к полям структурной переменной через указатель: используется также операция ->: имя_указателя_на_структуру -> имя_элемента_структуры // -> – есть операция непрямого доступа к элементу (члену) структуры
В случае шаблона структуры: struct date{ int day; int mes; int year; char mon_name[10]; } x, y, *ptr_date= &x;
эквивалентны записи: (*ptr_date). year и ptr_date->year (*ptr_date).mon_name[0] и ptr_date->mon_name[0]
Инициализация структурных переменных Разрешается выполнять инициализацию полей структурной переменной при её определении. Например:
struct Book {char name[20]; //определение шаблона структуры char title[44]; int year; float price; };
Book // инициализация структурных переменных при их определении first_book = {"Mitchel M.", "Unesennie vetrom", 2007, 20000 }, child_book = {"Troepolskij G.", "Belij Bim Chernoe Ucho", 2006, 10000 }, dog_book = {…..};
Инициализирующие значения располагаются в порядке объявления полей в структурном типе. Типы инициализирующих значений должны быть совместимы с типами соответствующих полей в определении структурного типа.
Вложенные структуры Поле, являющееся структурой, называют вложенной структурой. Естественно, что шаблон вкладываемой структуры должен быть уже известен компилятору. Например: struct UDC { char class, subclass; int number; }; struct Book { struct UDC udc_class; char name [20]; char title[44]; int year; float price; } first_book, child_book, dog_book;
Ссылка на поле вложенной структуры формируется из имени структурной переменной, имени структурного поля и имени вложенной структуры. Перечисленные имена разделяются символом «точка». Например: first_ book. udc_ class. class = ‘A’; // ( first_book. udc_class ). class. dog_book. udc_class. number = 681; child_ book. udc_ class. class = 65; //объяснить, почему верно
Теоретически не существует ограничения на величину уровня вложенности структур.
Пусть имеем вложенные структуры: struct Distance //длина в километрах и метрах { int km, m; }; struct Pole //размеры прямоугольного поля { Distance length; Distance width, };
Тогда инициализация структурной переменной типа Pole выглядит так: Pole pole = { { 2, 20 }, { 1, 5 }};
Массив структур Определим шаблон структуры data, содержащий информацию о дне рождения (год, месяц, день), и структурные переменные masha_data и sasha_data с информацией о днях рождения Маши и Саши: struct data { int year; //год unsigned mes; //месяц unsigned day; //день }; data masha_data, sasha_data;
Тогда: masha_data. day //доступ к полю «день рождения» Маши sasha_data. year //доступ к полю «год рождения» Саши
masha_data (вся информация о дате рождения Маши), sasha_data (вся информация о дате рождения Саши). Для данного структурного типа опишем массив структур person_data: data person_data [20]; Тогда: person_data – информация о датах рождения всей группы (массива людей из двадцати человек); person_data[i] – информация о дате рождения (i+1) – го члена группы (i – ый элемент массива); person_data[i]. mes – месяц рождения (i+1) – го члена группы; Определим структурный тип (шаблон структуры) mash с информацией о владельце автомобиля: номер, марка автомобиля, фамилия и адрес владельца. struct Auto {int nomer; //номер автомобиля char marka[20]; //марка автомобиля char fio[40]; //фамилия владельца char adres[60] //адрес владельца }; Auto mers, volvo, alfa_r [5], *mazda,person_list [20]; // определение структурных переменных mers. marka –доступ к полю «марка» автомобиля mers mers – вся информация о владельце автомобиля mers volvo. fio[0] – первая буква фамилии владельца автомобиля volvo alfa_ r [1]. adres[0] – первый символ адреса второго элемента массива владельцев alfa _ r person_ list – информация о всех владельцах автомобилей (массив из двадцати наборов данных); person_ list[ i] – информация о владельце (i+1) –го автомобиля (i –ый элемент в наборе данных); person_ list[ i]. fio – фамилия владельца (i+1) –го автомобиля; person_ list[ i]. fio[ j] –j-ая буква в фамилии владельца (i+1) –го автомобиля Расположение массива структур в памяти:
Массив структурных переменных можно описать и следующим образом: struct { char name[20]; char title[44]; int year; float price; } books[25]; Тогда к полю year в i-ом элементе массива структур books можно обратиться следующим образом: books[i]. year =2007; (*(books+i)). year =2007; (books+i)->year =2007;
Примеры работы со структурами 1. Определение структурного типа complex, представляющего комплексные числа, заданные в алгебраической форме, и определение структурных переменных x, y этого типа: struct complex { float re; //действительная часть числа float im; //мнимая часть числа } x, y;
При этом x.re – доступ к полю действительной части комплексного числа x, y.im – доступ к полю мнимой части комплексного числа y,
Тогда функции для ввода, вывода, сложения комплексных чисел могут выглядеть так: struct complex { float re, im;}; //определение структурного типа
complex read (); //прототип функции ввода комплексного числа void print (complex); //прототип функции вывода комплексного числа на экран void add (complex, complex, complex*); //прототип функции сложения комплексных чисел void add1 (const complex&, const complex&, complex&); int main() { complex c1, c2, c3,c4; //определение комплексных чисел c1 = read(); //вызов функции ввода числа c2 = read();
add (c1, c2, &c3); print(c1); cout << "\t + \t" << endl; print (c2); cout << " = " << endl; print (c3); cout << endl;
add1 (c1, c3, c4); print(c1); cout << "\t + \t" << endl; print (c3); cout << " = " << endl; print (c4);
_getch(); return 0; }
complex read() { complex c; cout << "re, im:"<< endl; cin >> c.re >> c.im; return c; }
void print (complex c) { cout << c.re << " + i*" << c.im << endl; return; }
void add (complex c1, complex c2, complex *c3) { c3->re = c1.re +c2.re; //или (*c3).re = c1.re + c2.re; c3->im= c1.im +c2.im; return; } void add1 (const complex &c1, const complex &c2, complex &c3) { c3.re = c1.re +c2.re; c3.im= c1.im +c2.im; return; }
2. Определение структурного типа racion, представляющего понятие «рациональное число» и набор функций для сокращения, печати, деления рациональных чисел: struct racion {int chis, znam;}; //определение структуры
void put (racion); //прототипы функций racion sokr (racion A); void div (racion A, racion B, racion *C);
int main() { racion A, B, C; puts ("racion1, racion2:?"); scanf ("%d%d%d%d", &A.chis, &A.znam, &B.chis, &B.znam); //ввод чисел div(A, B, &C); //вызов функции деления чисел printf (":"); put(A); printf ("\tna\t"); put(B); printf ("\n="); put(C); //вывод результата _getch(); return 0; }
void put (racion A) //функция выводит на экран «рациональное число» {if (A.chis * A.znam <0) printf ("-"); A.chis = abs(A.chis); A.znam = abs(A.znam); printf("%d / %d", A.chis, A.znam); }
void div (racion A, racion B, racion *C) //функция делит 2 рациональных числа { A=sokr(A); B= sokr (B); C->chis = A.chis*B.znam; C->znam = A.znam*B.chis; *C= sokr (*C); }
racion sokr (racion A) //функция выполняет сокращение «рационального числа» { int i, min; if (abs(A.chis) > abs(A.znam)) min= abs(A.znam); else min = abs(A.chis); for (i=min; i>1; i--) if(A.chis % i ==0 && A.znam % i ==0) break; A.chis /=i; A.znam /=i; return A; }
3. Рассмотрим программу, позволяющую по паре чисел (год, порядковый номер дня) получить название и число месяца: struct date { int d, m, y; //день, месяц, год char *mname; //название месяца } md;
//двумерный массив с количеством дней в месяце для високосного и невисокосного года static int dofm[2][12]={{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
//массив строк с названием месяцев static char *name[ ]={"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
void monthd(date*, int); //прототип функции пересчета //значение года передается функции в поле «год» структурной переменной, //пересчитанные значения дня и месяца возвращаются в этой же переменной, //поэтому значение структурной переменной передается по указателю
int main() {int yd; //порядковый номер дня года cout << "god, den?"; cin >> md.y >> yd; //ввод значений года и порядкового номера дня monthd (&md, yd); //вызов функции пересчета md.mname = name[md.m]; //присваивание названия месяцу cout << md.d <<" " << md.mname<< endl; _getch(); return 0; }
void monthd(date *md, int yd) {int i, v; v = (!(md->y%4) && (md->y%100) ||!(md->y%400)); //проверка на високосность if (yd > 365+v) {cout << "wrong number"; _getch(); exit(1);} //проверка значения дня года md->d = yd; //подготовка начального значения для поля md->d
for (i=0; md->d > dofm[v][i]; i++) //пересчет порядкового значения дня года md->d -= dofm[v][i]; //в день месяца md->m=i; //присваивание значения месяцу }
Примеры использования объединений Определение битовых полей Язык С++ допускает использование в структурах и объединениях в качестве полей данных особого типа полей – битовых. Каждое битовое поле представляет целое или беззнаковое целое значение, занимающее в памяти фиксированное число битов. Число связанных бит – ширина поля.
Общий синтаксис описания битового поля: тип_поля [имя_поля]: ширина_поля; Члены битовых полей могут иметь значения базовых целых типов (знаковых или беззнаковых). Эти ключевые слова записываются в поле «тип_поля». Для переносимости программ лучше указывать служебные слова signed или unsigned, однако заметим, что сама природа структур с битовыми полями не способствует переносимости.
Определение структурной переменной с битовыми полями имеет формат: struct имя_структурного _типа { тип_поля1 имя_поля1: ширина_поля1; тип_поля2 имя_поля2: ширина_поля2; } имя_структурной_переменной;
Каждому полю выделяется столько бит, сколько задается в поле «ширина». Ссылка на битовое поле выполняется по имени, указываемому в поле «имя». Например: struct EXAMPLE { int i: 3; unsigned j: 2; int: 3; int k: 2; } my_ struct;
Это описание включает 4 битовых поля: i из трех битов (значения от -4 до 3), j из двух битов (значения от 0 до 3), поле без имени из трех битов и поле k из двух битов (значения от -2 до 1). В памяти, отводимой под структуру EXAMPLE, битовое поле k будет расположено не непосредственно за полем j, а через три бита от него (на величину безымянного поля). Неименованное поле используется в структуре как заполнение:ничто не будет храниться в этих битах. При ссылке на битовое поле, в выражениях, выделяются (по шаблону) нужные биты и при необходимости выполняется сдвиг числа вправо. В результате оно вступает в операцию в соответствии с типом как число со знаком или без него. При ссылке на битовое поле слева от операции присваивания выполняется обратная операция: сдвиг числа влево, выделение по маске нужных битов и размещение их в структурной переменной поразрядной логической операцией с предыдущим содержимым поля.
Структуры с битовыми полями используются подобно обычным структурам. Битовые поля не могут быть самостоятельным объектом программы, а лишь элементами структур, объединений, классов. Не могут они объединяться и в массивы. К битовым полям не может быть применен оператор взятия адреса &, так как битовое поле может находиться внутри байта.
Битовые поля позволяют рационально использовать память с помощью хранения данных в минимально требуемом количестве битов, экономить память, работая с однобитовыми флажками, формировать объекты с длиной внутреннего представления, не кратной байту (т.е. упаковывать информацию). Их назначение – удобный доступ к отдельным битам, компактное представление в памяти упакованных структур. Однако в ряде случаев их использование может привести к замедлению выполнения программы. Компилятор старается размещать битовые поля в памяти последовательно. Для выравнивания он может свободно переходить к следующему байту или слову. Манипуляции с битовыми полями являются машинно-зависимыми. Поля могут размещаться как слева направо, так и справа налево (зависит от реализации). В некоторых компьютерах битовые поля могут пересекать границы машинного слова, тогда как в других – нет, но максимальная ширина поля не должна превышать длины слова компьютера. Размещение поля с длиной, не кратной длине слова или байта, возможно с расположением «встык», без пропусков или же с выравниванием на границе. Влиять на размещение битовых полей можно и на уровне синтаксиса языка С++ (в этом случае для выравнивания можно использовать недоступные биты – безымянные поля). Для структуры с битовыми полями: struct {int a: 10; int b: 14; } xx;
при выравнивании на границе слова или байта:
7 0 7 0 7 0 7 0
хх. b (14 битов) хх. a (10 битов)
при плотной упаковке: 7 0 7 0 7 0 7 0
хх. b (14 битов) хх. a (10 битов)
Примеры использования битовых полей Вариант 2. Используется функция, которая упаковывает в байт остатки от деления на 16 двух чисел int main() { int a=36, b=20; //два числа для формирования кода символа ‘D’ cout << cod(a, b) << endl; _getch(); return 0; }
unsigned char cod (int a, int b) { union { unsigned char z; struct {unsigned int x:4; unsigned int y:4; } hh; } un; un.hh.x=a%16; //остаток равен 4 un.hh.y=b%16; //остаток равен 4 return un.z; //возвращает символ с кодом 44 } Лекция 18 Структуры. Объединения. Поля битов в структурах Структура как пользовательский тип и совокупность данных. 1 Определение шаблона структуры и структурной переменной. 1 Расположение структурных переменных в памяти. 5 Инициализация структурных переменных. 7 Вложенные структуры.. 7 Операции над структурными переменными. 8 Массив структур. 10 Структура в качестве аргумента функции. 11 Примеры работы со структурами. 12 Объединение как пользовательский тип и совокупность данных. 15 Определение объединения и переменной объединяющего типа. 15 Примеры использования объединений. 17 Получение внутреннего представления вещественного числа. 17 Использование перечисляемого типа для обращения к полям объединения. 17 Битовые поля структур и объединений. 19 Определение битовых полей. 19 Примеры использования битовых полей. 20 Вывод значений битовых полей. 20 Формирование кода символа с помощью битовых полей объединения. 21 Формирование байта и вывод на экран его двоичного представления. 22
|
||||||||||||||||||||||||||||||
|
Последнее изменение этой страницы: 2021-12-15; просмотров: 93; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 216.73.216.3 (0.011 с.) |
|||||||||||||||||||||||||||||||