int main()
{
char c = 0xff;
bool b = 0xff == c;
// Under most C/C++ compilers' default options, b is FALSE!!!
}
无论是C或C ++标准指定焦炭用作符号或无符号,它是实现定义。
为什么作为符号或无符号,以避免像上面的代码危险误用C / C ++标准没有明确定义字符?
int main()
{
char c = 0xff;
bool b = 0xff == c;
// Under most C/C++ compilers' default options, b is FALSE!!!
}
无论是C或C ++标准指定焦炭用作符号或无符号,它是实现定义。
为什么作为符号或无符号,以避免像上面的代码危险误用C / C ++标准没有明确定义字符?
由于历史原因,大部分。
类型的表达式char
都提升到int
在大多数情况下(因为很多CPU不具有8位算术运算)。 在某些系统中,符号扩展是为了做到这一点的最有效方法,它主张使普通char
签署。
在另一方面,在EBCDIC字符集具有与所述高位比特组基本的字符(即,具有128或更大的值的字符); 在EBCDIC平台上, char
几乎必须是无符号。
在ANSI C的理由 (在1989年标准)没有很多话要说; 部分3.1.2.5说:
三种类型的字符指定:
signed
,平原,和unsigned
。 一个普通char
作为符号或无符号的,根据实施方式,如在现有实践中可以被表示。 该类型signed char
被介绍给做出那些实施的char为无符号的系统可用一个字节有符号整数类型。 对于对称的原因,关键字signed
允许其他整数类型的类型名称的一部分。
让我们回到更进一步,在一个早期版本的C参考手册从1975年说:
甲
char
对象可以在任何地方使用的int
的可能。 在所有情况下,char
被转换为int
通过所得整数的高位8比特传播其符号。 这是用于字符和整数的二进制补码表示是一致的。 (然而,该符号传播特性在其他实现中消失。)
这个描述更实现特定的比我们在以后的文件看,但它确实承认, char
可以或者带符号。 在其上“的标志传播消失”该“其它实施方式”,促进一个的char
对象int
将具有零扩展的8位表示的,基本上把它当作一个8位的无符号的数量。 (语言还不具备signed
或unsigned
关键字)。
C'S直接前身是一种叫做硼。硼语言是无类型语言,所以问题char
被签名或签名并不适用。 有关C的早期历史的更多信息,请参见后期丹尼斯里奇的主页 ,现在搬到这里 。
至于发生的事情在你的代码(应用现代C规则):
char c = 0xff;
bool b = 0xff == c;
如果纯char
是无符号的,则初始化c
其设置为(char)0xff
,与之相比,等于0xff
在第二行。 但是,如果滑动char
进行签名,然后0xff
(类型的表达式int
)转化为char
-但由于0xff
超过CHAR_MAX(假设CHAR_BIT==8
),其结果是实现定义 。 在大多数实现,结果是-1
。 在比较0xff == c
,两个操作数被转换为int
,使得它等同于0xff == -1
,或255 == -1
,这是当然假。
另一个需要注意的重要一点是unsigned char
, signed char
,和(平) char
三种不同类型。 char
具有相同的表示为任一 unsigned char
或 signed char
; 它的实现定义它是哪一个。 (在另一方面, signed int
和int
是同一类型的两个名字; unsigned int
是不同的类型(除了,只是添加到轻薄,它的实现定义声明为纯位字段是否。 int
签署或无符号的。))
是的,这一切都有点乱,我敢肯定,这将如果C正在从头开始设计今天已经被不同的定义。 但C语言的每次改版不得不避免破坏(太多)现有的代码,并在较小程度上现有实现的。
char
最初是为了存储字符,因此,无论是带符号并不重要。 真正重要的是如何在执行数学char
有效。 因此,依赖于系统,编译器会选择什么是最合适的
ARMv4之前,ARM已经加载半字和符号字节没有原生支持。 要加载符号字节,你必须LDRB然后签署延长值(LSL起来然后ASR它背下来)。 这是痛苦所以焦炭在默认情况下无符号的。
为什么无符号的类型是ARM CPU比较有效?
其实有很多的ARM编译器仍然采用unsigned char
在默认情况下,因为即使你可以加载与现代ARM ISA的符号扩展一个字节,该指令仍低于零扩展版本不够灵活
char
是unsigned
默认情况下,在Android NDK 而最现代的编译器还允许您更改字符的signness而不是使用默认设置