当我在C和C++开发中使用int
或long
、char
、short
等时,我总是知道我已经签署了值.顺便说一句,根据编译器或操作系统的不同,当这些类型的缺省符号变为无符号时会发生什么?我之所以询问,是因为我从来没有在一篇论文或一本书中看到过关于这一点的参考,我也不知道.
当我在C和C++开发中使用int
或long
、char
、short
等时,我总是知道我已经签署了值.顺便说一句,根据编译器或操作系统的不同,当这些类型的缺省符号变为无符号时会发生什么?我之所以询问,是因为我从来没有在一篇论文或一本书中看到过关于这一点的参考,我也不知道.
类型short
、int
、long
和long long
都是带符号的,除非显式限定为unsigned
.请注意,short
和long
实际上是限定符本身,如果省略,则类型int
是隐式的.
类型char
是特殊的:它不同于类型signed char
,后者显然是带符号的,也不同于类型unsigned char
,后者不是.根据平台和编译器设置,类型char
可以是有符号的,也可以是无符号的.您可以通过将<limits.h>
中定义的宏CHAR_MIN
的值与0
进行比较,或者将-1
转换为(char)
并测试它是否保持为负值来测试这一点.
#include <limits.h>
#include <stdio.h>
int main(void) {
if ((char)-1 < 0) {
/* most common case */
printf("char is signed, range is %d..%d\n", CHAR_MIN, CHAR_MAX);
} else
if (sizeof(char) == sizeof(int)) {
/* corner case, for some DSP systems */
/* char type is the same as unsigned int */
printf("char is unsigned, range is %u..%u\n", CHAR_MIN, CHAR_MAX);
} else {
/* common case, enabled with -funsigned-char for gcc and clang */
/* char values and constants will promote to int */
printf("char is unsigned, range is %d..%d\n", CHAR_MIN, CHAR_MAX);
}
return 0;
}
请注意,您不能使用上述测试进行预处理,但在<limits.h>
中定义的常量可以在预处理器表达式中使用:
#include <limits.h>
#include <stdio.h>
int main(void) {
#if CHAR_MIN < 0
printf("char is signed, range is %d..%d\n", CHAR_MIN, CHAR_MAX);
#elif CHAR_MAX == UINT_MAX
printf("char is unsigned, range is %u..%u\n", CHAR_MIN, CHAR_MAX);
#else
printf("char is unsigned, range is %d..%d\n", CHAR_MIN, CHAR_MAX);
#endif
return 0;
}
这在C++中也适用,但有一种更惯用的方法来测试它,使用std::is_signed_v<char>
.