我正在努力学习C,因为目前我已经陷入了数据类型.
看看这段代码:
#include <stdio.h>
#include <limits.h>
int main() {
char a = 255;
char b = -128;
a = -128;
b = 255;
printf("size: %lu\n", sizeof(char));
printf("min: %d\n", CHAR_MIN);
printf("max: %d\n", CHAR_MAX);
}
Run Code Online (Sandbox Code Playgroud)
printf输出是:
size: 1
min: -128
max: 127
Run Code Online (Sandbox Code Playgroud)
怎么可能?char的大小是1 Byte,默认的char似乎是签名的(-128 ... 127).那么如何在不发出溢出警告的情况下分配值> 127(我在尝试分配-128或256时得到)?gcc会自动转换为unsigned char吗?然后,当我指定负值时,它会转换回来吗?它为什么这样做?我的意思是,所有这些隐含性都不会让它更容易理解.
编辑:
好吧,它没有转换任何东西:
char a = 255;
char b = 128;
printf("%d\n", a); /* -1 */
printf("%d\n", b); /* -128 */
Run Code Online (Sandbox Code Playgroud)
所以它从下往上开始计算.但为什么编译器没有给我一个警告?为什么会这样,当我尝试分配256?
参见C99标准中的 6.3.1.3/3
...新类型已签名且值无法在其中表示; 结果是实现定义的,或者引发实现定义的信号.
因此,如果您没有收到信号(如果您的程序没有停止),请阅读编译器的文档以了解它的作用.
gcc记录行为(在http://gcc.gnu.org/onlinedocs/gcc/Integers-implementation.html#Integers-implementation中)
- 当该值无法在该类型的对象中表示时,将整数转换为有符号整数类型的结果或信号(C90 6.2.1.2,C99 6.3.1.3).
为了转换为宽度N的类型,该值以2 ^ N的模数减少到该类型的范围内; 没有信号被提出.