免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: zx_wing
打印 上一主题 下一主题

大家来看看这个程序,解释出原因了就明白指针和数组的区别了(程序很短) [复制链接]

论坛徽章:
0
1 [报告]
发表于 2006-12-17 17:28 |显示全部楼层
>> 指针需要访存,取出存放在指针变量中的内容,解释成地址再使用。

这只适用于指针变量。对于指针常量(如 null 指针常量)以及由表达式计算得到的指针值不需要访问内存。

>> 而数组本身就是地址,直接就可以使用。

“数组是地址”和“数组是指针”这两种说法是等同的。如果数组是地址的话,你怎么解释对一个数组对象的取址操作?解释为取地址的地址吗?

再强调一遍,数组对象解释为数组类型还是指针类型(即地址)是由其在表达式中所处的上下文环境决定的,即取决于是左值语义还是右值语义。没有任何前提条件的时候,你不能确定“数组是作为数组类型使用”还是“数组是作为指针类型使用”。

论坛徽章:
0
2 [报告]
发表于 2006-12-17 18:18 |显示全部楼层
>> 如果版主有不需要访存的指针表达式计算,请给出c代码和反汇编。

下面的表达式的计算都不需要进行内存访问:
  1. (int*)0 + 10
  2. &x + 10  // x 是一个静态对象。
复制代码


>> 版主你可以给个例子,不告诉我任何前提条件,只告诉我这是个数组还是指针,然后给出操作,如果我不能确定操作如何进行,我就赞同你上面的观点。

这我做不到。因为我如果给出操作了,也就等于告诉你使用环境了(因为运算符决定了操作数是左值还是右值语义)。我在上面所说的“没有任何前提条件”指的就是“在尚未确定进行何种操作的情况”。

论坛徽章:
0
3 [报告]
发表于 2006-12-18 09:41 |显示全部楼层
>> int a = 1; a++;
>> 我可以肯定的说上述代码不需要访存,因为我没有给出上下文环境以及平台,所以总能找出一种不需要访存的情况。

何出此言?为了进行 a++ 的计算,总是首先要从内存中取得 a 的值。为了在变量 a 中存储计算结果,最终总是要将结果值写到 a 所在的内存中去,不论在什么平台上。

>> 我强调指针访存只是想说明在数组和指针相似的行为下(例如用下标访问元素),其实质是不一样的。

其实质是一样的:无论是用数组名、指针变量还是指针表达式访问数组元素,都是通过指针进行访问。所不同的只是指针值的来源有所差别罢了--有的来自于一个数组对象,有的来自于一个指针变量,有的来自于一个表达式的值。

论坛徽章:
0
4 [报告]
发表于 2006-12-18 13:16 |显示全部楼层
To zx_wing

>> 有兴趣的朋友可以自己看看反汇编,会发现没有访存操作,a是放在一个寄存器里的(在x86平台上,我推测是eax)。

真的没有访存操作操作吗?那寄存器中的初始值是从哪里来的?

论坛徽章:
0
5 [报告]
发表于 2006-12-18 14:10 |显示全部楼层
>> 编译过后,初始化操作会被转换成一个立即数操作,例如:
>> mov 1, %eax

这是加了优化之后的情况吧?

优化是一种等价实现,强调的是结果的对等性,其具体的实现过程没有可比性,一般不能用来说明原代码的情况。还是看没有优化下的汇编吧。

论坛徽章:
0
6 [报告]
发表于 2006-12-22 14:56 |显示全部楼层
对同一对象的类型声明不一致是一种无定义行为。

>> 原因在于 extern 从来不检查类型

为了保证声明和定义的一致性,应该将声明单独放在一头文件中,在程序中进行声明此变量的时候要以包含头文件的方式进行(保证声明的一致性),在定义变量的文件中应该包含此头文件(这样可以在编译阶段检查出声明和定义是否一致)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP