返回信息流a.c
char a[]="abcd";
b.c
extern char *a;
printf("%x\n",a);
gcc编译打出来的是 0x64636261,相当于把数组a的值付给指针a了,为什么不是把a代表的&a[0] 赋值给指针a呢。在函数传参数的时候是把&a[0]传过去的。
数组a的值是什么, 是a指向的内容还是a代表的a[0]的地址。
这是一条镜像帖。来源:北邮人论坛 / cpp / #81438同步于 2014/8/9
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖
extern 的问题
yfy0535
2014/8/9镜像同步8 回复
订阅后,新回复会通过你的通知中心匿名送达。
8 条回复
extern声明的类型不一致。编译器是对两个文件是分离编译的,定义a时,a是整个数组“abcd”的符号,链接时,编译器从a.c中查询a,然后把b.a直接链接到a.a,也就是认为b.a这个变量的地址为&a.a[0]。
归根到底还是因为 char [] a和 char * a这两个不同,前者编译器并没有为a分配任何空间。如果你手头有《c陷阱与缺陷》的话可以看看,里面记得有解释。
【 在 yfy0535 的大作中提到: 】
: a.c
: char a[]="abcd";
:
: ...................
明白了。谢啦
【 在 gaoweiwei 的大作中提到: 】
: extern声明的类型不一致。编译器是对两个文件是分离编译的,定义a时,a是整个数组“abcd”的符号,链接时,编译器从a.c中查询a,然后把b.a直接链接到a.a,也就是认为b.a这个变量的地址为&a.a[0]。
: 归根到底还是因为 char [] a和 char * a这两个不同,前者编译器并没有为a分配任何空间。如果你手头有《c陷阱与缺陷》的话可以看看,里面记得有解释。
建议lz把a.c 里面 改成 char a[] = "abcdefg";
然后会发现输出内容还是0x64636261
所以lz说“相当于把数组a的值付给指针a了”是不准确的
感觉说是 把数组a在符号表中的位置给了指针a更准确?
因为printf里面的%x,所以通过符号表,去对应地址取了sizeof(unsigned int)字节的数据而已。
另外一个例子:
a.c
char a[] = "abcdefg";
b.c
extern char* a;
printf("%c", a[3]);
这样的话是会“Segmentation fault (core dumped)”的。
因为运行时,在b.c中,发现需要a[3]而且a是一个指针,
所以先去符号表中获得a的值,在这里获得的将是0x64636261
然后去内存中的0x64636261的位置读数据,假设读出来的数据是y(鬼知道y是多少)
然后把内存中y+3位置的数据给printf
想想就觉得可怕!
本质原因:对指针和数组的解析是不一样的。
盗一张《c专家编程》中不清晰的图:
【 在 yfy0535 的大作中提到: 】
: a.c
: char a[]="abcd";
:
: ...................