【问题标题】:What Is the "character" in string's definition?字符串定义中的“字符”是什么?
【发布时间】:2014-06-13 22:42:40
【问题描述】:

C11 将“字符串”定义为:

string 是一个以 and 结尾的连续字符序列 包括第一个空字符。 §7.1.1 1

前面将“字符”定义为:

3.7 字符
用于组织、控制或表示数据的一组元素的成员

3.7.1 角色
单字节字符
一个字节的位表示

3.7.2 多字节字符
代表扩展字符集成员的一个或多个字节的序列...

3.7.3 宽字符
由 wchar_t 类型的对象表示的值,能够表示任何字符 在当前语言环境中

问题:“字符串”的定义中使用了“字符”的什么定义:
3.7 中的“字符”,
3.7.1 中的“字符”,
还是别的什么?

【问题讨论】:

  • 以上所有。
  • 旁白:阅读3.7.3,宽字符串不能使用UTF-16。
  • 阅读Representation of Strings可能会有所帮助
  • @Deduplicator:对。如果“当前语言环境”仅包含 BMP,则可以使用 16 位 wchar_tUCS-2。

标签: c language-lawyer


【解决方案1】:

字符串是char类型的连续数据序列。
“人物”一词有两种含义,抽象的和实用的。
从抽象的角度来看,我们首先必须定义“字符集”的概念,以便稍后转到 3.7 并说“用于...的元素集的成员”。
这个“字符”的定义符合另一个标准:ISO/IEC 2382-1。

ISO/IEC 2382-1(character)

在那里,您可以分析与“信息表示”相关的大量术语。

我的简短回答:“字符串”定义中的“字符”对应于c11.3.7.1。
解释如下:

摘要中的人物

符号是人类的知识惯例。
因此,“A”的抽象符号是我们用来识别不同“图”(如 A、AA)的约定,它们都是“相同”的东西(比如说一条信息)。
然后,信息由一组(抽象)字符的有序和有限序列表示。
接下来,您需要对这些抽象符号进行编码,以使其在信息系统(计算机)中的表示成为可能。
通常,这是通过在给定集合中定义整数(称为代码点)与其对应字符之间的一一对应关系来完成的。
编码模式是一种将一组字符与特定数字(代码点)相关联的方式。
此编码可以从一个系统更改为另一个系统(“A”在 EBCDIC 中的编码与在 ASCII 中的编码不同)。
最后,我们为每个字符+代码点关联一个“图形”,即一种书面表示,最终可以打印或显示在屏幕上。
图形的形状可以根据字体设计而改变,因此定义术语“字符”不是一个好的起点。

C 中的字符

在 3.7.1 中。似乎 C11 指的是“字符”的另一种含义,旨在成为“单字节字符”的简短形式。它正在讨论恰好适合 1 个字节的代码点(即与“给定集合的抽象字符”相关联的整数)。
在这种情况下,我们需要 Byte 的定义。
在C语言中,一个字节是一个信息存储单元,由n位的有序序列组成,其中n是大于或等于 8(当然一般是 8),你可以通过检查 <limits.h> 中的常量 CHAR_BIT 来找到它的值。

有些数据类型的大小正好是 1 个字节:char, unsigned char, signed char
unsigned char 的取值范围正好是 0...2^n - 1,其中 nCHAR_BIT
char的取值范围与signed charunsgined char一致,但C11并没有说它们中的哪一个对应char
此外,在任何情况下,char 类型必须被认为不同于signed charunsigned char

现在,字符串是char 类型的对象序列。

为什么要使用 CHAR?

标准用char定义了字符的表示:

(6.2.5.3)

声明为 char 类型的对象足够大,可以存储基本的任何成员 执行字符集。如果基本执行字符集的成员存储在 char 对象,其值保证为非负数。如果任何其他字符存储在 一个 char 对象,结果值是实现定义的,但应在范围内 可以在该类型中表示的值。

字符串

现在,C 中的字符串是 (单字节)字符 的连续序列,以空字符结尾,在 C 中始终为 0。
这个定义可以用抽象的方式再次理解,但是在 7.1.1.1 中,文本谈到了字符串的地址,因此必须理解“字符串”是内存中的对象。 那么,“字符串”对象就是一个连续的“字节”序列,每个字节都包含一个字符的代码点。

这是因为“字符”旨在完全适合 1 个字节。
它在 C 中由 char 类型的数组表示,其最后一个元素为 0。

多字节字符

“多字节”的定义很复杂。
它指的是一些使用可变字节数来表示(抽象)字符的特殊编码模式。
您需要有关执行字符集的信息才能正确处理多字节字符集。
但是,即使您有一个多字节字符,它仍然在内存中表示为一个字节序列。

这意味着您将再次将多字节字符串表示为array of char。 执行系统解释这些字节的方式是一个不同的问题。

宽字符

宽字符是另一组(抽象)字符中的一个元素,与char 类型中表示的字符不同。
旨在使“宽字符”集大于“单字节字符”集。
但情况不一定如此。

“宽字符”的相关事实如下:

  • “宽字符”集,无论它们是什么,都可以用wchar_t 类型的值范围来表示。
  • 这些字符可能与char 类型中表示的字符不同。
  • “宽字符”可以使用超过 1 个字节的存储空间。
  • “宽字符串”是以空字符结尾的连续“宽字符”序列。

因此,“宽字符串”与“字符串”是不同的对象。

结论

字符串与“宽”字符无关,而只是“单字节字符”。
字符串是一个以空值结尾的连续“字节”序列,这又意味着一些 char 类型的对象:char, signed char, unsigned char,对应于适合 1 个字节的抽象字符集的代码点。

【讨论】:

  • 我对这个短语的精度有一些问题:“由第一个空字符终止并包括第一个空字符” 那么,concat 函数会丢弃字符吗?字符串长度函数是一对一的吗?字符串结束指针不是超越的吗?字符集必须有一个空字符?如果它将其空字符编码为 0 以外的值怎么办?如果它没有任何编码为 0 的字符怎么办?我认为终止符不是字符串的一部分,也不是字符集中的 字符; 它只是 0,如果字符集确实有一个编码为 0 的字符,则不能用一个字符串。
  • @TomBlodget 问题太多...我无法正确回答此 cmets 中的所有问题。
  • @Tom Blodget 我会尝试一个:“字符串长度函数是一对一的吗?”。 strlen() 根据定义返回 '\0' 之前的字符数。因此,即使包含'\0' 在内的字符串定义,strlen() 的定义正如您所建议的“off by-one”,因为它不会返回字符串中char 的数量。相反,strlen()定义 影响,但不包括 '\0' 在其返回值中。 sizeof("1234") 确实返回 5。
  • 我之前的修辞问题是题外话。该标准确实要求执行字符集具有空字符并将其编码为 0。因此终止符问题与所提出的问题或@pablo1977 的出色答案无关。
猜你喜欢
  • 2020-06-06
  • 2014-11-20
  • 2022-01-21
  • 2012-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多