当您进行基本算术和按位运算时,我对 C 语言如何处理不同大小的整数有点困惑。如果在这种情况下会发生什么:
int8_t even = 0xBB;
int16_t twice = even << 8;
twice = twice + even;
如果我采取另一种方式并尝试将 16 位 int 添加到 8 位怎么办?普通的 int 声明是动态的吗?为什么我要指定尺寸?当我添加两个都是 0xFF 的 8 位整数时会发生什么?
最佳答案
正如我在评论中提到的,在算术过程中所有内容都至少提升为 int。
这是一个示例程序来演示:
main(){
struct {
char x : 1;
}t;
t.x = 1;
int i = t.x << (sizeof i * 8 - 1);
printf("i = %x\n",i);
}
t.x
只有一位,但在此操作中,它会一直提升为整数以给出输出:
i = 80000000
另一方面,如果我们添加行
long long j = t.x << (sizeof j * 8 - 1)
gcc 给了我警告:
warning: left shift count >= width of type [enabled by default]
如果我采取另一种方式并尝试将 16 位 int 添加到 8 位怎么办?
所有算术都将以整数精度(可能是 32 位)完成,然后结果的底部 8 位将存储在 8 位数字中。
普通的 int 声明是动态的吗?
没有。它在实现上是固定宽度的(在您的实现上可能是 32 位)。
为什么我要指定尺寸?
也许您有空间限制。也许你的算法是为了处理特定大小的整数而设计的。也许您确实想处理 uint16_t (Z_65536) 提供的某些模字段。
当我添加到都是 0xFF 的 8 位整数时会发生什么?
这里的提升并不重要,8位结果将是0xFE。如果您要将结果存储在 16 位数字中,则结果将为 0x1FE(除非您的实现中的 int 只有 8 位。除了某些深奥的嵌入式应用程序之外,这种情况极不可能发生)。
编辑
我在这里写了关于无符号约定的内容,因为您将数字表示为 0xFF 似乎是指无符号数字(在 K&R C 中 0xFF
实际上是一个无符号文字)。如果您实际上指的是有符号的 8 位值 0xFF(相当于 -1),那么您的问题就变得微不足道了。无论整数有多大,它都应该始终能够表示 -1,以及 -1 + (-1) = -2
(实际上只需要两位来表示这些数字)。
关于c - C 中大小整数的算术和按位操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23134958/