数组名在编译器中是如何实现的?

C专家编程里解释的很好:


经典的错误:在一个文件定义了数组,却在另外一个文件声明其为指针。代码如下:
/*File name: main.c*/

extern int* array; /*声明指针*/

int main(void)

{

array[0]=1; /*用指针访问数据*/

return 0;

}

/*File name: def.c*/

int array[5]={0}; /*定义的却是数组*/


1。编译器对数组名和指针变量的处理方式

编译器在编译时会产生一个符号表,记录了符号名和它的地址。对于指针变量,这显然很好理解。而数组名就不那么明显了,它仅仅是一个符号而已,何来地址?编译器是这样处理的,它记录了array[0]的地址;这和我们通常的理解也是一样的。

2。带下标形式的数组和指针寻址方式

(1)数组情形

char a[9]=”abcdefgh”;



c=a[i];

在编译期,会在符号表中创建这样一条记录:

name:a address:9980

要获取a[i]的值分两个步骤:

step 1:取得i的值并和9980相加

step 2:在内存地址(9980+i)处取其内容


(2)指针情形

char* p=”abcdefgh”;



c=p[i];

在编译期,会在符号表中创建这样一条记录:

name:p address:4624

要获取p[i]的值分三个步骤:

step 1:在内存地址4624处取其内容,比如说“5081”

step 2:取得i的值并和5081相加

step 3:在内存地址(5081+i)取其内容


现在有了这些知识,前面出现的错误就很好解决了。在def.c中定义array是一个int型数组,在符号表中就会有把array和array[0]的地址关联起来。而在main.c中却把把array看作是一个int型指针,于是乎按照上面介绍的指针寻址方式,把符号表中array的地址(即&array[0])中的内容当作指针来寻址,这显然是不对的。