12

我最近读到了

char
unsigned char

signed char

是平台特定的。
我无法完全理解这个?这是否意味着位序列可以从一个平台到下一个平台不同,即平台1 的符号是第一位,平台2 的符号可能在末尾?您将如何对此进行编码?

基本上我的问题来自于看到这条线:

typedef unsigned char byte;

我不明白标牌的相关性?

4

6 回答 6

19

假设您的平台有 8 位字节,并假设我们有位模式10101010。对于 a signed char,该值为 -86。但是,对于unsigned char,相同的位模式表示 170。我们没有移动任何位;它是相同的位,以两种不同的方式解释。

现在为char. 该标准没有说明这两种解释中的哪一种应该是正确的。char持有位模式的值10101010可以-86170。它将是这两个值之一,但您必须先了解编译器和平台,然后才能预测它将是哪个值。一些编译器提供了一个命令行开关来控制它将是哪一个。一些编译器根据它们运行的​​操作系统具有不同的默认值,因此它们可以匹配操作系统约定。

在大多数代码中,这真的无关紧要。出于重载的目的,它们被视为三种不同的类型。指向其中一种类型的指针与指向另一种类型的指针不兼容。尝试strlen用 asigned char*unsigned char*; 它行不通。

signed char当您需要一字节有符号数字类型时使用,unsigned char当您需要一字节无符号数字类型时使用。char当您想保留字符时,请使用普通旧的。这就是程序员在编写您要询问的 typedef 时所想的。“byte”这个名字没有保存字符数据的含义,而“unsigned char”这个名字在它的名字中带有“char”这个词,这导致一些人认为它是一个很好的保存字符的类型,或者说将它与 type 的变量进行比较是个好主意char

由于您不太可能对字符进行一般算术运算,因此char在您使用的任何平台和编译器上是有符号还是无符号都无关紧要。

于 2009-07-31T14:44:56.190 回答
18

你误会了什么。signed char 始终是有符号的。unsigned char 始终是无符号的。但是普通字符是有符号还是无符号是特定于实现的——这意味着它取决于你的编译器。这与 int 类型不同,它们都是有符号的(int 与signed int 相同,short 与signed short 相同)。更有趣的是,char、signed char 和 unsigned char 在函数重载方面被视为三种不同的类型。这意味着您可以在同一个编译单元中拥有三个函数重载:

void overload(char);
void overload(signed char);
void overload(unsigned char);

对于 int 类型是相反的,你不能有

void overload(int);
void overload(signed int);

因为 int 和 signed int 是一样的。

于 2009-07-31T11:30:33.037 回答
3

说它是特定于编译器的更正确,并且在没有或限定符的情况下char使用时,您不应该指望被签名或未签名。charsignedunsigned

否则,您将面临以下问题:您编写和调试程序假设char默认签名,然后使用编译器重新编译,假设否则,程序行为会发生巨大变化。如果您在代码中仅偶尔依赖此假设,则在某些情况下可能会面临意外行为,这些行为仅在特定条件下在您的程序中触发并且很难检测和调试。

于 2009-07-31T11:17:04.767 回答
2

也许您指的是签名char是编译器/平台特定的事实。这是一个博客条目,可以对此有所了解:

C 和 C++ 中的字符类型

于 2009-07-31T11:23:34.830 回答
0

拥有一个有符号字符更像是在 C 中如何处理所有基本变量类型的侥幸,通常使用负字符实际上并没有什么用处。

于 2009-07-31T11:19:14.807 回答
-6

有符号字符始终为 8 位,并且始终将有符号位作为最后一位。

unsigned char 始终为 8 位并且没有符号位。

据我所知,一个字符总是无符号的。任何默认使用有符号字符的编译器都会面临很多不兼容的程序。

于 2009-07-31T11:24:00.680 回答