C 语言中的字符指针与字符数组

昨天晚上和今天上午,一直在琢磨《剑指offer》上的面试题5:替换空格 ,之后还给书的作者提交了一个 issue,这道题目也就告一段落了。耗费了这么长的时间,其实大多时间都卡壳在字符指针和字符数组差异上,对这两种 C 语言中字符串的表示没有很深刻的理解,现在明白了点,遂记载如下,以防下次又给忘了。

以下摘自 C 程序设计语言(第2版) 5.5 字符指针与函数,中文版页码 89。

字符串常量 是一个字符数组,例如:

"I am a string";

在字符串的内部表示中,字符数组以空字符 '\0' 结尾,所以,程序可以通过检查空字符找到字符数组的结尾。字符串常量占据的存储单元数也因此比双引号内的字符数大 1。

字符串常量最常用的用法也许是作为函数参数,例如:

printf("hello, world\n");

当类似于这样的一个字符串出现在程序中时,实际上是通过字符指针访问该字符串的。在上述语句中,printf 接受的是一个指向字符数组第一个字符的指针。也就是说,字符串常量可通过一个指向其第一个元素的指针访问。

除了作为函数参数外,字符串常量还有其他用法。假定指针 pmessage 的声明如下:

char *pmessage;

那么,语句

`pmessage = "now is the time";`

将把一个指向该字符数组的指针赋值给 pmessage。该过程并没有进行字符串的复制,而知识涉及到指针的操作。C 语言没有提供将整个字符串作为一个整体进行处理的运算符。下面两个定义之间有很大的差别:

char amessage[] = "now is the time"; /* 定义了一个数组 */

char *pmessage = "now is the tiem"; /* 定义了一个指针 */

上述声明中, amessage 是一个仅仅保存足以存放初始化字符串以及空字符 '\0' 的一维数组。 数组中的单个字符可以进行修改 ,但 amessage 始终指向同一存储位置 。另一方面,pmessage 是一个指针,其初值指向一个字符串常量,之后它可以被修改以指向其他地址,但如果试图(通过 pmessage 指针) 修改字符串的内容,结果是没有定义的(会出现段错误 Segment Fault )。

另外,在页码 85 中有描述

在函数定义中,形式参数 char s[];char *s; 是等价的。我们通常更习惯于使用后一种形式,因为它比前者更直观地表明了这个参数是一个指针。如果将数组名传递给函数,函数可以根据情况判定是按照数组处理还是按照指针处理,随后根据相应的方式操作该参数。为了直观且恰当地描述函数,在函数中甚至可以同时使用数组和指针这两种表示方法。

版权声明

本作品采用知识共享署名 4.0 国际许可协议进行许可,转载时请注明原文链接。