Введение
Язык Си иногда называют макроассемблером за его тягу к железу. Если не использовать оптимизацию, можно даже примерно оценить, в какие конструкции на ассемблере
преобразуется код программы. Простота и минимализм языка (простоту языка не путать с простотой программирования на языке)
привели к тому, что на многих платформах си остаётся единственным высокоуровневым языком программирования. Без обзора побитовых операций, конечно, изучения языка было
бы неполным.
Побитовые операции, как понятно из названия, позволяют оперировать непосредственно с битами. Большое количество примеров использования побитовых операций можно найти, например,
в книге Генри Уоррена «Алгоритмические трюки для программистов». Здесь мы рассмотрим только сами операции и примитивные алгоритмы.
Как создать желаемое будущее, не зная, чего вы хотите | Лю Бэтчелор | TEDxJIET
Как лучше всего создать т.е. поле при преобразовании из или вообще?
Эквивалент — это поле.
В ты используешь а также для установки битового поля (точно так же, как поле да / нет в Access). В Management Studio он отображается как ложное / истинное значение (по крайней мере, в последних версиях).
При доступе к базе данных через ASP.NET поле отображается как логическое значение.
3 И если вы свяжете таблицу в базе данных Access, true будет иметь значение -1, а false будет иметь значение 0. По крайней мере, в Access 2003. (Это версия, которая была у меня под рукой, которая была подключена к базе данных MSSQL клиента)
2 Обратите внимание, что это не совсем эквивалент. Если скалярная функция возвращает бит, вам все равно нужно проверить, равен ли он 0 или 1
Например, dbo.IsReturnsBit (value) = 1 @ D-Money: Да, но вам нужно провести сравнение, только если вы хотите использовать значение в условии. Если вы используете значение в результате, вам не следует проводить сравнение. Re Mgt Studio, если вы копируете + вставляете данные, вам также необходимо иметь значение True / False, а не 1 или 0.
В тип данных обычно используется для хранения ценности ( за , за ).
- 1 это указано в стандарте SQL? Мне трудно его найти. Ближайшее, что я мог видеть, — это «логический тип».
- 1 Вас вообще беспокоит различие семантики битов и логических значений?
Вы можете использовать тип столбца.
Вы можете использовать поле.
Для добавления столбца BIT в существующую таблицу команда SQL будет выглядеть так:
Если вы хотите создать новую таблицу, вы можете сделать: .
Вы можете использовать тип данных
Вставленные значения больше 0 будут сохранены как ‘1’.
Вставленные значения меньше 0 будут сохранены как ‘1’.
Значения, вставленные как «0», будут сохранены как «0».
Это верно и для MS SQL Server 2012 Express.
- 1 Вы уверены в утверждении относительно значений меньше 0?
- 3 @BiLaL Это обычное поведение для большинства языков. ложно, любое не- число верно. Также часто -1 было значением по умолчанию для истины, потому что в двоичном формате со знаком каждый бит установлен в 1. В настоящее время очень распространено видеть 1 в качестве значения по умолчанию для истины (установлен только младший значащий бит).
Уже есть ответы, говорящие об использовании Bit. Я дополню эти ответы.
Вы должны использовать бит для представления логических значений.
Замечания из статьи MSDN.
Вставка значений в таблицу с указанием или без указания столбцов
Рассмотрим подробнее применение оператора INSERT с указанием имён столбцов и без указания, остановимся
на случаях, когда указывать имена столбцов всё же требуется.
Будем работать с базой данных портала объявлений. В ней есть таблица ADS, содержащая
данные о объявлениях, поданных за неделю.
Если вы хотите выполнить запросы к базе данных из этого урока на MS SQL Server, но эта СУБД
не установлена на вашем компьютере, то ее можно установить, пользуясь инструкцией по этой ссылке.
А скрипт для создания базы данных «Портал объявлений 1», её таблицы и заполения таблицы данных —
в файле по этой ссылке.
Для использующих же MySQL приводим содержание оператора CREATE для создания таблицы:
CREATE TABLE ADS (
Id INT(11) NOT NULL DEFAULT ‘100’,
Category varchar(25) DEFAULT ‘Some Category’,
Part varchar(25) DEFAULT ‘Some Part’,
Units INT(5) DEFAULT NULL,
Money INT(10) DEFAULT NULL,
PRIMARY KEY (Id)
)
Пример 1. Итак, есть база данных портала объявлений.
Таблица ADS выглядит так:
Id | Category | Part | Units | Money |
1 | Транспорт | Автомашины | 110 | 17600 |
2 | Недвижимость | Квартиры | 89 | 18690 |
3 | Недвижимость | Дачи | 57 | 11970 |
4 | Транспорт | Мотоциклы | 131 | 20960 |
5 | Стройматериалы | Доски | 68 | 7140 |
6 | Электротехника | Телевизоры | 127 | 8255 |
7 | Электротехника | Холодильники | 137 | 8905 |
8 | Стройматериалы | Регипс | 112 | 11760 |
9 | Досуг | Книги | 96 | 6240 |
10 | Недвижимость | Дома | 47 | 9870 |
11 | Досуг | Музыка | 117 | 7605 |
12 | Досуг | Игры | 41 | 2665 |
Для вставки новой строки в эту таблицу на MySQL используем следующий запрос:
INSERT INTO ADS
(Id, Category, Part, Units, Money)
VALUES
(13, ‘Недвижимость’, ‘Гаражи’, 22, 4620)
Или без указания имён столбцов:
INSERT INTO ADS
VALUES (13, ‘Недвижимость’, ‘Гаражи’, 22, 4620)
MS SQL Server в ответ на такой запрос выдаст сообщение об ошибке, так как при
создании таблицы было указано, что значения столбца Id являются идентификаторами и вставляются при
добавлении новых строк автоматически с приращением 1. Поэтому на
MS SQL Server нужно использовать следующий запрос (можете скопировать его и вставить в окно запросов):
USE adportal1;
INSERT INTO ADS
(Category, Part, Units, Money)
VALUES
(‘Недвижимость’, ‘Гаражи’, 22, 4620);
В результате выполнения запроса в таблице появится новая строка:
13 | Недвижимость | Гаражи | 22 | 4620 |
Из примера видно, что для вставки числовых значений в таблицу значения нужно указывать без кавычек,
а для вставки строковых значений — в одинарных кавычках.
В запросе на вставку данных можно список столбцов можно указать не в том порядке, который задан
при создании таблицы, и тогда данные следует указывать также в изменённом порядке.
Пример 2. Таким будет запрос на MySQL, в котором порядок следования
столбцов изменён:
INSERT INTO ADS
(Category, Id, Money, Part, Units)
VALUES
(‘Недвижимость’, 13, 4620, ‘Гаражи’, 22)
В результате выполнения запроса в таблице появится такая же новая строка,
как и в примере 1.
Если вы используете MS SQL Server, то в запросе не нужно указывать столбец Id и
запрос с изменённым порядком следования столбцов будет таким:
USE adportal1;
INSERT INTO ADS
(Category, Money, Part, Units)
VALUES
(‘Недвижимость’, 4620, ‘Гаражи’, 22)
JOIN и соединение более двух таблиц
Реляционные базы данных должны подчиняться требованиям целостности и неизбыточности данных,
в связи с чем данные об одном бизнес-процессе могут содержаться не только в одной, двух, но и в трёх и более
таблицах. В этих случаях для анализа данных используются цепочки соединённых таблиц: например, в одной (первой)
таблице содержится некоторый количественный показатель, вторую таблицу с первой и третьей связывают
внешние ключи — данные пересекаются, но только третья таблица содержит условие, в зависимости от которого
может быть выведен количественный показатель из первой таблицы. И таблиц может быть ещё больше. При помощи оператора
SQL JOIN в одном запросе можно соединить большое число таблиц. В таких запросах за одной секцией соединения
следует другая, причём каждый следующий JOIN соединяет со следующей таблицей таблицу, которая была второй
в предыдущем звене цепочки. Таким образом, синтаксис SQL запроса для соединения более двух таблиц следующий:
SELECT ИМЕНА_СТОЛБЦОВ (1..N)
FROM ИМЯ_ТАБЛИЦЫ_1 JOIN ИМЯ_ТАБЛИЦЫ_2
ON УСЛОВИЕ
JOIN ИМЯ_ТАБЛИЦЫ_3
ON УСЛОВИЕ
…
JOIN ИМЯ_ТАБЛИЦЫ_M
ON УСЛОВИЕ
Пример 8. База данных — та же, что и в предыдущих примерах. К таблицам
Categories и Parts в этом примере добавится таблица Ads, содержащая данные об опубликованных на портале объявлениях.
Приведём фрагмент таблицы Ads, в котором среди записей есть записи о тех объявлениях, срок публикации которых
истекает 2018-04-02.
A_Id | Part_ID | Date_start | Date_end | Text |
21 | 1 | ‘2018-02-11’ | ‘2018-04-20’ | «Продаю…» |
22 | 1 | ‘2018-02-11’ | ‘2018-05-12’ | «Продаю…» |
… | … | … | … | … |
27 | 1 | ‘2018-02-11’ | ‘2018-04-02’ | «Продаю…» |
28 | 2 | ‘2018-02-11’ | ‘2018-04-21’ | «Продаю…» |
29 | 2 | ‘2018-02-11’ | ‘2018-04-02’ | «Продаю…» |
30 | 3 | ‘2018-02-11’ | ‘2018-04-22’ | «Продаю…» |
31 | 4 | ‘2018-02-11’ | ‘2018-05-02’ | «Продаю…» |
32 | 4 | ‘2018-02-11’ | ‘2018-04-13’ | «Продаю…» |
33 | 3 | ‘2018-02-11’ | ‘2018-04-12’ | «Продаю…» |
34 | 4 | ‘2018-02-11’ | ‘2018-04-23’ | «Продаю…» |
Представим, что сегодня ‘2018-04-02’, то есть это значение принимает функция CURDATE() —
текущая дата. Требуется узнать, к каким категориям принадлежат объявления, срок публикации которых
истекает сегодня. Названия категорий есть только в таблице CATEGORIES, а даты истечения срока публикации объявлений
— только в таблице ADS. В таблице PARTS — части категорий (или проще, подкатегории) опубликованных объявлений.
Но внешним ключом Cat_ID таблица PARTS связана с таблицей CATEGORIES, а таблица ADS связана внешним
ключом Part_ID с таблицей PARTS. Поэтому соединяем в одном запросе три таблицы и этот запрос можно
с максимальной корректностью назвать цепочкой.
Запрос будет следующим:
SELECT C.Cat_name FROM Categories C JOIN Parts P
ON P.Cat=C.Catnumb JOIN ads A ON A.Part_id=P.Part_id
WHERE A.Date_end=CURDATE()
Результат запроса — таблица, содержащая названия двух категорий — «Недвижимость» и
«Транспорт»:
Cat_name |
Недвижимость |
Транспорт |
Битовые флаги
Расммотрим синтетический пример. Пусть у нас есть три логические переменные, и нам нужно вывести определённое значение
в зависимости от всех этих переменных сразу. Очевидно, что может быть 23 возможных вариантов. Запишем
это условие в виде ветвления:
#include <stdio.h> int main() { unsigned char a, b, c; a = 1; b = 0; c = 0; if (a) { if (b) { if (c) { printf("true true true"); } else { printf("true true false"); } } else { if (c) { printf("true false true"); } else { printf("true false false"); } } } else { if (b) { if (c) { printf("false true true"); } else { printf("false true false"); } } else { if (c) { printf("false false true"); } else { printf("false false false"); } } } _getch(); return 0; }
Мы получили 8 ветвей. Пусть теперь нам понадобилось добавить ещё одно условие. Тогда число ветвей удвоится, и программа
станет ещё сложней для понимания и отладки. Перепишем пример.
Если каждое из наших логичесих значений сдвинуть на своё число бит влево и логически сложить, то мы получим свою уникальную
комбинацию бит в зависимоти от значений a, b и c:
#include <stdio.h> #include <limits.h> void printbits (int n) { int i; for (i = CHAR_BIT - 1; i >= 0; i--) { printf("%d", (n & (1 << i)) != 0); } printf("\n"); } int main() { unsigned char a, b, c; unsigned char res; a = 1; b = 0; c = 0; res = c | b << 1 | a << 2; printbits(res); a = 0; b = 1; c = 1; res = c | b << 1 | a << 2; printbits(res); a = 1; b = 0; c = 1; res = c | b << 1 | a << 2; printbits(res); _getch(); return 0; }
Используем этот подход к нашей задаче и заменим ветвеление на switch:
#include <stdio.h> int main() { unsigned char a, b, c; unsigned char res; a = 1; b = 0; c = 0; res = c | b<< 1 | a << 2; switch (res) { case 0b00000000: printf("false false false"); break; case 0b00000001: printf("false false true"); break; case 0b00000010: printf("false true false"); break; case 0b00000011: printf("false true true"); break; case 0b00000100: printf("true false false"); break; case 0b00000101: printf("true false true"); break; case 0b00000110: printf("true true false"); break; case 0b00000111: printf("true true true"); break; } _getch(); return 0; }
Этот метод очень часто используется для назначения опций функций в разных языках программирования. Каждый
флаг принимает своё уникальное название, а их совместное значение как логическая сумма всех используемых флагов.
Например, библиотека fcntl:
char *fp = "/home/ec2-user/file.txt"; int flag = O_RDWR | O_CREAT | O_TRUNC | O_APPEND; int fd = open(fp, flag, 0644);
Q&A
Всё ещё не понятно? – пиши вопросы на ящик
Примечание. Рекомендуется сохранять значения 1 и 0 только с типом данных. NOT NULL
As Bit имеют значения 1, 0 и NULL. См. Таблицу истинности для этого. Так что планируйте ценности соответственно. Это может внести путаницу, если разрешить значение NULL для битового типа данных.
Пример использования при создании таблицы:
Вы можете использовать поле
Чтобы создать новую таблицу:
Добавление столбца в существующую таблицу:
Чтобы вставить запись:
будет самым простым и при этом займет минимум места. Не очень многословно по сравнению с «Д / Н», но меня это устраивает.
4 Думаю, это лучше — не нужно беспокоиться о Y == y и N = n, истинно или ложно. Намерение совершенно очевидно, и нет никаких «особых» случаев, когда односимвольные поля приглашают
самый подходящий вариант. В противном случае я когда-то использовал для этой цели. за & за .
- 2 Обычно используется 0 для False и ненулевое значение для True.
- +2 есть много вкусов или правда, можно сказать хороший политик: D
который предоставит вам или же Варианты значений. если вы хотите использовать только или же тогда вы можете использовать этот метод:
Но строго посоветую как ЛУЧШИЙ Вариант. Надеюсь полностью это поможет кому-то.
Синтаксис
декларатор-структуры:
declarator
type-specifierdeclaratoroptconstant-expression
Выражение constant-expression задает ширину поля в битах. type-specifier для должен иметь тип , или , а значение должно быть неотрицательными и целочисленным. Если указано значение 0, то объявление не содержит . Массивы битовых полей, указатели на битовые поля, а также функции, возвращающие битовые поля, не допускаются. Необязательный параметр задает имя битового поля. Битовые поля могут объявляться только в рамках структуры. Оператор взятия адреса ( & ) не может применяться к компонентам битового поля.
Создавать ссылки на неименованные битовые поля невозможно; их содержимое во время выполнения непредсказуемо. Их можно использовать в качестве фиктивных полей в целях выравнивания. Неименованное битовое поле, ширина которого указывается как 0, гарантирует, что хранилище для элемента, следующего за ним в списке-объявление-структуры , начинается на границе.
Битовые поля должны иметь достаточную длину, чтобы вмещать в себя битовый шаблон. Например, следующие два оператора недопустимы.
В этом примере определен двумерный массив структур с именем .
Массив содержит 2000 элементов. Каждый элемент представляет собой отдельную структуру с четырьмя членами, каждый из которых представляет собой битовое поле: , , и . Размер каждой структуры равен 2 байтам.
Битовые поля имеют одну и ту же семантику, что и целочисленный тип. Это означает, что битовое поле используется в выражениях точно так же, как использовалась бы переменная того же базового типа, независимо от количества битов в битовом поле.
Блок, относящийся только к системам Microsoft
Битовые поля, определенные как , обрабатываются как . Расширение Microsoft к стандарту ANSI C допускает битовые поля типов и (как , так и ). Неименованные битовые поля с базовым типом , или ( или ) принудительное выравнивание по границе, подходящей для базового типа.
Битовые поля в целом числе назначаются в направлении от младшего разряда к старшему. В приведенном ниже коде
биты размещаются следующим образом:
Поскольку в процессорах семейства 8086 младший байт целочисленных значений размещается перед старшим байтом, указанное выше целое число будет храниться в физической памяти как , за которым следует .
Стандарт ISO C99 позволяет реализации выбирать, может ли битовое поле охватывать два экземпляра хранилища. Рассмотрим эту структуру, в которой хранится четыре битовых поля, всего 64 бит:
Стандартная реализация C может упаковать эти битовые поля в два 32-разрядных целых числа. Она может хранить как 16 бит в одном 32-разрядном целом числе и 14 бит в следующем 32-разрядном целом числе. Соглашение Windows ABI подразумевает упаковку битовых полей в одиночные целые числа хранилища и не объединяет единицы хранения. Компилятор Майкрософт хранит каждое битовое поле в приведенном выше примере таким образом, чтобы оно полностью помещалось в одно 32-разрядное целое число. В этом случае и хранятся в одном целом числе, хранится во втором целом числе, а — в третьем. Оператор возвращает значение для экземпляра . Дополнительные сведения см. в разделе Заполнение и выравнивание членов структуры.
Завершение блока, относящегося только к системам Майкрософт
Объединения
Объединения в си похожи на структуры, с той разницей, что все поля начинаются с одного адреса.
Это значит, что размер объединения равен размеру самого большого его поля. Так как все поля начинаются с одного адреса, то
их значения перекрываются. Рассмотрим пример:
#include <conio.h> #include <stdio.h> union Register32 { struct { unsigned char byte1; unsigned char byte2; unsigned char byte3; unsigned char byte4; } bytes; struct { unsigned short low; unsigned short high; } words; unsigned dword; }; typedef union Register32 EAX; void main() { EAX reg; reg.dword = 0x0000C0FF; printf(" dword \t%08x\n", reg.dword); printf(" low word \t%04x\n", reg.words.low); printf("high word \t%04x\n", reg.words.high); printf(" byte1 \t%02x\n", reg.bytes.byte1); printf(" byte2 \t%02x\n", reg.bytes.byte2); printf(" byte3 \t%02x\n", reg.bytes.byte3); printf(" byte4 \t%02x\n", reg.bytes.byte4); getch(); }
Здесь было создано объединение, которое содержит три поля – одно поле целого типа (4 байта), два поля типа short int (2 байта каждое) и
4 поля по одному байту. После того, как значение было присвоено полю dword, оно также стало доступно и остальным полям.
Объединение в си.
Напоминаю, что на x86 байты располагаются справа налево. Все поля объединения «обладают» одинаковыми данными, но каждое поле имеет доступ
только до своей части.
Вот ещё один пример: рассмотрим представление числа с плавающей точкой:
#include <conio.h> #include <stdio.h> union floatint{ float f; int i; }; void main() { union floatint u = {10.f}; printf("%f\n", u.f); printf("%x\n", u.i); getch(); }
Обратите внимание, что объединение можно инициализировать, как и структуру. При этом значение будет приводиться к типу,
который имеет самое первое поле
Сравните результаты работы
#include <conio.h> #include <stdio.h> union floatint{ int i; float f; }; void main() { union floatint u = {10.f}; printf("%f\n", u.f); printf("%x\n", u.i); getch(); }
Как сделать видео на YouTube для начинающих НАЧНИТЕ ДО ЗАВЕРШЕНИЯ!
Как лучше всего создать т.е. поле при преобразовании из или вообще?
Эквивалент — это поле.
В ты используешь и для установки битового поля (точно так же, как поле да / нет в Access). В Management Studio он отображается как ложное / истинное значение (по крайней мере, в последних версиях).
При доступе к базе данных через ASP.NET поле отображается как логическое значение.
3 И если вы свяжете таблицу в базе данных Access, true будет иметь значение -1, а false будет иметь значение 0. По крайней мере, в Access 2003. (Это версия, которая была у меня под рукой, которая была подключена к базе данных MSSQL клиента)
2 Обратите внимание, что это не совсем эквивалент. Если скалярная функция возвращает бит, вам все равно нужно проверить, равен ли он 0 или 1
Например, dbo.IsReturnsBit (value) = 1 @ D-Money: Да, но сравнение нужно только в том случае, если вы хотите использовать значение в условии. Если вы используете значение в результате, вам не следует проводить сравнение. Re Mgt Studio, если вы копируете + вставляете данные, вам также необходимо иметь значение True / False, а не 1 или 0.
В тип данных обычно используется для хранения значения ( за , за ).
- 1 это указано в стандарте SQL? Мне трудно его найти. Ближайшее, что я мог видеть, — это «логический тип».
- 1 Вас вообще беспокоит различие семантики битов и логических значений?
Вы можете использовать тип столбца.
Вы можете использовать поле.
Для добавления столбца BIT в существующую таблицу команда SQL будет выглядеть так:
Если вы хотите создать новую таблицу, вы можете сделать: .
Вы можете использовать тип данных
Вставленные значения больше 0 будут сохранены как ‘1’.
Вставленные значения меньше 0 будут сохранены как ‘1’.
Значения, вставленные как «0», будут сохранены как «0».
Это верно и для MS SQL Server 2012 Express.
- 1 Вы уверены в утверждении относительно значений меньше 0?
- 3 @BiLaL Это обычное поведение для большинства языков. ложно, любое не- число верно. Также часто -1 было значением по умолчанию для истины, потому что в двоичном формате со знаком каждый бит установлен в 1. В настоящее время очень распространено видеть 1 в качестве значения по умолчанию для истины (установлен только младший значащий бит).
Уже есть ответы об использовании Bit. Я дополню эти ответы.
Вы должны использовать бит для представления логических значений.
Замечания из статьи MSDN.
Определение
Битовый массив — это отображение некоторого домена (почти всегда диапазона целых чисел) на значения в наборе {0, 1}. Значения можно интерпретировать как темный / светлый, отсутствующий / присутствующий, заблокированный / разблокированный, действительный / недействительный и т. Д. Дело в том, что возможных значений всего два, поэтому их можно хранить в одном бите. Как и в случае с другими массивами, доступом к одному биту можно управлять, применяя индекс к массиву. Предполагая, что его размер (или длина) равняется n битам, массив можно использовать для указания подмножества домена (например, {0, 1, 2, …, n −1}), где 1 бит указывает наличие и 0-битное отсутствие номера в наборе. Эта структура данных набора использует около n / w слов пространства, где w — количество бит в каждом машинном слове . Независимо от того, указывает ли младший бит (слова) или самый старший бит на наименьшее число индекса, в значительной степени не имеет значения, но первый имеет тенденцию быть предпочтительным (на машинах с прямым порядком байтов ).
SQL запрос Union (объединение)
Над множеством можно выполнять операции объединения, разности и декартова произведения. Те же операции можно использовать и в sql запросах (выполнять операции с запросами).
Использование оператора требует выполнения нескольких условий:
- количество выходных столбцов каждого из запросов должно быть одинаковым;
- выходные столбцы каждого из запросов должны быть сравнимы между собой по типам данных (в порядке их очередности);
- в итоговом наборе используются имена столбцов, заданные в первом запросе;
- может быть использовано только в конце составного запроса, так как оно применяетя к результату объединения.
Пример: Вывести цены на компьютеры и ноутбуки, а также их номера (т.е. произвести выгрузку из двух разных таблиц в одном запросе)
Решение:
1 2 3 4 5 6 |
SELECT `Номер` , `Цена` FROM pc UNION SELECT `Номер` , `Цена` FROM notebook ORDER BY `Цена` |
Результат:
Рассмотрим более сложный пример с объединением inner join:
Пример: Найти тип продукции, номер и цену компьютеров и ноутбуков
Решение:
1 2 3 4 5 6 7 8 |
SELECT product.`Тип` , pc.`Номер` , `Цена` FROM pc INNER JOIN product ON pc.`Номер` = product.`Номер` UNION SELECT product.`Тип` , notebook.`Номер` , `Цена` FROM notebook INNER JOIN product ON notebook.`Номер` = product.`Номер` ORDER BY `Цена` |
Результат:
SQL Union 1. Найти производителя, номер и цену всех ноутбуков и принтеров
SQL Union 2. Найти номера и цены всех продуктов, выпущенных производителем Россия
Объявление битовых полей
Элементом структуры может быть битовое поле, обеспечивающее доступ к отдельным битам памяти. Вне структур или объединений битовые поля объявлять нельзя. Нельзя также организовывать массивы битовых полей и нельзя применять к полям операцию определения адреса или получить ссылку на них.
Синтаксис объявления типа структуры с битовыми полями:
struct { Тип1 ИмяПоля1 : ШиринаПоля1 Тип2 ИмяПоля2 : ШиринаПоля2 ........................ ТипN ИмяПоляN : ШиринаПоляN } ИмяСтруктуры;
где struct – спецификатор типа;
ИмяСтруктуры – идентификатор;
Тип1, … ТипN – тип поля, который может быть только int, возможно, со спецификатором unsigned или signed ;
ШиринаПоля (длина) – целое неотрицательное десятичное число, значение которого обычно (в зависимости от реализации компилятора) не должно превышать длины машинного слова.
Например:
struct { int c1 : 4; int c2 : 12; } ab;
Битовые поля длиной 1 должны объявляться как unsigned, поскольку 1 бит не может иметь знака. Битовые поля могут иметь длину от 1 до 16 бит для 16-битных сред и от 1 до 32 бит для 32-битных сред.
Разрешается поле без имени (для этого надо указать только двоеточие и ширину), с помощью которого в структуру вводятся неиспользуемые биты (промежуток между значимыми полями). Нулевая ширина поля вводится, когда необходимо, чтобы следующее в данной структуре поле разместилось с начала очередного машинного слова.
Например, если нам нужны только биты cts и dsr, то можно объявить структуру status_type следующим образом:
struct status_type { unsigned : 4; unsigned cts :1; unsigned dsr :4; } status;