更改外部变量的值

我们在File1.c中

int arr[10]; 

在File2.c中

 extern int *arr; int main() { arr[0]=10; return 0; } 

这有什么问题可以解决?为什么?

数组不是指针。 内存访问将是错误的。

File1.c ,您有内存布局:

 +---+---+---+---+---+---+---+---+---+---+ + 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | +---+---+---+---+---+---+---+---+---+---+ ^ arr 

File2.c ,您已经告诉编译器您有内存布局:

 +-------+ | ptr | +-------+ ^ arr 

指针可能指向可以存储整数的地方。

编译器必须完全不同地访问extern int *arr; 来自extern int arr[];

如上所述,最可能的结果是崩溃,因为编译器取消引用空指针。 但是,这种行为是不确定的,一切皆有可能。 你骗了编译器; 编译器会自己回来 – 它不喜欢被骗。

数组不是指针。

arr被定义为一个数组,因此也将它声明为一个数组。

 extern int arr[10]; // file2.c 

如果不这样做,程序将调用未定义的行为。

int arr[10]; forms, arr本身不占用记忆空间; 它只是一个可以在链接时确定的地址值。 假设arr是100; arr[0]是存储器地址100中的值。

extern int *arr; forms, arr本身就是记忆中的一个变量。 假设arr为100, arr[0]是存储器地址ptr中的值,而ptr是地址100处的存储器单元的值。

编辑

gcc生成的asm给出了深刻的见解:

 extern int a[10]; extern int *b; int foo(void) { return a[3] + b[5]; } _foo: pushl %ebp movl %esp, %ebp movl _b, %eax /* 1st memory load for pointer */ addl $20, %eax movl (%eax), %eax /* 2nd memory load for pointer */ addl _a+12, %eax /* only one memory load for array */ popl %ebp ret