void foo(void)
{
unsignedint a = 6;
int b = -20;
(a + b > 6) ? puts("> 6") : puts("<= 6");
}
这无符号整型问题的答案是输出是">6"。原因是当表达式中存在有符号类型和无符号类型时所有的操作数都自动转换为无符号类型。因此-20变成了一个非常大的正整数,所以该表达式计算出的结果大于6。这一点对于应当频繁用到无符号数据类型的嵌入式系统来说是丰常重要的。
a ^= b;-----+
b ^= a; +------->a ^= b ^= a;
a ^= b;-----+
(只能对 int,char,实型变量(double,float,longdouble)不参与位运算)
=======================
a = a + b;
b = a - b;
a = a - b;
=======================
struct bit
{
int a : 3;
int b : 2;
int c : 3;
};
int main()
{
bit s;
char *c = (char*)&s;
cout << sizeof(bit) << endl;//4
*c = 0x99;//10011001cout << s.a << endl << s.b << endl << s.c << endl;
//s.a = 100//s.b = 11//s.c = 001int a = -1;
printf("%x", a);//ff ff ff ffreturn0;
}
答:因为 0x99 在内存中表示为 10011001 , a = 001, b = 11, c = 100。当 c 为有符号数时, c = 100, 最高 1 为表示 c 为负数,负数在计算机用 补码表示,所以 c = -4;同理 b = -1;当 c 为有符合数时, c = 100,即 c = 4,同理 b = 3。
21.分析以下代码
struct s1
{
int i : 8;
int j : 4;
int a : 3;
double b;
};
struct s2
{
int i : 8;
int j : 4;
double b;
int a : 3;
};
printf("sizeof(s1)= %d\n", sizeof(s1));
printf("sizeof(s2)= %d\n", sizeof(s2));
result: 16, 24
答:第一个 struct s1 理论上是这样的,首先是 i 在相对 0 的位置,占 8 位一个字节,然后,j 就在相对一个字节的位置,由于一个位置的字节数是 4 位的倍数, 因此不用对齐, 就放在那里了,然后是 a,要在 3 位的倍数关系的位置上,因此要移一位,在 15 位的位置上放下,目前总共是 18 位,折算过来是 2 字节 2 位的样子,由于 double 是 8 字节的,因此要在相对 0 要是 8 个字节的位置上放下,因此从 18 位开始到 8 个字节之间 的位置被忽略,直接放在 8 字节的位置了,因此,总共是 16 字节。(个人觉得这个解释有误)
第二个最后会对照是不是结构体内最大数据 的倍数,不是的话,会补成是最大数据的倍数。
1. 一个位域必须存储在同一个字节中,不能跨两个字节。如一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。也可以有意使某位域从下一单元开始。例如:
struct bs
{
unsigned a:4unsigned :0/*空域*/unsigned b:4/*从下一单元开始存放*/unsigned c:4
}
在这个位域定义中,a占第一字节的4位,后4位填0表示不使用,b从第二字节开始,占用4位,c占用4位。
2. 由于位域不允许跨两个字节,因此位域的长度不能大于一个字节的长度,也就是说不能超过8位二进位
3. 位域可以无位域名,这时它只用来作填充或调整位置。无名的位域是不能使用的。例如:
struct k
{
int a:1int :2/*该2位不能使用*/int b:3int c:2
};
从以上分析可以看出,位域在本质上就是一种结构类型, 不过其成员是按二进位分配的