如果在C语言中字符串数组是以空字符结尾的,那么为什么其他数据类型的数组不以空字符结尾呢?

8

在C语言中,字符串或字符数组必须以null结尾,以便知道它们何时结束。为什么其他类型的数组不遵循同样的规则呢?例如,计算机如何知道整数数组何时结束?在内存中表示整数/浮点数/双精度浮点数数组是否有区别?


2
一个C字符串和一个“字符数组”并不是同一回事。一个字符数组不需要以0结尾。 - Sean Bright
为什么其他类型的数组不适用于相同的规则呢?- 实际上是适用的。一些库需要空/零/某些额外字符分隔的数据。举个例子,getopt_long 使用以 {0,0,0,0} 结尾的数组。只是恰好“字符串”由 C 标准定义,并且 C 标准库支持它们。 - KamilCuk
@KamilCuk 为什么要使用第三方库?main中的 argv 已经是以空指针结尾的了 :) - Ruslan
“其他数据类型” 可以包含多个零,这些零是这些类型的合法成员。因此,零不能作为有效的数组结束标记。 - Eugene Sh.
那是个好例子 - argcargv结合在一起可能是两种方法的例子 - 你可以在argc中得到数量,而且argv仍然以null结尾。这只是一种惯例。根据使用情况使用最佳方法。 - KamilCuk
4个回答

4

字符数组不一定需要以空字符结尾。

char foo[3]="foo"; //not nul-terminated
char bar[]={'b','a','r'}; //not nul-terminated

其实字符串字面量就是以nul结尾的数组,而C语言非常容易通过使用字符串字面量作为初始化器来创建以nul结尾的数组:

 char baz[]="baz"; //nul-terminated because "baz" is

C语言之所以这样做,是因为设计者们的选择,因为使用终止符比维护字符计数对他们来说更方便,其原因可以参考这里

但是C语言并没有强制要求你遵循这种偏好。


"string literal"和"string"是相似但不同的C语言概念。对于关于"string"和"字符数组"的问题,使用"string literal"的答案会更加复杂。 - chux - Reinstate Monica

2
在C语言中,字符串是由一系列的char字符组成,并以空字符结尾。它是char数组的一个特例。
你也可以有一个char数组是没有以空字符结尾的。例如:
char x[] = { 'a', 'b', 'c' };

通常情况下,数组在内存中表示为基本类型的连续序列。语言本身不会跟踪数组的大小,您需要自己管理。

2
简短回答:因为C语言是这样定义的。
更长回答:C字符串本身并没有什么特别之处。它们是包含字节的内存块,就像其他块一样。但是通过定义以0结尾的约定,所有函数都可以同意处理字符串的方式。
它们可以以强制你单独处理长度并始终向每个函数提供指针和长度的方式完成。那很麻烦,所以最好只使用终止符。在连接等情况下也会更慢,因为首先必须查找结束位置。
至于为什么它不与其他类型一起使用,有时确实会使用。原因相同:它被视为约定,并且与字符串一样。我们不知道有多少个值,因此我们在末尾有一个哨兵值。它可以是null、0或其他值。但是我们也可以不这样做,并单独提供元素数量。

有时使用哨兵值是不可能的或不必要的,例如我们需要整个数据类型或知道数据的大小。例如,如果我们有一张RGB图像,我们如何定义结束值?我们需要所有字节可以有的值来定义颜色,因此我们不能有一个哨兵值。我们也不需要一个,因为我们知道图像的大小。

至于计算机,它对数据一无所知。它只能处理字节和单词以及它被构建来处理的任何东西。字符串在更高级别上进行处理,并完全在所使用的语言库中处理。处理器仅根据您告诉它要执行的操作移动数据。例如,PC BIOS在打印字符串时使用$作为终止字符,而不是0。


1
通常情况下,您会将数组的长度与指针一起传递。没有任何东西“知道”任何东西的长度。
内存就是内存。一个字节的数组中可能包含0x42 0x41 0x44 0x00,这恰好是“BAD”的字符串。但它也可以是表示“1145127936”的整数或表示“773.0625”的浮点数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接