C中的外部行为

Jay*_*ram 1 c extern

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

在file2.c中如果II有这样的函数

extern int *Array;
fun()
{
    Array[0]=10; 
}
Run Code Online (Sandbox Code Playgroud)

这有没有问题?

650*_*502 8

是的,有一个问题.

你声明一个Array是一个指针,而它是一个数组.这两个是非常不同的对象,在这里你基本上是向编译器提供虚假信息.

请注意,访问元素的C语法Array[0]在两种情况下都是如此,但如果Array是指针变量,则所需的机器代码将不同于if Array而不是数组(指针有一个额外的间接).

例如,如果Array1声明为gcc extern 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
Run Code Online (Sandbox Code Playgroud)

如果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
Run Code Online (Sandbox Code Playgroud)

正如您在第一种情况中所看到的那样,存在一个额外的间接,并且Array1读取地址处的内存内容以查找应在内存中进行增量的位置.在第二种情况下,只需要读取索引来计算要递增的位置.

为了使C中的东西更加混乱,在很多情况下,数组"衰减"成指向第一个元素的指针,例如,如果你有一个函数,期望一个指针传递一个数组很好,因为编译器将负责处理差异.

必须告诉编译器内存中的对象是数组还是指针,因为语义不同; 问题中的代码确切地说就是这样...程序的一部分分配一个数组并告诉程序的某些部分它是一个指针.