C 和 C++ 中的“int”或“long”、“char”等类型是否始终带符号?

KiW*_*Lee 1 c c++ unsigned signed

int当我在 C 和 C++ 开发中使用or longcharshort等时,我一直知道我有符号值。顺便说一句,根据编译器或操作系统的不同,当这些类型的默认符号变为无符号时会发生什么?我之所以询问,是因为我从未在论文或书籍中看到过对此的引用,而且我也不知道。

chq*_*lie 5

类型shortintlonglong long经过签名,除非明确限定为unsigned。请注意,shortand实际上是限定符本身,如果省略long,则类型是隐式的。int

Typechar很特殊:它不同于 type signed char,后者显然是有符号的unsigned char,而 type 则不是。根据平台和编译器设置,类型char可以是有符号的或无符号的。您可以通过比较toCHAR_MIN中定义的宏的值来测试这一点,或者通过强制转换为并测试它是否保持负数。<limits.h>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;
}
Run Code Online (Sandbox Code Playgroud)

请注意,您不能使用上述测试进行预处理,但定义的常量<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;
}
Run Code Online (Sandbox Code Playgroud)

这也适用于 C++,但有一种更惯用的方法可以使用std::is_signed_v<char>.