Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Книга6.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
2.45 Mб
Скачать

9.2 Бітові поля

Для економії пам’яті в структурах дозволено визначати бітові поля. При використанні бітових полів збільшується час доступу до даних, що зберігаються в цих полях.

Бітове поле – це число, що займає деякий набір бітів і напряму не може бути адресоване процесором. Синтаксис визначення полів і доступу до них базується на синтаксисі структур.

Бітові поля можуть бути корисні з декількох причин, а саме:

  • якщо пам'ять обмежена, то в одному байті можна зберігати кілька булевих змінних (які приймають значення true і false);

  • деякі пристрої передають інформацію про стан, закодовану в байті в одному або кількох бітах;

  • для деяких процедур шифрування потрібен доступ до окремих біт всередині байта.

Бітове поле може бути членом структури або об'єднання. Воно визначає довжину поля в бітах.

Синтаксис бітового поля такий:

тип <ім’я > : <довжина>;

Тут тип означає тип бітового поля, а довжина – кількість біт, які займає це поле. Тип бітового поля може бути int, signed або unsigned. (Крім того, відповідно до стандарту С99, у бітового поля ще може бути тип _Вооl.)

Приклад 9.9 Визначення бітових полів.

struct pol

{

unsigned char R:2;

unsigned char G:3;

unsigned char B:3;

} color;

Приклад 9.10. Робота з бітовими полями.

#include <stdio.h>

#include <stdlib.h>

struct pol

{

unsigned char R:2;

unsigned char G:3;

unsigned char B:3;

};

int main (void)

{

struct pol color;

color.R = 3;

color.G = 6;

color.B = 3;

printf("R=%d\nG=%d\nB=%d\n", color.R, color.G, color.B);

system("pause");

return 0;

}

Результат роботи програми:

У прикладі 9.10 розглянуто варіант визначення структури pol, що містить бітові поля. Число, наступне за двокрапкою у описі елементу структури, задає ширину бітового поля. Зображення образу об’єкту color, який має тип pol у памяті представлено на рисунку 9.1.

Рисунок 9.1 Розташування бітових полів у пам’яті

9.3 Ключове слово typedef

Ключове слово typedef призначено для створення нових імен в програмі, це засіб заміни громіздких послідовностей імен типів у визначеннях новими іменами.

Синтаксис застосування typedef:

typedef <назва існуючого типу> <назва синоніму>;

Приклад 9.11. Оголошення та використання typedef.

typedef unsigned long int ULINT;

typedef float FLT;

typedef char SomeString[55];

ULINT b; /* еквівалентно unsigned long int b; */

SomeString str[10]; /* Масив із 10 покажчиків на масив з 55

елеметів типу char (еквівалентно

char str[10][55]) */

Синонімічні типи, введені за допомогою typedef, подібно до змінних,

можуть мати обмежену область видимості, або бути глобальними.

Приклад 9.12. Області видимості типів, введених за допомогою typedef.

#include <stdio.h>

#include <stdlib.h>

typedef int cntr; /* тип cntr доступний для

всієї подальшої програми */

cntr f(void)

{

static cntr count=0;

return ++count;

}

int vizov(void)

{

typedef int chislo_viklikiv; /* тип chislo_viklikiv не

можна використовувати за

межами vizov() */

chislo_viklikiv c;

while((c=f())<250);

return c;

}

int main(void)

{

printf("Chislo viklikiv funkcii f(): %d\n",vizov());

system("PAUSE");

return 0;

}

Результат роботи програми:

Програма, приведена у прикладі 9.12 ілюструє обмеженість області видимості типу chislo_viklikiv, який введено локально для конкретної функції. Використання цього типу за межами функції vizov приведе до помилки на етапі компіляції.

За допомогою typedef можна вводити необмежену кількість синонімів до єдиного типу, навіть коли області видимості синонімів перетинаються.

Але введення двох синонімів з однаковим ім’ям навіть до різних типів в одній області видимості призведе до генерації компілятором помилки. Виключення становить перевизначення синонімів в різних програмних блоках. У цьому випадку перевизначений синонім стає локальним для даного блоку і його дія закінчується по закінченню програмного блоку.

Приклад 9.13. Перевизначення синонімів.

void f(void)

{

typedef unsigned int ui;

{

typedef int ui; /* локальне перевизначення ui */

}}

Приклад 9.14. Заміна typedef за допомогою директиви #define

#define char* PCHAR

typedef char* pchar;

void f(void){

PCHAR pc1,pc2; /* еквівалентноchar* pc1,pc2; */

pchar pc3,pc4; /* еквівалентно char *pc3,*pc4 */

}

Припустимо нам необхідно оголосити чотири змінних типу покажчиків на символ. На перший погляд ідентичні записи із прикладу 14 на практиці призводять до дещо неочікуваних результатів. Із синтаксичної точки зору програма немає помилок і може бути успішно скомпільована, але за рахунок того що всі макропідстановки виконуються препроцесором ще до етапу компіляції і представляють собою просту заміну літералу PCHAR на char*, оголошення змінної pc2 трактується компілятором як оголошення змінної типу char.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]