为什么C / C ++ stdlibs中的大多数字符串函数都需要char*
个指针?
char
的签名甚至没有在标准中指定,但大多数现代编译器(GCC,MSVC)都将char
视为默认签名。
什么时候将字符串视为(可能)有符号字节是有意义的? AFAIK在任何字符集中都没有低于零的有意义的字符值。对于某些字符串操作,无论如何都必须将值转换为unsigned char
。
那么为什么stdlibs会使用char*
?甚至C++
- 具体方法,例如string::string(const char *);
?
答案 0 :(得分:10)
unsigned char
。char
可以是有符号或无符号类型。 C和C ++标准明确允许任何一个(它始终是unsigned char
或signed char
的单独类型,但与一个或另一个具有相同的范围。)char *
,但std::string
是大多数C ++中使用的函数。答案 1 :(得分:10)
C标准与普通char
是签名还是未签名的问题无关,并且唯一地将char
视为与signed char
不同。此外,基本ASCII字符集包括大多数主要控制字符和英语可打印字符,由128个字符组成,因此可以用签名的char
充分表示(至少在每个字节提供8位的任何系统上) )。正如Jim Balter指出的那样(参见下面的评论),ASCII并不构成C语言的完整基本字符集,但我怀疑它确实包含了大多数常用字符。还有一大块C代码依赖于ASCII的属性(虽然不一定是唯一的)(例如,NUL
特殊字符的值为零,字母数字字符按顺序和按升序排列,等等)。
答案 2 :(得分:5)
Jim Balter在评论中指出
处理字节的PDP-11上的指令将它们视为有符号数量,因此早期的C编译器对它们进行处理,而无符号甚至不存在。
我强烈怀疑这是为什么默认字符类型char
不需要是无符号的答案,但是为了确保这一点需要来自某个书面历史帐户的引用。
至于为什么不需要在非二进制补码机上签名(!),例如(我知道可能仍在使用的唯一一个)一个Clearpath Dorado,signed char
不能保存unsigned char
的所有值,因为它在负零上浪费了一个位模式,或者无法使用该位模式。如果需要对char
进行签名,那么将一般数据重新解释为char
值序列将是一个问题。因此,在这样的机器上char
必须是未签名的,否则软件将不得不进行极端扭曲来处理它。
答案 3 :(得分:2)
正如Bjarne在 C ++编程语言中所说,char
是否被认为是有符号或无符号是依赖于实现的,而C ++语言为每个实现提供了两种类型。
答案 4 :(得分:2)
其他人已经进入历史原因,当C首次设计和(后来)标准化时,它就是这种方式,但另一个原因是为什么这种看似异常的现象持续到今天。
只是当您使用char
字符时,不需要来知道它是已签名还是未签名。标准库提供了用于对字符进行操作的便携式函数,无论其表示如何。如果你忽略这些功能并坚持对字符进行比较和算术运算,那么你应该得到所有的错误。
举一个简单的例子,使用表达式c >= ' '
或等效c >= 0x20
来检查字符是否可打印是很常见的,但您应该只使用isprint(c)
。这样,您就不会暴露自己的签名/未签名混淆,并可能将与平台相关的错误引入您的程序。
一旦你习惯使用signed char
和unsigned char
作为算术的小(通常是8位)整数,你在操作时只使用char
字符数据,char
是一个具有实现定义的签名的独立类型似乎是完全自然的,更自然的是字符串处理函数总是使用char
和char *
而不是签名或无符号变体。 char
的签名似乎与bool
的签名相关。
答案 5 :(得分:0)
Char既没有签名也没有签名。见https://stackoverflow.com/a/2054941/396583
答案 6 :(得分:0)
为什么C / C ++ stdlibs中的大多数字符串函数都采用char *指针?
在C ++中,使用std :: string。在C中,当引入无符号类型时,使用模式已经过于确定,我不会排除效率问题。
零以下没有有意义的字符值
在C ++标准的某处,有一个约束,即基本字符集中的字符是正数。但是认为这种约束适用于所有角色是天真的。
该约束强制实现允许EBCDIC作为编码系统使其char无符号。
大多数现代编译器(GCC,MSVC)都将char视为默认签名。
gcc行为取决于目标,并具有更改目标默认值的选项。