180

在“C 的完整参考”一书中提到,char默认情况下它是无符号的。

但我试图用 GCC 和 Visual Studio 来验证这一点。默认情况下将其视为已签名

哪一个是正确的?

4

6 回答 6

234

书错了。该标准没有指定 plainchar是有符号还是无符号。

事实上,该标准定义了三种不同的类型:charsigned charunsigned char。如果你#include <limits.h>再看CHAR_MIN,你可以发现 plaincharsignedor unsigned(如果CHAR_MIN小于 0 或等于 0),但即便如此,就标准而言,这三种类型是不同的。

请注意,char这种方式很特别。如果将变量声明int为 100% 等同于将其声明为signed int. 这对于所有编译器和架构都是如此。

于 2010-01-13T06:48:09.317 回答
74

正如Alok 指出的那样,标准将其留给实施。

对于 gcc,默认是签名的,但您可以使用-funsigned-char. 注意:对于 Android NDK 中的 gcc,默认为 unsigned。您还可以使用 . 明确要求签名字符-fsigned-char

在 MSVC 上,默认已签名,但您可以使用/J.

于 2010-01-13T06:51:52.320 回答
39

C99 N1256 草案6.2.5/15“类型”对 type 的签名有这样的说法char

实现应将 char 定义为与有符号字符或无符号字符具有相同的范围、表示和行为。

并在脚注中:

CHAR_MIN,在 中定义<limits.h>,将具有值0或之一SCHAR_MIN,这可用于区分这两个选项。无论做出何种选择,char它都是与其他两种不同的类型,并且与任何一种都不兼容。

于 2010-01-13T07:09:44.193 回答
8

根据丹尼斯·里奇 (Dennis Ritchie) 的 C 编程语言一书,这是 ANSI C 的事实上的标准书,有符号或无符号的普通字符取决于机器,但可打印字符始终是正数。

于 2012-07-31T08:36:20.647 回答
8

根据 C 标准,普通字符的签名是“实现定义的”。

一般来说,实现者会选择在他们的架构上实现更有效的那个。在 x86 系统上,char 通常是有符号的。在 arm 系统上,它通常是未签名的(Apple iOS 是一个例外)。

于 2016-11-23T18:55:49.590 回答
2

现在,我们知道标准将其留给实施。

但是如何检查一个类型是signedor unsigned,比如char

我写了一个宏来做到这一点:

#define IS_UNSIGNED(t) ((t)~1 > 0)

gcc并用、clang和测试它cl。但我不确定它对于其他情况总是安全的。

于 2018-12-20T08:57:11.097 回答