今天在看了专家c的第四章后对数组和指针有了更深入的理解
首先
1 /*文件1*/ 2 int p[100]; 3 4 /*文件2*/ 5 extern int *p; 6 7 /*.........................*/ 8 9 /*.............对p[i]相关的操作.................*/
为什么会这样呢?指针和数组难道不就是一个玩意吗? 然而并不是.
先列出指针和数组的重要区别
------------------------------------------------------------------------------------
| 指针 | 数组 |
------------------------------------------------------------------------------------
| 保存的是数据的地址 | 保存数据本身 |
------------------------------------------------------------------------------------
| 间接访问数据,首先在 | 首先在符号表中找到数组 |
| 符号表中找到该指 | 的地址,然后从该位置开始 |
| 针的地址,取出内存中的 | 后面连续的位置全为数据 |
| 值,然后访问该值所指 | |
| 的地址从而达到数据 | |
---------------------------------------------------------------------------------------
根据以上区别,推导一下平时用指针来访问数组的过程
(1) 当我们有
char *p="12345"; c=*p;
通过如下过程获得数据
1.编译器在符号表取得p的地址
2.然后取得p中的内容
3.以p中内容为地址得到数据
(2)当我们有
char p[]="12345"; c=p[3];
通过如下过程获得数据
1.编译器在符号表中取得p的地址
2.从p开始的连续多个字节中就是存的数据,这里是3就是从p开始跳三步,每步大小为一字节
(3)当我们有
char *p="12345"; c=p[3];
通过如下过程获得数据
1.编译器在符合表中获得p的地址(这个字符串常量会分配内存且被定义为只读的)
2.从p的地址中读出内容,即指针
3.将内容与偏移量相加这里是3
4.以3为地址取出该位置的值
再来思考一下开始的那个错误
1 /*文件1*/ 2 int p[100]; 3 4 /*文件2*/ 5 extern int *p; 6 7 /*.........................*/ 8 9 /*.............对p[i]相关的操作.................*/
在文件二中我们声明了p为一个指针,编译器会把它当做指针来解释(无论p之前是定义为数组还是指针)从而也就是我们上面的情况(3)
将执行
1.在符号表中找到p的地址
2.取出p中的内容作为地址
3.将............等一等.........
我们发现在文件一中,p定义为数组
也就是说按照这种机制,p的第一个数据将被编译器解释成一个地址,一个int型的数当成了一个地址....................................所以错误可想而知.......