所有的 字符串 都可以被视为 字符数组 (是的),但不是所有的 字符数组 都可以被视为 字符串 (不是的)。
为什么不是?为什么很重要?
除了其他回答解释字符串的长度没有作为字符串本身的一部分存储以及引用字符串定义标准的答案外,另一方面是 "C 库函数如何处理字符串?"
虽然字符数组可以容纳相同的字符,但它只是一个字符数组,除非最后一个字符之后跟随 空字符。这个 空字符 是使字符数组能够被视为(处理为)字符串的原因。
C 中的所有期望参数为字符串的函数都期望字符序列以 空字符 结尾。为什么呢?
这与所有字符串函数的工作方式有关。由于长度不作为数组的一部分包含在内,字符串函数会在数组中向前扫描,直到找到 空字符 (例如,'\0'
-- 相当于十进制 0
)。请参阅 ASCII 表和说明。无论您是使用 strcpy
、strchr
、strcspn
等函数,所有字符串函数都依靠存在 空字符 来定义字符串的结束位置。
通过比较 string.h
中两个类似函数的例子,可以强调 空字符 的重要性。例如:
char *strcpy(char *dest, const char *src);
strcpy
函数只是简单地将字节从src
复制到dest
,直到找到nul-terminating字符,告诉strcpy
在哪里停止复制字符。现在看一下类似的函数memcpy
:
void *memcpy(void *dest, const void *src, size_t n);
该函数执行类似的操作,但不考虑或要求src参数为字符串。由于memcpy无法简单地在src中向前扫描,将字节复制到dest直到达到nul终止字符,因此需要显式指定要复制的字节数作为第三个参数。这第三个参数提供了与strcpy相同的大小信息,strcpy只需向前扫描,直到找到nul终止字符即可推导出该信息。
(这也强调了如果未向期望字符串的任何函数(如strcpy)提供nul终止字符串,会发生什么错误 - 它不知道在哪里停止,并且会快乐地跑过内存段引发未定义行为,直到在内存中偶然发现nul字符- 或者发生分段错误)
这就是为什么期望nul终止字符串的函数必须传递nul终止字符串并且为什么它很重要的原因。
char *str = "hello";
...str[0] = foo;
的问题。 - Jabberwocky0
,或者根据上下文,是指向包含后续元素中的0
的字符数组元素的指针。 - pmgchar[n+1]
的范例数十年,显式地为字符串声明提供了空间以容纳空终止符号。它是“自我记录代码”的真正例子。 - David R Tribble