7-1 limits.h中的数据类型范围定义 (P198)书中介绍了C语言编译器在<limits.h>头文件中以宏定义的形式定义了字符型以及其他所能表示的数值的最小值和最大值。这里贴出VS2017中编译器对应的limits.h部分内容:
#define CHAR_BIT 8 // number of bits in a char
#define SCHAR_MIN (-128) // minimum signed char value
#define SCHAR_MAX 127 // maximum signed char value
#define UCHAR_MAX 0xff // maximum unsigned char value
#define MB_LEN_MAX 5 // max. # bytes in multibyte char
#define SHRT_MIN (-32768) // minimum (signed) short value
#define SHRT_MAX 32767 // maximum (signed) short value
#define USHRT_MAX 0xffff // maximum unsigned short value
#define INT_MIN (-2147483647 - 1) // minimum (signed) int value
#define INT_MAX 2147483647 // maximum (signed) int value
#define UINT_MAX 0xffffffff // maximum unsigned int value
#define LONG_MIN (-2147483647L - 1) // minimum (signed) long value
#define LONG_MAX 2147483647L // maximum (signed) long value
#define ULONG_MAX 0xffffffffUL // maximum unsigned long value
这里可以看到其中一些含有L和U的数字常量,含有L的常量是长整型常量long,而U是unsigned无符号的意思。这里的L用于将数字以long类型进行存储,
7.2 负数移位&数据溢出 当对负数进行移位运算时,根据编译器的不同有可能执行算数位移或逻辑位移。算数位移就是考虑正负数的位移,而逻辑位移就是将负数看做unsigned来实现位移,所以不建议对负数进行位移运算。(据说C#的编译器就针对负数位移给出了解决方案,引入了一个>>>的算数右移来实现对负数的位移操作,感兴趣的童鞋可以了解下)。
这里还有一个常见的隐性错误,就是数据溢出,这常常出现在数组越界、变量赋值超范围等情况下。这些错误的变异提示随着编译器不同而不同,有些编译器是不会给出提示的(比如CCS的编译器就不会提示数组越界这种问题,现象就是程序运行过程中在不相关的代码处修改了某个数组或变量的数值),这需要小伙伴们注意下。