21

为什么 C/C++ 标准库中的大多数字符串函数都采用char*指针?

尽管大多数现代编译器(GCC,MSVC)默认情况下都将其视为已签名char,但标准中甚至没有指定 的char签名。

何时将字符串视为(可能)有符号字节有意义?AFAIK 在任何字符集中都没有低于零的有意义的字符值。unsigned char对于某些字符串操作,无论如何都必须将值强制转换为。

那么为什么 stdlibs 使用char*? 甚至C++- 特定的方法,例如string::string(const char *);?

4

7 回答 7

10
  1. 我很确定大多数字符串函数早于unsigned char.
  2. Plainchar可以是有符号或无符号类型。C 和 C++ 标准明确允许其中任何一个(它始终是与 or 不同的类型unsigned charsigned char但与一个或另一个具有相同的范围)。
  3. 虽然 C 字符串函数使用char *,std::string是大多数 C++ 中使用的。
于 2012-06-24T03:27:23.993 回答
10

C 标准对于 plain 是有符号还是无符号的问题是不可知的char,并且唯一地char区别于signed char. 此外,包含大多数主要控制字符和英语可打印字符的基本 ASCII 字符集由 128 个字符组成,因此可以用带符号的字符充分表示char(至少在任何提供每字节 8 位的系统上)。正如 Jim Balter 所指出的(参见下面的评论),ASCII 并不构成 C 语言的完整基本字符集,但我怀疑它确实包含了大多数常用字符。还有一个庞大的 C 代码语料库依赖于 ASCII 的属性(尽管不一定是唯一的)(例如,NUL值为零的特殊字符、字母数字字符按顺序和升序排列等)。

于 2012-06-24T03:30:58.817 回答
5

Jim Balter 在评论中指出

PDP-11 上处理字节的指令将它们视为有符号量,因此早期的 C 编译器就是这样处理它们的,而 unsigned 甚至不存在。

我强烈怀疑这是为什么默认字符类型char不需要无符号的答案,但是为了确定,需要从一些书面历史记录中引用。

至于为什么不需要在非二进制补码机器上签名(!),例如(我知道的唯一一个可能仍在使用的)Clearpath Dorado,asigned char不能保存 an 的所有值unsigned char,因为它在负零上浪费了一个位模式,或者该位模式用于任何用途。如果char需要签名,那么将一般数据重新解释为char值序列将是一个问题。因此,在这样的机器char上必须是未签名的,否则软件将不得不进行极端的扭曲来处理它。

于 2012-06-24T10:47:56.697 回答
2

正如 Bjarne 在The C++ Programming Language中所说,是否将 achar视为有符号或无符号取决于实现,并且 C++ 语言为每个实现提供两种类型。

于 2012-06-24T03:35:06.587 回答
2

其他人已经探讨了当 C 最初被设计和(后来)标准化时这种情况的历史原因,但还有另一个原因是这种看似异常的现象一直持续到今天。

很简单,当你使用charfor 字符时,你不需要知道它是有符号还是无符号。标准库提供了对字符进行操作的可移植函数,而不管其表示形式如何。如果您忽略这些函数并坚持对字符进行比较和算术运算,那么您应该得到每个错误。

c >= ' '举一个简单的例子,使用表达式或等效检查字符是否可打印是很常见的c >= 0x20,但您应该只使用isprint(c)。这样,您就不会将自己暴露在有符号/无符号的混淆中,也不会在程序中引入与平台相关的错误。

一旦你养成了只使用小整数(通常是 8 位)进行算术运算的习惯,并且仅在对字符数据进行操作时使用,那么使用signed char实现定义的单独类型似乎是完全自然的符号性,甚至更自然的是字符串处理函数总是使用and而不是有符号或无符号变体。的符号似乎与 的符号一样相关。unsigned charcharcharcharchar *charbool

于 2012-06-29T00:20:47.977 回答
0

Char 既不是标准的签名也不是无符号的。见https://stackoverflow.com/a/2054941/396583

于 2012-06-24T03:27:34.840 回答
0

为什么 C/C++ 标准库中的大多数字符串函数都采用 char* 指针?

在 C++ 中使用 std::string。在 C 中,当引入无符号类型时,使用模式已经非常成熟,我不会排除效率问题。

没有低于零的有意义的字符值

那么在 C++ 标准中的某个地方有一个约束,即基本字符集中的字符是正数。但认为这种约束适用于所有角色是天真的。

该约束强制允许 EBCDIC 作为编码系统的实现使其 char 无符号。

大多数现代编译器(GCC、MSVC)默认将 char 视为已签名。

gcc 行为取决于目标,并具有更改目标默认值的选项。

于 2012-06-24T08:26:40.887 回答