为什么字符串使用char *?

时间:2012-06-24 03:24:17

标签: c++ c

为什么C / C ++ stdlibs中的大多数字符串函数都需要char*个指针?

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

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

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

7 个答案:

答案 0 :(得分:10)

  1. 我很确定大多数字符串函数早于unsigned char
  2. 的存在
  3. 普通char可以是有符号或无符号类型。 C和C ++标准明确允许任何一个(它始终是unsigned charsigned char的单独类型,但与一个或另一个具有相同的范围。)
  4. 虽然C字符串函数使用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 charunsigned char作为算术的小(通常是8位)整数,你在操作时只使用char字符数据,char是一个具有实现定义的签名的独立类型似乎是完全自然的,更自然的是字符串处理函数总是使用charchar *而不是签名或无符号变体。 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行为取决于目标,并具有更改目标默认值的选项。