
9.4 字符串的指针和指向字符串的指针变量
9.4.1 字符串表示形式
1.用字符数组实现
前面章节学习过该范例,这里回顾一下,观察其输出结果,这就是字符数组,处理字符串就用这种字符数组的方式:

设置一个断点,看一看上面的mystr1、mystr2内存的样子,注意字符串末尾的'\0',是字符串结束标记,如图9.24所示。
其中,mystr1、mystr2都是字符数组名,代表字符数组首地址。那显然mystr1==&mystr1[0],而mystr2==&mystr2[0],并且要注意,mystr1和mystr2所代表的地址并不相同,这意味着字符串"IloveChina"被保存到了两块不同的内存中,也就是说,"Ilove China!"是字符串常量,把这个字符串常量分别复制到了这两个字符数组所代表的内存中去了。

图9.24 跟踪调试,查看字符串中的内容
2.用字符指针实现
如下代码行:

跟踪调试,如图9.25所示。

图9.25 字符指针指向一个字符串常量
通过跟踪调试上面的代码,注意到这样一个事实,pmystr1指向的地址等于pmystr2指向的地址,都指向这个字符串"IloveChina!",读者一定会有疑问,为什么在用字符数组实现时是把字符串常量"Ilove China!"分别复制到两个不同的字符数组中去了,而这里这两个字符指针却指向了一个相同的地址?
这是因为:这段代码没有定义字符数组,也就是没有内存来保存"IloveChina!"这一堆字符。实际上,读者要明白,首先"Ilove China"是字符串常量,C语言中对字符串常量有特殊的处理,那就是在内存中会开辟出一块专门的地方来存放字符串常量。所以,这个"Ilove China"是存在于专门开辟出的这块内存中,并且有一个固定内存地址。
那“constchar*pmystr1="IloveChina!";”这行相当于把内存中这个字符串常量的首地址赋给了指针pmystr1导致pmystr1指向该字符串常量。同理,“char *pmystr2="Ilove China!";”相当于把内存中这个字符串常量的首地址赋给了指针pmystr2导致pmystr2指向该字符串常量,因为都是同一个字符串常量"IloveChina",所以首地址必然相同,所以pmystr1和pmystr2指向的地址相同。同时,要注意,因为这块专门存放字符串常量的内存是只读的,所以,不能修改这块内存的内容,例如如果写“pmystr2[3]='c';”,这样的代码必然会使系统报错。
对字符串中字符的存取,可以用下标方法,也可以用指针方法。演示代码如下,先用下标方法尝试一下:

修改一下上面的范例,这回用指针变量来尝试一下。演示代码如下:
