免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 5216 | 回复: 11

exepert c programming: Arrays and Pointers部分的疑问 [复制链接]

论坛徽章:
0
发表于 2006-12-30 16:57 |显示全部楼层
关于extern int *x与extern int y[]的区别,看了半天还是不明白,自己写程序测试:
a.c:

  1. #include <stdio.h>
  2. char arr[100]="hello world";
  3. extern void printadd(){
  4.   printf("the true add:%p\n",arr);
  5.   printf("arr[2]:%c\n",arr[2]);
  6. }
复制代码

  1. #include <stdio.h>
  2. extern char *arr;
  3. extern void printadd();
  4. main()
  5. {
  6.   printadd();
  7.   printf("addr:%p\n",arr);
  8. }
复制代码

疑问1:a.c中定义了arr[100],在b.c中extern char *arr以后两者一点关系都没有吗?程序结果:
./a
the true add:8060900
arr[2]:l
addr:6c6c6568
想知道extern char *arr到底做了些什么?
疑问2:文中一句The key point here is that the address of each symbol is known at compiletime. So if the compiler needs to do something with an address (add an offset to it, perhaps), it can do that directly and does not need to plant code to retrieve the address first. In contrast, the current value of a pointer must be retrieved at runtime before it can be dereferenced (made part of a further look-up). Diagram A shows an array reference.。对底层一些的东西还是不了解,有没有这种可能compiler分配的address被其他程序占用,这时候该程序运行会是什么样子?

[ 本帖最后由 digex 于 2006-12-30 17:32 编辑 ]

论坛徽章:
0
发表于 2006-12-30 19:20 |显示全部楼层
编译链接时就会关联起来了
你的两个文件里面的变量定义要相同呀,一个是变量,一个是指针??回CORE的

论坛徽章:
0
发表于 2006-12-30 21:32 |显示全部楼层
>> 疑问1:a.c中定义了arr[100],在b.c中extern char *arr以后两者一点关系都没有吗?

不,有关系。因为 arr 这个名字在两个编译单位中都具有外部连接属性,所以 arr 指的应该是同一个对象。

>> 这时候该程序运行会是什么样子?

然而,由于在不同的编译单位中声明的 arr 的类型不同,其结果导致了在不同的编译单位中用不同的类型存取同一个对象。根据标准的规定,这样的行为是无定义的。

评分

参与人数 1可用积分 +3 收起 理由
langue + 3

查看全部评分

论坛徽章:
0
发表于 2006-12-30 21:55 |显示全部楼层
在 b.c 声明 arr 为 a.c 的 arr 的同一实体,但不同的存取方法。

在a.c中:
printf("the true add:%p\n",arr); 打印的是arr[]的地址。

但在b.c中:
printf("the true add:%p\n",arr); 打印的是 *arr 的内容,即:“hell" 的数值

评分

参与人数 1可用积分 +3 收起 理由
langue + 3

查看全部评分

论坛徽章:
0
发表于 2006-12-31 09:53 |显示全部楼层
原帖由 whyglinux 于 2006-12-30 21:32 发表
>> 疑问1:a.c中定义了arr[100],在b.c中extern char *arr以后两者一点关系都没有吗?

不,有关系。因为 arr 这个名字在两个编译单位中都具有外部连接属性,所以 arr 指的应该是同一个对象。

>>  ...


嗯,在b.c中printf("addr:%p\n",&arr)跟a.c中打印的地址是相同的,我的理解是这样的:char arr[100]="hello world"的时候为arr分配了内存,假设其开始地址是8888,在b.c中extern char *arr的时候将arr声明为了 char型指针,但其地址没有变化,也就是&arr是8888,不过这个时候指针里的内容是'a',对arr的任何操作都是错误的,不知道这样理解对不对?


我的第二个问题说的不清楚,这样,书里有一段讲左值右值:
The compiler allocates an address (or l-value) to each variable. This address is
known at compiletime, and is where the variable will be kept at runtime. In contrast, the value stored
in a variable at runtime (its r-value) is not known until runtime.
我的理解是编译时为变量分配地址,运行时为地址设置内容,我的疑问是编译的时候怎样分配的地址,会不会分配的地址被其他程序占用?

论坛徽章:
0
发表于 2006-12-31 10:33 |显示全部楼层
需要纠正一点,指针存放的是地址,只有指针指向的内存才是真正的内容。

论坛徽章:
0
发表于 2006-12-31 14:23 |显示全部楼层
原帖由 wyaccent 于 2006-12-31 10:33 发表
需要纠正一点,指针存放的是地址,只有指针指向的内存才是真正的内容。

对,不过访问extern以后的arr的地址不会core dump,因为这个值是arr定义时分配的地址,而访问arr的内容则会core dump,因为extern后arr指针里的内容是字符(当然这是人为造成的),不是地址。。。

[ 本帖最后由 digex 于 2006-12-31 14:25 编辑 ]

论坛徽章:
0
发表于 2006-12-31 14:34 |显示全部楼层
原帖由 mik 于 2006-12-30 21:55 发表
在 b.c 声明 arr 为 a.c 的 arr 的同一实体,但不同的存取方法。

在a.c中:
printf("the true add:%p\n",arr); 打印的是arr[]的地址。

但在b.c中:
printf("the true add:%p\n",arr) ...


这个是不对的,extern arr以后arr是一个指针,该指针的地址(&arr)是arr初始化时的地址,但是该指针的值也就是arr为‘abcd..’,不是地址,所以打印arr相当于Interpreting ASCII characters as an address,printf("the true add:%p\n",arr)返回的不是字符串,如果printf("the true add:%s\n",arr)则会core dump.

论坛徽章:
0
发表于 2006-12-31 16:10 |显示全部楼层
原帖由 mik 于 2006-12-30 21:55 发表
printf("the true add:%p\n",arr); 打印的是 *arr 的内容,即:“hell" 的数值

这里输出的是指针变量arr的值,而不是*arr的值,arr的值才是“lleh"(6c6c6568)!

[ 本帖最后由 tyc611 于 2006-12-31 16:55 编辑 ]

论坛徽章:
0
发表于 2006-12-31 16:38 |显示全部楼层
我还是没看明白,不过我试了在a.c文件中定义:
int ii = 2 ;
在b.c文件增加声明:
extern int ii;
他们的地址是一样的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP