您的位置:首页 > 编程语言 > C语言/C++

深入理解字符串指针和字符串数组

2016-05-30 16:28 253 查看
首先我们来看一段程序:

#include <stdio.h>

int main()
{
char str[] = "hello code";
char *ps = "hello code";
char *p = str;

printf("str: %s\n",str);
printf("&str: %s\n",&str);
printf("&&str: %s\n",&p);
printf("&&str: %p\n",&p);
printf("---------------------------------\n");
printf("ps: %s\n",ps);
printf("&ps(s): %s\n",&ps);
printf("&ps(p): %p\n",&ps);

return 0;
}


它的输出结果如图:



分析:我们首先声明了一个字符串数组和一个字符串指针。然后将他们等同类型的输出做对比。

从输出结果我们可以看到,想要输出整个字符串。分别以%s格式输出str和ps即可。

1.字符串指针名ps和数组名str都存放着字符串的首地址。而字符串本身存放在以该首地址为首的一块连续的内存空间中,并以 '\0' 作为串的结束。

2.对str和ps分别取地址,以%s格式输出。

&str: 输出的结果仍然是字符串。

&ps: 输出的结果为乱码。

那么,这是什么原因呢?

实际上,对于字符串数组,str和&str都一样,都是字符串数组str[]的首地址。但类型不一样,一个是指向char的指针,一个是指向整个数组的指针。但是对他们分别+1效果就不一样了,一个偏移sizeof(char),一个偏移sizeof(char)*11(也就是整个数组的大小)。所以字符串数组可以理解为存在“双层地址”,但是这两个地址值都是一样的,都指向字符串首地址。

而对于字符串指针,ps和&ps相去甚远了。ps是整个字符串的首地址,由于并不存在类似数组的"双层地址“结构,所以ps已经是指向字符串最底层最基本的地址了,不具有数组名这一地址,只具有“单层地址”,所以对它进行&操作,然后以%s格式输出,这是不合法的,将一个地址以%s输出只能得到乱码。

3.如上图:对于字符串数组,我们加入了一个指针变量p,使它指向str,然后进行&p(相当于&&str)操作,以%s格式输出,结果才出现乱码。而对于字符串指针,只以%s格式输出&ps操作结果就显示乱码。我们将&&str和&ps分别以%p格式打印出来,输出结果显示为正常地址。证实了我们的“双层地址”和“单层地址”一说。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息