您的位置:首页 > 其它

数组的下标访问和指针访问方式效率分析比较

2015-07-22 11:36 375 查看
1、

int array[10], a;

for (a = 0; a < 10; a ++)

{

    array[a] = 0;

}

该组使用下标方式赋值,为了对下标表达式求值,编译器在程序中插入指令,取的a的值,并把它与整型的长度(也就是4)相乘,这个乘法需要花费一定的时间和空间

2、

int array[10], *ap;

for (ap = array; ap <array + 10; ap ++)

{

    *ap = 0;

}

该组使用指针方式赋值,尽管这里并不存在下标,但还是存在乘法运算,现在这个乘法运算出现在for语句的调整部分,1这个值必须与整型长度相乘,然后再与指针相加,但这里存在一个重大区别:循环每次执行时,执行乘法运算的部分都是两个相同的数(1和4).结果,这个乘法只在编译时执行一次——程序现在包含了一条指令,把4与指针相加,程序在运行时并不执行乘法运算。

摘自《c和指针》8.1.3 指针与下标

书上讲指针法要比下标法访问数组速度快,是嘛?

我觉得楼主的问题需要更具体一些,我们区分如下三种情况:

1、定义了数组 a
, 通过 a[i] 和 *(a+i) 来访问

2、一个指针 p 指向一段合法空间,通过 p[i] 和 *(p+i) 来访问

3、定义了数组 a
,令指针 p = a,分别通过 p 和 a 来访问 

对于情况 1、2, 访问方式 [] 和 * 是完全等价的,没有差别。我强调一下,对于数组 a, a[i] 与 *(a+i) 是完全一样的。类似地,对于指针 p, *(p+i) 与 p[i] 也是完全一样的。一样指的是生成的汇编代码没有差别。

真正有差别的是 3, 差别在于通过 a 访问还是通过 p 访问,而不在于用 [] 还是用 *

对于 3, 假如要访问 a[i]
(I) 通过 a 访问
      系统只需要计算常量 a 与 i*sizeof(type) 之和,然后访问该地址

(II) 通过 p 访问
      p 是个变量,系统必须先访问 p 的地址,得到 p 的值,然后计算该值 v(p) 与 i*sizeof(type) 之和, 然后再访问得到的地址。 

相比之下,(II) 要稍微慢一些(指针慢)。

通过指针访问唯一有可能快的地方是使用 ++ 进行移动,然后通过 *p 访问。 
但只适用与以下情况:
(a) 硬件对自增有支持,否则 ++ 被转换为 +sizeof(type) 的加法指令,也快不了。
(b) 依次遍历数组

总之,我得出如下结论,在绝大多数情况下,指针与数组相比,没有效率上的优势,有时反而更慢。指针的真正优势是灵活,好用。

ps>; 对于优化的一些补充。

的确,通过 [] 和 * 都可访问任何地址(包括 coredump 的情况),但正如我前面所说的,差别不再在 [] 还是用 * ,在于通过指针访问还是通过数组访问。

对于 int a[10], 你可以用 a[100] 或 a[-10] 访问数组以外的空间,但后果是未定义的。编译器可以无视这种代码,假设通过 a 只会访问 a..a+9,并将之作为优化依据。

对于 int *p ,p 可以指向任何 int 数据。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c 数组 指针 编译效率