Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Структуры. Объединения. Поля битов в структурахСтр 1 из 8Следующая ⇒
Лекция 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) –го автомобиля Расположение массива структур в памяти:
person_list [1]. fio person_list [i-1].fio[j] Массив структурных переменных можно описать и следующим образом: 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; просмотров: 34; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.16.51.3 (0.166 с.) |