C 指针 五
接着前面的指针来讲,有人会遇到如下困惑:
#include <stdio.h>
int main()
{
char *p="hello world!";//两者为什么可以“=”
printf("p=%s",p);//能打印出字符串常量
printf("p=%s",*p);//报错,不能打印出字符串常量
}
分析
一、两者为什么可以“=”
①首先需要明白一点,在c中,将由双引号引起的一串字符叫做字符串(c中是没有字符串这种类型的),这里的“hello world!”是常量字符串,系统默认在字符串常量最后添加了一个字符’\0’。
②字符串打印用%s,打印规则是:从首元素开始打印,直到结束符(也就是‘\0’)的位置
③c中是如何处理字符串常量的?
c中,处理字符串常量,是将其处理为一个指向data段(就当做内存就好了,先不用管)这段字符串的首地址。可以验证:
#include <stdio.h>
int main()
{
printf("p0=%s\n","hello world!");
printf("p1=%s\n","hello world!"+1);//首地址加1
printf("p4=%s\n","hello world!"+4);
}
结果:
首元素的地址就是首地址了,结合%s打印的规则,char *p=“hello world!”,这不就是把一个首地址赋给了指针吗?指针这么用,没什么毛病。
二、能打印出字符串常量
如下图,依然有这种指向关系,只不过,字符串在c中比较特殊。 直接printf(“p=%s”,p),按照%s打印时,内部会有一些相应的操作(操作p所指向的内存),类似于下面的代码,让我们看起来是将hello world!直接一次打印出来,其实是一个字符一个字符打印出来的,就可以不用加*。至于printf(“p=%p”,p),就是将p内存中的值按%p格式打印出来,打印的是地址。
int i=0;
while(*(p+i)!='\0')
{
printf("%c",*(p+i));
i++;
}
printf("\n");
三、报错,不能打印出字符串常量
那么根据上面的图,为什么*p就不能打印出来字符串?而且还报错?这是因为在这里*p是代表第0个元素,第0个元素的类型是:char ,当然就不能用%s来打印了,要用%c。
#include <stdio.h>
int main()
{
char *p="hello world!";
printf("p0=%c\n",*p);
printf("p1=%c\n",*(p+1));//第一个元素
printf("p11=%c\n",*(p+11));
}
结果: