Лекции по обектно-ориентирано програмиране



страница4/16
Дата25.07.2016
Размер0.95 Mb.
#6568
ТипЛекции
1   2   3   4   5   6   7   8   9   ...   16

6. Полета от битове.

В езика C и C++ е възможно да се дефинират като елементи на структура и да се използват набори от битове;

синтаксис:

[ тип [име]]:ширина;


за всяко поле се отделят точно толкова битове, колкото са указани с ширината; достъпът до битовото поле става с помощта на указаното в него име; ако името е пропуснато, то описаните битове се заделят, но достъпът до тях е невъзможен; в стандарта на C и C++ няма специални ограничения относно типа на полето и размера, тези въпроси са решени отделно за всеки компилатор; битовите полета са машинно зависима конструкция; най-често използваните типове са unsigned int и int; в Borland C и C++ може да се използва и char, но float не може да се използва;

размерът на всяко поле не може да надвишава броя на битовете, които се отделят за съответния тип;

при дефиниране на променлива от тип битово поле, заделената памет зависи от общата дължина на дефинираните полета; памет се заделя на порции, размера на които зависи от реализацията на компилатора – 1, 2, 4, 8 байта;

в Borland C и C++ тези порции зависят от характеристиката Structure Alignment; редът на разполагане на полетата в заделената за тях памет също зависи от реализацията – в Borland C и C++ полетата се разполагат от младши към старши битове, но в други реализации разполагането е от старши към младши битове;

ако структурата съдържа няколко битови полета, те започват да се разполагат в една и съща порция памет последователно в реда на появяването им;

ако за някое битово поле няма достатъчно място в текущата порция памет, то се записва в началото на следващата порция, при това в предишната порция могат да останат неизползвани битове;

при някои реализации (например Borland C и C++) битовите полета могат да пресичат границите на порциите памет;

ако две битови полета в тялото на структурата са разделени от описанието на друг елемент, който не е битово поле, тогава те ще се запишат в различни порции памет;

обръщението към битовите полета и използването им в изрази е както при обикновените полета на структурата, т.е. използват се операции ‘.’, ‘->’; ако на битово поле се присвои величина, която е по-голяма отколкото може да се запише в него, в полето се записват толкова битове, колкото е неговата ширина; при това се губят старшите битове на величината;

можем да дефинираме битово поле без име с цел да се извърши отместване в съответната порция памет; ако размерът на полето без име е 0, то непосредствено следващото битово поле се разполага в началото на следващата порция памет;

пример:

struct bfield



{ unsigned fd1:1;

:0;


int fd2:3;

} bf;


ако подравняването е по байт, тогава имаме следната конфигурация:

| | | | | | | | |x| | | | | |x|x|x|

в първия байт се записва полето fd1 (например от младши към старши битове), полето с ширина 0 указва, че другото битово поле fd2 ще се запише в началото на следващия байт;

ако вместо :0; имаме float x; и трите полета ще се запишат в различни порции памет;


примерна програма:

#include

void main ()

{ struct example

{ int i:2;

unsigned j:2;

int :2;

int k:2;


int d:8;

} mystruct;

mystruct.d = 0;

mystruct.i = 1;

mystruct.j = 3;

mystruct.k = -1;

printf (“Стойността на полетата: %d%u%d\n”, mystruct.i, mystruct.j,

mystruct.k);

}
ако подравняването е по дума имаме следната конфигурация:

|d|d|d|d|d|d|d|d|k|k| | |j|j|i|i|

при полетата signed, най-старшия бит се приема като знаков и затова в битовете за k ще се запише |1|1| и ще се интерпретира като –1;
използването на битови полета е свързано със следните ограничения:


  • не се допускат указатели към битови полета, т.е. към тях не може да се приложи операция &;

  • елементите на масив не могат да бъдат битови полета



7. Обединения.

В езика C и C++ е предвидена възможност за описания на област от паметта, в която могат да се записват в различно време променливи от различен тип; описания от този тип се наричат обединения;

синтаксис:

union име_на_тип

{ описание_на_елемент1;

описание_на_елемент2;

...

описание_на_елементn;



};

всички правила за дефиниране и работа със структури са в сила и за обединения;

съществената разлика между структурите и обединенията е, че за променливите от тип обединение компилаторът разпределя памет, достатъчна за записването на полето с максимална дължина; това е така, защото полетата на обединението започват от една и съща граница; в така разпределената памет за обединението в даден момент може да се записва само един от елементите на обединението;

пример:


union set

{ int k; //2 байта

float f; //4 байта

char ch;//1 байт

char string[5];//5 байта

} example;

дължината на това обединение зависи от подравняването на данните – ако е по байт е 5 байта, по дума 6 байта и т.н.

можем да дефинираме променливи и указатели към променливи от тип обединение по следния начин:

union set x, *p = &x; //в C++ ключовата дума union не е задължителна;

обръщението към елементите на обединението става с операциите

.’ и ‘->’; например:

x.k = 2;


x.f = 7.8; //по този начин губим горната стойност 2

x.ch = ‘A’; //по този начин губим горната стойност 7.8

с указателна операция:

p->k = 2;

p->f = 7.8;

x->ch = ‘A’;


кой елемент от обединението фактически е записан в паметта се контролира единствено от програмиста; например в практиката се въвежда допълнитела променлива от цял тип, която да подскаже на програмиста стойност за кое поле е записана в паметта за обединението;

повечето компилатори (Borland C и C++) поддържат структури с елементи обединения, обединения с елементи структури, масив чийто елементи са обединения – по този начин можем да избегнем ограничението елементите на масива да са от един и същи тип;

например:

union first

{ int k;

float f;


char ch;

} masiv[10];

обединението позволява по различен начин да се обръщаме към една и съща област от паметта; друг случай за използване на обединение – по-особено преобразуване на данните;

x.f = 7.8; искаме да видим какво е записано в третия байт на обединението – използваме масива string, по-точно string[3];


в Borland C и C++ обединение може да се инициализира, но само по първия елемент;

например:

union set x = { 5};//първия елемент на обединението set е int k;




Сподели с приятели:
1   2   3   4   5   6   7   8   9   ...   16




©obuch.info 2024
отнасят до администрацията

    Начална страница