为什么C中的字符串函数在使用char而不是unsigned char的数组上工作?

vsz*_*vsz 9 c string

在C标准库函数中,字符串的元素是chars.是否有一个很好的理由来决定它而不是unsigned char?

使用unsigned char8位字符串有一些虽然小的优点:

  • 它更直观,因为我们通常将ASCII码记忆为无符号值,并且在处理二进制数据时,我们更喜欢范围0x00到0xFF,无符号,而不是处理负数.所以我们要投.
  • 使用无符号整数可能更快/更有效,或者在某些处理器上生成更小的代码.

Ste*_*sop 11

C提供三种不同的字符类型:

  • char 表示一个字符(C也称为"字节").
  • unsigned char 表示字节大小的位模式,或无符号整数.
  • signed char 表示字节大小的有符号整数.

它是实现定义的,无论char是有符号类型还是无符号类型,所以我认为这个问题相当于"为什么它根本就char存在这个可能签名的类型?" 或"为什么C不需要char签名?".

首先要知道的是,Ritchie在1971年为B语言添加了"char"类型,C从那里继承了它.在此之前,B是面向字的而不是字节导向的(所以说这个人自己,参见"B的问题".)

完成后,我的两个问题的答案可能是C的早期版本没有无符号类型.

一旦char建立了字符串处理函数,将它们全部更改unsigned char为一个严重的重大变化(即几乎所有现有代码都将停止工作),并且C在过去几十年中试图培养其用户群的方法之一是主要是避免灾难性的不相容变化.因此,C做出改变会令人感到意外.

鉴于它将char是字符类型,并且(正如你所观察到的那样)它对于无符号很有意义,但是已经存在大量已经存在的char签名,我想这使得char的签名实现定义是一个可行的妥协 - 现有代码将继续工作.如果它char仅用作字符而不用于算术或顺序比较,那么它也可以移植到char无符号的实现.

与C的一些古老的实现定义的变体不同,实现者仍然选择签名字符(英特尔).C标准委员会不禁发现,有些人出于某种原因似乎坚持使用签名字符.无论这些人的原因是当前的还是历史的,C必须允许它,因为现有的C实现依赖于它被允许.所以强迫无条件char在可实现的目标列表中远远低于强制int为2的补码,而C甚至没有这样做.

一个补充问题是"为什么英特尔仍指定char在其ABI中签名?",我不知道答案,但我猜他们从来没有机会在没有大量中断的情况下做其他事情.也许他们甚至喜欢他们.