【问题标题】:Can someone explain how the signedness of char is platform specific?有人可以解释 char 的签名是如何特定于平台的吗?
【发布时间】:2009-07-31 11:13:53
【问题描述】:

我最近读到两者之间的区别

char
unsigned char

signed char

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

基本上我的问题来自于看到这一行:

typedef unsigned char byte;

我不明白标牌的相关性?

【问题讨论】:

    标签: c++ signedness


    【解决方案1】:

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

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

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

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

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

    【讨论】:

    • 这就是我正在寻找的解释! +1 非常感谢!
    • 所以如果你想要的是一个字节而不是一个实际的字符,请使用来自stdint.huint8_tint8_t
    【解决方案2】:

    你误会了什么。 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 是一样的。

    【讨论】:

    • 我认为这可以很好地说明问题,但在我接受答案之前我希望得到更多反馈
    • Re 'int is the same as signed int' 等:除非你把它用作位域的类型!
    • +1 非常好的答案,从中学到了很多。不会 char 在任何一个平台上采用有符号字符或无符号字符之一吗?在这种情况下,重载如何工作?
    • 应该是“过载是如何工作的?”。但只需再次阅读 tkopec 的答案,就清楚地提到它们被视为不同的类型。我的坏
    【解决方案3】:

    更正确的说法是它是特定于编译器的,当使用没有 signedunsigned 限定符的 char 时,您不应指望 char 被签名或未签名。

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

    【讨论】:

    • 这是一个令人惊讶的行为示例:stackoverflow.com/questions/1097130/…
    • ISO 8859-1中的土耳其元音变音(ÿ,Unicode U+00FF)出现一个经典问题,字符代码为255 -1.
    【解决方案4】:

    也许您指的是char 的签名是编译器/平台特定的。下面是一篇博客文章,对它有所启发:

    Character types in C and C++

    【讨论】:

    • 我想这就是我实际阅读的内容!我已添加到我的问题中
    • 这回答了我的问题:为什么有些平台有unsigned char 而其他平台有signed char char
    【解决方案5】:

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

    【讨论】:

    • 很多人会说'一般来说,无符号字符没有用'这就是为什么 char 的签名在不同的实现中有所不同。
    • 这是我不明白的,肯定下签名的字符比签名的更有用吗?
    • 你实际上曾经为一个角色分配了一个负值,现在宽字符支持等比负值的字符更重要。
    • @Adam,没有足够的字符来填充 ANSI C/ISO C++(ASCII 字符集)中字节的每一位都没有关系,因此符号位更多很好的衡量标准。
    • @William Pursell:我从来没有觉得 'char' 被签名是有用的,而让它们不签名会使很多字符(文本)处理变得更简单。
    【解决方案6】:

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

    无符号字符始终为 8 位且没有符号位。

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

    【讨论】:

    • 字符并不总是 8 位。从历史上看,它通常是 9。目前,它通常是 16 或 32。char 中的位数是 CHAR_BIT,这取决于实现。
    • 我不相信这是正确的...parashift.com/c++-faq-lite/intrinsic-types.html#faq-26.4 明确指出 char == 1 字节和 1 byte == 至少 8 位?
    • gcc, msvc 默认将 char 识别为有符号字符。
    • Yossarian,对于 GCC,默认取决于它运行的平台。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-08
    • 2011-09-12
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多