1

如果我int Array[10];在 file1.c 中声明

在 file2.c 中,如果 II 有这样的功能

extern int *Array;
fun()
{
    Array[0]=10; 
}

这有什么问题吗?

4

2 回答 2

8

是的,有问题。

您声明 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 中的事情更加混乱,在许多情况下,数组“衰减”为指向第一个元素的指针,因此例如,如果您有一个函数期望指针传递数组,这很好,因为编译器会处理差异.

必须告诉编译器内存中的对象是数组还是指针,因为语义不同;问题中的代码正是这样做的......程序的一部分分配了一个数组并告诉程序的一部分它是一个指针。

于 2013-07-12T12:05:01.460 回答
0

该声明extern int *Array未声明数组,因此与实际定义不匹配。您必须声明:

extern int Array[];

C99(ISO/IEC 9899) §6.5.7.2数组声明符

注意声明之间的区别

extern int *x;
extern int y[];

第一个声明 x 是一个指向 int 的指针;第二个声明 y 是一个未指定大小的 int 数组(一个不完整的类型),其存储在别处定义。

于 2013-07-12T12:05:46.970 回答