我最近读到了
之间的区别char
unsigned char
和
signed char
是特定于平台的。
我不能完全理解这个问题?这是否意味着比特序列可以从一个平台到另一个平台变化,即平台1,标志是第一位,平台2标志可能在末尾?你会怎么反对这个?
基本上我的问题来自于看到这一行:
typedef unsigned char byte;
我不明白标牌的相关性?
答案 0 :(得分:18)
假设您的平台有8位字节,假设我们有位模式10101010
。对于signed char
,该值为-86。但是对于unsigned char
,相同的位模式代表170.我们没有移动任何位;它是相同的位,以两种不同的方式解释。
现在为char
。该标准没有说明这两种解释中的哪一种应该是正确的。保持位模式char
的{{1}}可以 -86 或 170.它将是这两个值中的一个,但是你有在预测编译器和平台之前,先了解它们。一些编译器提供命令行开关来控制它将是哪一个。某些编译器具有不同的默认值,具体取决于它们运行的操作系统,因此它们可以匹配操作系统约定。
在大多数代码中,它确实无关紧要。出于重载的目的,它们被视为三种不同的类型。指向其中一种类型的指针与指向另一种类型的指针不兼容。尝试使用10101010
或strlen
来呼叫signed char*
;它不会起作用。
如果需要单字节有符号数字类型,请使用unsigned char*
;如果需要单字节无符号数字类型,请使用signed char
。如果要保留字符,请使用普通旧unsigned char
。这就是程序员在编写你要求的typedef时的想法。名称“byte”没有保存字符数据的含义,而名称“unsigned char”在其名称中包含单词“char”,这导致某些人认为它是用于保存字符的好类型,或者将它与char
类型的变量进行比较是个好主意。
由于您不太可能对字符进行一般算术运算,因此char
在您使用的任何平台和编译器上是否已签名或未签名都无关紧要。
答案 1 :(得分:16)
你误会了什么。 signed char总是签名。 unsigned char始终是无符号的。但是普通字符是有符号还是无符号是特定于实现的 - 这意味着它取决于您的编译器。这与int类型有所不同,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是相同的。
答案 2 :(得分:3)
更正确地说它是特定于编译器的,并且在使用char
而没有char
或signed
限定符时,您不应指望unsigned
被签名或无符号。
否则您将面临以下问题:您编写并调试程序,假设默认情况下char
已签名,然后使用编译器重新编译,否则程序行为会发生巨大变化。如果您在代码中仅偶尔使用此假设,则在某些情况下可能会面临意外行为,这些行为仅在特定条件下在程序中触发,并且很难检测和调试。
答案 3 :(得分:2)
也许您指的是char
的签名是特定于编译器/平台的事实。这是一篇博客文章,对此有所了解:
答案 4 :(得分:0)
拥有一个有符号的字符更像是在C语言中处理所有基本变量类型的侥幸,通常情况下,负字符实际上并没有用。
答案 5 :(得分:-4)
有符号字符始终为8位,并且始终将有符号位作为最后一位。
unsigned char始终为8位且没有符号位。
就我所知,char总是无符号的。任何默认为签名字符的编译器都将面临许多不兼容的程序。