如果我int Array[10];
在 file1.c 中声明
在 file2.c 中,如果 II 有这样的功能
extern int *Array;
fun()
{
Array[0]=10;
}
这有什么问题吗?
是的,有问题。
您声明 aArray
是一个指针,而它是一个数组。这两个是非常不同的对象,在这里您基本上是在向编译器提供错误信息。
请注意,访问元素的 C 语法Array[0]
在这两种情况下都是如此,但如果Array
是指针变量,所需的机器代码将不同于 ifArray
是数组(使用指针有一个额外的间接)。
例如 ifArray1
被声明为gccextern int *Array
生成的机器码是:Array1[ix] += 3
movslq ix(%rip), %rax ;; Load index value from location ix
movq Array1(%rip), %rdx ;; Load pointer value from location Array1
leaq (%rdx,%rax,4), %rax ;; Compute rax as pointer + index*4
addl $3, (%rax) ;; Add 3 to the location pointed by rax
相反,如果Array2
将其声明为extern int Array2[10]
代码,Array2[ix] += 3
则很简单:
movslq ix(%rip), %rax ;; Load in rax the index value from location ix
addl $3, Array2(,%rax,4) ;; Add 3 to the location Array2 + index*4
正如您在第一种情况下看到的那样,有一个额外的间接性,并且Array1
读取地址处的内存内容以找到应该在内存中进行增量的位置。在第二种情况下,只需要读取索引来计算要增加的位置。
为了使 C 中的事情更加混乱,在许多情况下,数组“衰减”为指向第一个元素的指针,因此例如,如果您有一个函数期望指针传递数组,这很好,因为编译器会处理差异.
必须告诉编译器内存中的对象是数组还是指针,因为语义不同;问题中的代码正是这样做的......程序的一部分分配了一个数组并告诉程序的一部分它是一个指针。
该声明extern int *Array
未声明数组,因此与实际定义不匹配。您必须声明:
extern int Array[];
C99(ISO/IEC 9899) §6.5.7.2数组声明符
注意声明之间的区别
extern int *x;
extern int y[];
第一个声明 x 是一个指向 int 的指针;第二个声明 y 是一个未指定大小的 int 数组(一个不完整的类型),其存储在别处定义。