先来看一个例子:
文件1:int array_a[3]={1, 2, 3}
文件2:extern int *array_a; printf(“%d”, array_a[2]);
请问输出是多少?
答案是运行时会出错,原因是访问了不可访问的内存。将extern int *array_a改为extern int array_a[]后正常输出。
为什么会出现这样的情况呢?
出现这个问题的原因是编译器对数组和指针的解释是不同的。
使用extern int *array_a; 作声名,编译器会把array_a理解为一个指向int 的指针,对指针的访问是先取址然后在寻址的过程。
而如果使用extern int array_a[], 编译器会把array_a理解为一个数组,访问时直接加上偏移量进行寻址即可。
说得直白一点:如果你使用声名extern int *array_a; printf(“%x/n”, array_a); 想一下你会得到什么值,你可能会毫不犹豫地说是一个地址,但是很遗憾,你说错了。答案是 数组的第一元素的值。原因是什么呢?注意到我们定义的array_a确确实实是一个数组,但我们却把它声名为一个指针。对于一个数组名,只有在作为函数参数进行传递或者传递给左值时,它才会被编译器解释为地址,否则它表示的是数组的第一个元素的值。
在上面的例子中,我们将array_a声名为int *, 但array_a其实是一个数组,因此array_a[2]就成了*(1+2) (注意array_a的第一元素被赋值为1), 当然会出错了。