file1.cpp
extern char a[];
extern char *b;
file2.cpp
char *a;
char b[100];
第一种情况:定义为指针,声明为数组
编译错误。对于声明和定义,并不像简单的赋值语句,如”chara[];char *p=a;”,这样指针保存的是数组a的第一个元素,即数组首元素的首地址赋值给了p,这是符合逻辑的一种赋值方法。但是对于声明和定义,声明为a[]时,a表示的是一个常量,即数组首地址,寻址方式为(a+i),但是在文件2中定义的是一个指针*a,这里a表示的是数组首元素的地址(假设值为0x12345678),寻址方式是先获取数组首地址,然后加上偏移量。而此时却以数组的寻址方式代替指针访问方式,结果是a[0]=0x12,a[1]=0x34, a[2]=0x56, a[3]=0x78,即本来表示为地址的值被认为了数组元素。后面的结果可能导致访问其他内存,造成未定义错误。
第二种情况:定义为数组,声明为指针
编译错误。与第一种情况类似,文件2中b是数组首地址常量(假设数组元素分别为:0x12,0x34,0x56,0x78,0x90),而文件1中声明的是指针,所以按照指针的寻址方式读取数据,即先获取数组首地址,char*b=0x12345678,这样本来是数组元素的值被当成了指针,如果该指针指向了某个有效数据,那么对指针的操作可能导致未定义的错误。
总结:之所以发生这样的错误,根本原因是数组和指针的访问方式的区别。数组访问是直接寻址,指针访问是间接寻址。