c - 为什么 C 中的字符串函数对带有 char 而不是 unsigned char 的数组起作用?

标签 c string

C 标准库函数中,字符串的元素是char。有充分的理由决定它而不是 unsigned char 吗?

对 8 位字符串使用 unsigned char 有一些优势,尽管优势不大:

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

最佳答案

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

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

char 是有符号类型还是无符号类型是实现定义的,所以我认为这个问题相当于“为什么 char 存在,因为这可能-签名类型?”或者“为什么 C 不要求 char 是无符号的?”。

首先要知道的是,Ritchie 在 1971 年将“char”类型添加到 B 语言中,C 从那里继承了它。在此之前,B 是面向字而非字节的( so says the man himself ,参见“B 的问题”。)

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

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

鉴于 char 将成为字符类型,并且(正如您所观察到的)它是无符号的很有意义,但是已经存在大量的实现,其中 char已签名,我认为使 char 实现定义的签名是一种可行的妥协——现有代码将继续工作。如果它仅将 char 用作字符而不用于算术或顺序比较,它也可以移植到 char 未签名的实现。

与 C 的一些古老的实现定义的变体不同,实现者仍然选择带符号的字符 (Intel)。 C 标准委员会不得不观察到有些人似乎出于某种原因坚持使用带符号的字符。无论这些人的原因是什么,当前的还是历史的,C 都必须允许它,因为现有的 C 实现依赖于它被允许。因此,在可实现的目标列表中,强制 char 为 unsigned 远低于强制 int 为 2 的补码,C 甚至没有做到这一点。

一个补充问题是“为什么英特尔仍然指定要在其 ABI 中签名的 char?”,我不知道答案,但我猜他们从来没有一个在没有大规模破坏的情况下做其他事情的机会。也许他们甚至喜欢它们。

关于c - 为什么 C 中的字符串函数对带有 char 而不是 unsigned char 的数组起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12106155/

相关文章:

php - 试图从 PHP 执行用 C 编译的文件

python - Python 中 2 个列表中字符串中的常见字符

Java 开关始终运行默认代码

java - 将字符串数组拆分为二维字符数组

c# - 如何使用字符串作为索引?

c# - 如何使用 String.Replace

c - 按位操作地址

c++ - 具有 C 链接和 C++ 实现的不透明结构

c++ - C 和 C++ 调用函数时 EAX 寄存器初始化的差异

c - 查找乌拉姆序列 C 中的数字