使用 extern 将数组与指针链接起来
Posted
技术标签:
【中文标题】使用 extern 将数组与指针链接起来【英文标题】:using extern to link array with pointer 【发布时间】:2012-11-25 03:11:47 【问题描述】:假设我有两个文件: file1.c- 包含一个名为“array[10]”的大小为 10 的 int 数组的全局定义。 file2.c- 包含一个名为“extern int *array”的 int 指针,这里我试图将这个指针链接到数组。
但是当我检查 file1.c 中的数组地址和 file2.c 中的指针值时,它们都是不同的。为什么会这样?
【问题讨论】:
【参考方案1】:那不行,在file2.c
,你需要
extern int array[];
因为数组和指针不是一回事。两个声明必须具有兼容的类型,int*
与 int[N]
不兼容。
没有具体说明实际发生的情况,程序格式错误,extern int *array;
,但可能数组的前 sizeof(int*)
字节被解释为地址。
【讨论】:
但是内存中到底发生了什么?是否为数组(40 字节)和指针(32 位为 4 字节)分配了内存? 未定义的行为(实际上是格式错误的程序)。但很可能,数组的前四个(或八个)字节被解释为一个地址。 好的,但是链接器将指针链接到一个数组并且不报告编译时错误。它实际链接到什么? 它链接到同名符号,这意味着每当您在file2.c
中引用array
时,数组的适当字节数将被解释为int*
的值.对该(相信的)指针的任何取消引用很可能会导致崩溃。【参考方案2】:
extern1.c
#include <stdio.h>
extern int *array;
int test();
int main(int argc, char *argv[])
printf ("in main: array address = %x\n", array);
test();
return 0;
extern2.c
int array[10] = 1, 2, 3;
int test()
printf ("in test: array address = %x\n", array);
return 0;
输出:
in main: array address = 1
in test: array address = 804a040
还有汇编代码:
08048404 <main>:
8048404: 55 push %ebp
8048405: 89 e5 mov %esp,%ebp
8048407: 83 e4 f0 and $0xfffffff0,%esp
804840a: 83 ec 10 sub $0x10,%esp
804840d: 8b 15 40 a0 04 08 mov 0x804a040,%edx <--------- this (1)
8048413: b8 20 85 04 08 mov $0x8048520,%eax
8048418: 89 54 24 04 mov %edx,0x4(%esp)
804841c: 89 04 24 mov %eax,(%esp)
804841f: e8 dc fe ff ff call 8048300 <printf@plt>
8048424: e8 07 00 00 00 call 8048430 <test>
8048429: b8 00 00 00 00 mov $0x0,%eax
804842e: c9 leave
804842f: c3 ret
08048430 <test>:
8048430: 55 push %ebp
8048431: 89 e5 mov %esp,%ebp
8048433: 83 ec 18 sub $0x18,%esp
8048436: c7 44 24 04 40 a0 04 movl $0x804a040,0x4(%esp) <------- this (2)
804843d: 08
804843e: c7 04 24 3d 85 04 08 movl $0x804853d,(%esp)
8048445: e8 b6 fe ff ff call 8048300 <printf@plt>
804844a: b8 00 00 00 00 mov $0x0,%eax
804844f: c9 leave
8048450: c3 ret
注意汇编代码中的
【讨论】:
在main
中,您打印的不是地址,而是指针的值(在test
中,指针的值指向数组在传递时转换为的第一个元素到printf
)。如果您在两者中都打印&address
,您将获得相同的输出。很好的插图。
int* 与 int[N] 不兼容以上是关于使用 extern 将数组与指针链接起来的主要内容,如果未能解决你的问题,请参考以下文章
外部链接:当使用rel =“external”或rel =“nofollow”时?
C++ Primer 5th笔记(chap 19 特殊工具与技术)链接指示: extern “C“
链接属性rel=’external’rel=’nofollow’rel=’external nofollow’三种写法的区别