4.8.3 指针和字符串(1)
数组和指针的特殊关系可以扩展到C-风格字符串。请看下面的代码:
数组名是第一个元素的地址,因此cout语句中的flower是包含字符r的char元素的地址。cout对象认为char的地址是字符串的地址,因此它打印该地址处的字符,然后继续打印后面的字符,直到遇到空字符(\0)为止。总之,如果给cout提供一个字符的地址,则它将从该字符开始打印,直到遇到空字符为止。
这里的关键不在于flower是数组名,而在于flower是一个char的地址。这意味着可以将指向char的指针变量作为cout的参数,因为它也是char的地址。当然,该指针指向字符串的开头,稍后将核实这一点。
前面的cout语句中最后一部分的情况如何呢?如果flower是字符串第一个字符的地址,则表达式"s are red\n"是什么呢?为了与cout对字符串输出的处理保持一致,这个用引号括起的字符串也应当是一个地址。在C++(www.cppentry.com)中,用引号括起的字符串像数组名一样,也是第一个元素的地址。上述代码不会将整个字符串发送给cout,而只是发送该字符串的地址。这意味着对于数组中的字符串、用引号括起的字符串常量以及指针所描述的字符串,处理的方式是一样的,都将传递它们的地址。与逐个传递字符串中的所有字符相比,这样做的工作量确实要少。
注意:在cout和多数C++(www.cppentry.com)表达式中,char数组名、char指针以及用引号括起的字符串常量都被解释为字符串第一个字符的地址。
程序清单4.20演示了如何使用不同形式的字符串。它使用了两个字符串库中的函数。函数strlen( )我们以前用过,它返回字符串的长度。函数strcpy( )将字符串从一个位置复制到另一个位置。这两个函数的原型都位于头文件cstring(在不太新的实现中,为string.h)中。该程序还通过注释指出了应尽量避免的错误使用指针的方式。
程序清单4.20 ptrstr.cpp
下面是该程序的运行情况:
程序说明
程序清单4.20中的程序创建了一个char数组(animal)和两个指向char的指针变量(bird和ps)。该程序首先将animal数组初始化为字符串"bear",就像初始化数组一样。然后,程序执行了一些新的操作,将char指针初始化为指向一个字符串: