为什么字符串使用字符*
Why do strings use char*?
为什么 C/C++ stdlibs 中的大多数字符串函数都采用char*
指针?
标准中甚至没有指定char
的有符号性,尽管大多数现代编译器(GCC,MSVC)默认将char
视为有符号。
什么时候将字符串视为(可能)有符号字节才有意义?AFAIK 任何字符集中都没有低于零的有意义的字符值。对于某些字符串操作,无论如何都必须将值强制转换为unsigned char
。
那么为什么 stdlibs 使用char*
呢?甚至C++
特定的方法,例如string::string(const char *);
?
- 我很确定大多数字符串函数都早于
unsigned char
的存在。 - 纯
char
可以是有符号类型,也可以是无符号类型。C 和 C++ 标准明确允许其中之一(它始终是与unsigned char
或signed char
不同的类型,但与其中一个具有相同的范围)。 - 虽然C字符串函数使用
char *
,但大多数C++都使用std::string
。
C 标准在普通char
是有符号还是无符号的问题上是不可知的,并且独特地将char
与signed char
区别对待。此外,基本 ASCII 字符集(包括大多数主要控件和英语可打印字符)由 128 个字符组成,因此可以用有符号char
充分表示(至少在任何提供每字节 8 位的系统上)。正如 Jim Balter 指出的那样(见下面的评论),ASCII 并不构成 C 语言的完整基本字符集,但我怀疑它确实包含了大多数常用字符。还有一个庞大的 C 代码语料库依赖于 ASCII 的属性(尽管不一定是 ASCII 独有的)(例如,值为零的NUL
特殊字符,按顺序和升序排列的字母数字字符等)。
Jim Balter在评论中指出:
PDP-11 上处理字节的指令将它们视为有符号数量,所以这就是早期 C 编译器处理它们的方式,无符号甚至不存在。
我强烈怀疑这就是为什么默认字符类型char
不需要无符号的答案,但需要引用一些书面历史记载才能确定。
至于为什么它也不需要签名(!),在非二的补码机器上,例如(我知道唯一可能仍在使用的)Clearpath Dorado,signed char
不能保存unsigned char
的所有值,因为它在负零上浪费了一个位模式,或者该位模式用于的任何用途。如果需要对char
进行签名,那么将一般数据重新解释为char
值序列将是一个问题。因此,在这样的机器上,char
必须未签名,否则软件将不得不进行极端扭曲来处理它。
正如 Bjarne 在 The C++ Programming Language 中所说,char
是有符号还是无符号取决于实现,C++语言为每个实现提供了两种类型。
其他人已经探讨了当 C 首次被设计和(后来)标准化时它的历史原因,但还有另一个原因为什么这种看似异常现象一直持续到今天。
只是当您将char
用于字符时,您不需要知道它是有符号的还是无符号的。标准库提供了可移植的函数,用于对字符进行操作,而不管其表示形式如何。如果你忽略这些功能并坚持对字符进行比较和算术,你应该得到每一个错误。
举一个简单的例子,使用表达式 c >= ' '
或等效的 c >= 0x20
检查字符是否可打印是很常见的,但您应该改用isprint(c)
。这样,您就不会让自己陷入已签名/未签名的混淆,并可能将依赖于平台的错误引入程序。
一旦你养成了使用signed char
和unsigned char
只作为小(通常是 8 位)整数进行算术的习惯,并且在对字符数据进行操作时只使用 char
,那么char
是一个具有实现定义的符号性的单独类型似乎是完全自然的,更自然的是字符串处理函数总是使用 char
和 char *
而不是有符号或无符号变体。char
的签名性似乎与bool
的签名性一样重要。
不是有符号的,也不是无符号的。见 https://stackoverflow.com/a/2054941/396583
为什么 C/C++ stdlibs 中的大多数字符串函数都采用 char* 指针?
在C++中,使用std::string。在 C 语言中,引入无符号类型时,使用模式已经过于成熟,我不排除效率问题。
没有低于零的有意义的字符值
那么在C++标准的某个地方有一个约束,即基本字符集中的字符是正数。 但是,认为这种约束适用于所有角色是幼稚的。
该约束强制实现允许EBCDIC作为编码系统使其字符未签名。
大多数现代编译器(GCC,MSVC)默认将char视为签名。
GCC 行为取决于目标,并具有更改目标默认值的选项。
- 从 argv[1] 转换为字符 * 字符串后有什么问题?
- 将 NULL 与 C 的字符* 字符串一起使用
- 无法在声明时使用初始值设定项列表初始化常量字符*/字符串数组的向量
- 无法将常量字符字符串传递给模板类
- 如何组合一个宽字符字符串,中间插入一些空字符
- 如何将二维数组类型字符(字符串)作为函数参数传递?
- 从给定索引返回子字符字符串的函数
- 字符 [](c 字符串)的初始化标准
- 如何将字符字符串用作数学运算符
- 将 Unicode 字符/字符串写入文件
- C++,字符* 字符串修改
- 如何有效地用不同的整数元素替换字符字符串的元素
- C++:如果我们在字符串中添加一些整数,为什么它会从开头删除该数量的字符?(字符串 + 整数)
- strcpy正在复制sth字符i字符串.如何解决此错误
- 在C++中将双精度转换为字符*/字符串
- C 中的宽字符字符串
- 如何提取C 中的字符/字符串之间的字符串
- 无法将字符/字符串转换为int
- 带有指针的反转字符字符串
- 反转字符串中的 n 个字符(字符串中没有空格),而不使用 c++ 中的内置函数