指针的这两个种运算方法哪个快些

[复制链接]
4028|21
 楼主| ilikerome 发表于 2012-4-21 07:44 | 显示全部楼层 |阅读模式
如下:

我自己觉的B要比A快,因为,B比A多了个i++,但是它是加法运算,而A中的

a+100有是乘法运算。

不知这样理解是否正确?

请高手指教。

谢谢!


A
int *p;
int a[100];
for(p=a;p<a+100;p++)
      {.....}   


B

int *p,i;
int a[100];
for(i=0;i<100;i++)
      {
        p++;
        .....}
john_lee 发表于 2012-4-21 08:07 | 显示全部楼层
楼主,你认为 a + 100 中,不管是加法,乘法或是别的运算,编译器会生成实际的代码吗?当然,太烂的编译器就不要考虑了。
ayb_ice 发表于 2012-4-21 08:42 | 显示全部楼层
这个难说,取决于CPU架构,编译器了
lllaaa 发表于 2012-4-21 09:05 | 显示全部楼层
如果指针类型和int类型宽度一样。两者应该没有显著差异。

如果指针类型宽度比int大,那应该是b快
airwill 发表于 2012-4-21 09:08 | 显示全部楼层
楼主的代码是不对等的, B 里面是不该出现 p++;
去掉 p++; 这行对比.
楼上非常正确.

在51系统里, 上面的效率高.
在 ARM 的系统里, 下面的代码不低于上面的代码, 适当的优化, 可能会高于上面的代码.
 楼主| ilikerome 发表于 2012-4-21 10:02 | 显示全部楼层
2# john_lee
估计你没明白我的意思。
 楼主| ilikerome 发表于 2012-4-21 10:03 | 显示全部楼层
3# ayb_ice

恩,但是大部分cpu或者mcu中的逻辑运算单元应该都是加法吧
 楼主| ilikerome 发表于 2012-4-21 10:05 | 显示全部楼层
本帖最后由 ilikerome 于 2012-4-21 10:06 编辑

5# airwill

肯定要P++啊,最终的目的就是要使P++,只是第一个用P本身的值来判断什么时候结束,第二个是用i++来判断什么时候结束。

主要是我觉得a+100这种元算,实际上是 a+100*2(或者4),这里有个乘法运算。
john_lee 发表于 2012-4-21 12:40 | 显示全部楼层
8# ilikerome
如果我这样写:
  1. for(p=a;p<&a[100];p++)

或者更明确一些,只是有点不好看:
  1. for(p=a;p<(int*)((int)a + sizeof(a));p++)

你还会认为编译器会有生成有乘法的代码?
john_lee 发表于 2012-4-21 12:52 | 显示全部楼层
在进一步,如果你的int p[100]是全局对象,那么,你这个p + 100,应该是常量,对吧?
使用优化良好的编译器,当CPU的指令集中具有可以直接比较立即数地址的情况下(例如x86),一定会生成:
CMP Rx, #addr
之类的指令,addr 就是 p + 100的地址。
如果CPU没有这样的指令(例如 ARM),那么编译器也会把p + 100直接装入某个寄存器,并且这个装入过程,是被提到了循环之前,循环中比较时,就直接比较这个寄存器值就行了。
batsong 发表于 2012-4-21 15:36 | 显示全部楼层
李老师威武啊
mxh0506 发表于 2012-4-21 20:46 | 显示全部楼层
首先要分清"a + 100"是编译时计算还是运行时计算。如果是编译时计算,那么一次循环中:A包括一次指针比较(p<a+100)运算和一次指针增量运算(p++);而B包括一次循环变量比较(i<100),一次循环变量增量(i++)和一次指针增量(p++)。对于相同的硬件平台和编译器,这时要比较的明显只是 i 和 p 的数据类型。
airwill 发表于 2012-4-21 22:11 | 显示全部楼层
5# airwill

肯定要P++啊,最终的目的就是要使P++,只是第一个用P本身的值来判断什么时候结束,第二个是用i++来判断什么时候结束。

主要是我觉得a+100这种元算,实际上是 a+100*2(或者4),这里有个乘法运算。 ...
ilikerome 发表于 2012-4-21 10:05


对于 B,
*p 已经不需要了, 因为 用 a 来存取数据了
O狂且O 发表于 2012-4-21 23:26 | 显示全部楼层
<深入理解计算机系统> 讨论了这个问题,  循环展开! 额........
O狂且O 发表于 2012-4-21 23:30 | 显示全部楼层
指针运算往往隐含有乘法运算(寻址方式???)! 好的编译器可以优化! GCC 可以, keil或者其他的编译器不知道! 你可以反汇编比较看看!
星火燎原 发表于 2012-4-22 00:47 | 显示全部楼层
highgear 发表于 2012-4-22 10:31 | 显示全部楼层
理论上,这种情况,一个好的编译器是不会出现乘法运算。但不排除某些编译器的优化令人不可思议。例如 keil c, 很多情况下,指针索引等运算会使用乘法运算。所以楼主问题必须指定编译器,才能有确切的答案。
Tinnal 发表于 2012-4-22 10:38 | 显示全部楼层
8# ilikerome 和2、4、8、16等数的乘除法可以直接用移位运算代替。
apple 发表于 2012-4-22 11:20 | 显示全部楼层
这好比是说BenZ跑得快还是BMW跑得快
 楼主| ilikerome 发表于 2012-4-22 22:02 | 显示全部楼层
9# john_lee
for(p=a;p<(int*)((int)a + sizeof(a));p++)
这段代码还是蛮有意思的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:创造价值是我们学习知识的目的. 知识是创造价值的手段而非全部.

18

主题

516

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部