Возможный дубликат:
Что означает этот код C ++?
В следующем коде C ++
# include <stdio.h>
int main()
{
struct clap
{
int i:2;
int j:2;
int k:3;
}x={1,2,3};
printf("%d %d %d",x.i,x.j,x.k);
return 0;
}
Запустив следующий код, я получаю вывод
1 -2 3
Пожалуйста, объясните значение оператора «:» в отношении приведенного выше кода и причину этого странного вывода;
Эти указывают битовые поля с длиной, обозначаемой после двоеточия
struct clap
{
int i:2; // length 2
int j:2; // length 2
int k:3; // length 3
};
Битовые поля экономят место. Попробуйте вычислить sizeof(clap)
и вы найдете, что это 4 байта на gcc 4.7. Причина это не 1 байт (2 + 2 + 3 = 7 бит < 1 байт), это то, что компиляторы также выравнивают структуры на определенных границах в зависимости от типа подчиненного значения битовых полей. Например. изменения int
в short
или же char
как базовый тип битовых полей уменьшит общий размер clap
соответственно 2 и 1 байт (с gcc 4.7 снова).
Это следует сравнить с хранением 3 полных целых чисел, обычно занимает 12 байтов (если int равно 4 байта). OTOH, битовые поля могут замедлить ваш код, потому что обращение к членам влечет за собой сдвиг и распаковку битовых полей.
Проблема знака возникает потому, что 2-битные дополнение двух из 2 равно -2. Расширение кода до int j:3
будет выводить 2
,
Двоеточие в структуре означает, что члены битовые поля. То есть каждое поле использует только указанное количество битов.
Что вы получаете -2
для поля j
вероятно потому что printf
трактует как целое число с расширенным знаком.
Это то, что называется битовое поле.
Обновить:
Причина того, что x.j
был напечатан как -2
: x.j
равен 2, но имеет только 2 бита, а старший бит равен 1, что будет считаться знаковым битом printf
с %d
формат. Чтобы убедиться в этом, просто измените %d
в %u
и посмотрим, что получится.
Как и другие ответы говорят, что это битовое поле.
Одно важное замечание о них:
Таким образом, C ++ 0x обрабатывает все (ненулевой длины) битовые поля в смежных
последовательность битовых полей как часть одной ячейки памяти;
назначение одному конфликтует с назначением любому другому.
Такие смежные битовые поля не должны обновляться одновременно
разные темы. Обычно это означает, что они должны быть защищены
одиночный замок
http://www.hpl.hp.com/personal/Hans_Boehm/c++mm/threadsintro.html#bitfields