在现实当中我们经常将数组和指针混用且多数情况下不会出问题,那是因为数组和指针在多数情况下产生的效果是相同的,比如:
-
#include <stdio.h>
-
-
int main(void)
-
{
-
char *p = "1234";
-
-
printf("p[1]:%c" ,p[1]);
-
-
return 0;
-
}
通过上面的程序我们能够访问到第二个元素即字符'2',另外我们可以通过下面的方式来访问:
-
#include <stdio.h>
-
-
int main(void)
-
{
-
char p[5] ="1234";
-
-
printf("p[1]:%c",*(p+1));
-
-
return 0;
-
}
同样我们能够得到第二个元素字符‘2’。但是他们访问的方式却有本质的区别,第一个是直接引用,第二个是间接引用,
,之所以他们能够得到的结果,看下面......
前者:
编译阶段,编译器符号表中存有p的地址。
运行阶段:
1.先取得p地址存放的指针
2.将取得的指针加上下标得到一个新的指针
3.取指针所指向内容的值
后者:
编译阶段,编译器符号表中存有p的地址
运行阶段:
1.将p的地址加上下标得到一个新的地址
2.取出该地址的值
可见两种访问的方式不相同。那么为什么定义char p[10],声明时为extern char *p,然后再在声明后面使用p[x]会出错拉?如下:
extern char *p告诉编译器我们声明的是一个指针,那么在使用p[x]时,它会做如下处理:
1.取出p地址处存放的指针
2.将该指针与x相加得到一个新的指针。
3.取出该指针指向的内容。
但实际上p地址存放的是一个字符,此时编译器却将它当作一个地址,于是就会产生错误。另外这样做的好处使得我们用malloc分配的地址页可以用p[x]来访问。
以上情况,数组和指针不同,但数组和指针在应用中多数情况下是相同的,最普遍的是形参,在数组做为参数传给函数时,它会退化成为一个指针,即行参只是拷贝了一个数组的首地址,它不会进行边界检查。所以通常我们传数组的时候,我们需要或者是以'nul'结尾,或者在在传一个length,来避免访问越界的情况。
阅读(1306) | 评论(0) | 转发(0) |