test1.c
#include <stdio.h>
extern char p[];
int main()
{
printf("char %c \n",p[1]);
return 0;
}
test2.c
char p[10]="123456789";
g++ test1.c test2.c
./a.out #程序运行正确
把test1.c修改一下,改成test3.c
test3.c
#include <stdio.h>
extern char * p; //定义一个指针来访问数组,将数组解释为指针
int main()
{
printf("char %c \n",p[1]);
return 0;
}
g++ test3.c test2.c
./a.out #程序运行错误
问题,为什么第二段代码是错误的?
首先要区别一下以下这两段代码的,分别执行arr[1]和p[1]的区别?
char arr[10]="123456789";
cout<<arr[1]<<endl;
char * p = "123456789";
cout<<p[1]<<endl;
访问一个数组的流程:
image.png
访问一个指针的流程:
image.png
所以,问题就出现在这里,编译器对访问一个指针和访问一个数组的解释是不一样的。一个被解释被两步,一个被解释为三步。
小结:
- 如果p被定义为一个指针,那么访问p[1]的时候,编译器会按照上面提到的三步的流程去访问p[1]。
- 如果p被定义为一个数组,那么访问p[1]的时候,编译器会按照上面提到的两步的流程去访问p[1]。
对于这个例子:
image.png
那么,为什么常用的一种写代码的方式是没有问题的?
#include <stdio.h>
char p[10]="123456789";
char * p1 = p; // 用指针指向数组,然后访问指针,程序也是ok的,为什么这样不会出问题?
int main()
{
printf("char %c \n",p[1]);
printf("char %c \n",p1[1]);
return 0;
}
image.png
参考
《c专家编程》 第四章
除了这个书上面还有一个,指的mark一下。
image.png
网友评论