提问人:KiWon Lee 提问时间:6/23/2023 最后编辑:chqrlieKiWon Lee 更新时间:6/24/2023 访问量:180
类型“int”或“long”、“char”等是否总是在 C 和 C++ 中签名?
Are types 'int' or 'long', 'char', etc. always signed in C and C++?
问:
我一直都知道,当我在 C 和 C++ 开发中使用 or 、 、 等时,我已经对值进行了签名。顺便说一句,根据编译器或操作系统的不同,当这些类型的默认有符号变为无符号时会发生什么?我正在询问,因为我从未在论文或书籍中看到过对此的提及,而且我不知道。int
long
char
short
答:
5赞
chqrlie
6/24/2023
#1
类型 、 和 都是有符号的,除非显式限定为 。请注意,和 实际上是限定符本身,如果省略,则类型是隐式的。short
int
long
long long
unsigned
short
long
int
类型是特殊的:它不同于类型,显然是有符号的,而类型则不是。根据平台和编译器设置,类型可以是有符号的,也可以是无符号的。您可以通过比较 中定义的宏的值来测试这一点,或者通过强制转换为并测试它是否保持负值来测试它。char
signed char
unsigned char
char
CHAR_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;
}
请注意,不能使用上述测试进行预处理,但可以在预处理器表达式中使用中定义的常量:<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>
评论
0赞
HolyBlackCat
6/24/2023
或。std::is_signed_v<char>
0赞
chqrlie
6/24/2023
@HolyBlackCat:当然,答案修改了。
0赞
pts
6/24/2023
...或(char)-1 < (char)0
0赞
chux - Reinstate Monica
6/24/2023
@chqrlie 极端情况:对于那些讨厌的宽,需要 when 是无符号的。char
int/unsigned
printf(", range is %d..%d\n", CHAR_MIN, CHAR_MAX);
printf(", range is %u..%u\n", CHAR_MIN, CHAR_MAX);
char
1赞
chqrlie
6/25/2023
警告:语言律师口语。 可以表示为 ,但它的类型可能是在病理情况下,其中 是无符号的 和 。在 C17 之前,传递 for 是未定义的行为,如果该值仅在 C23 之前在两种类型中都可以表示,则进行定义。这种变化植根于常识,但来得有点晚。for 的情况有所不同,但更具说服力,因为该行为在 C17 下和之前未定义,适用于所有其他架构。CHAR_MIN
int
unsigned int
char
sizeof(unsigned) == 1
unsigned int
%d
%u
CHAR_MAX
评论
char
可以是 OR(实现定义),并且是与 和 不同的类型;请参阅字符类型signed
unsigned
unsigned char
signed char
char
在某些平台上可以取消签名,但通常是签名的。其他一切都已签名。