在c语言中学习数据存储的时候发现
%d, %u都会自动取4字节的二进制内容进行解析转换为整形数据
int main() {
char a = -1;
// 1111 1111 0xff
printf("%d\n", a); // -1
printf("%u\n", a); // 巨大
// 0xff ff ff ff
unsigned char b = -1;
// 1111 1111 0xff
printf("%d\n", b); // 255
printf("%u\n", b); // 255
// 0x 00 00 00 ff
printf("hello data\n");
return 0;
}
字符c 在内存中存储为 1111 1111
当用%d, %u的形式解析输出时,因为 %d, %u都取4字节, 所以要补3个字节,至于补什么
signed型是基于最高位数字,如果最高位数字是1,那在高位一直补1,直到补到4个字节
unsigned型是一直补0,直到补到4个字节
代码运行之后看结果
%d 和 %u 的区别在我看来%d是要涵盖正负,以8-bit存储举例,涵盖正负的话,
%d的范围是[-128, 127]
%u的范围是[0, 255]
考虑到计算机的加法运算,就搞出来补码这个神奇的东西。
而无符号就不需要,因为没有负数的存储,全为正数,那就一直加就好了。
总结:
- %d, %u都会自动取4字节的二进制内容进行解析转换为整形数据
- signed int型提升会基于最高位符号数
- unsigned int型提升就补0
- 其区别是是否涵盖正负数
- 为了signed int的加法运算,有补码的概念利于加法,其转换方法是
- c语言中默认都是signed数据
- 整形提升就是,如果需解析数据小于4字节,却要以%d %u形式输出,则会依最高位一直补到4字节为止,再解析。
- 当然整形提升的范围不止于此,因为:表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度一般就是int的字节长度,同时也是CPU的通用寄存器的长度。因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度。
-
通用CPU(general-purpose CPU)是难以直接实现两个8比特字节直接相加运算(虽然机器指令中可能有这种字节相加指令)。所以,表达式中各种长度可能小于int长度的整型值,都必须先转换为int或unsigned int,然后才能送入CPU去执行运算。