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

一、
int array[10], a;
for (a = 0; a < 10; a ++)
{
    array[a] = 0;
}
该组使用下标方式赋值,为了对下标表达式求值,编译器在程序中插入指令,取的a的值,并把它与整型的长度(也就是4)相乘,这个乘法须要花费必定的时间和空间
二、
int array[10], *ap;
for (ap = array; ap <array + 10; ap ++)
{
    *ap = 0;
}
该组使用指针方式赋值,尽管这里并不存在下标,但仍是存在乘法运算,如今这个乘法运算出如今for语句的调整部分,1这个值必须与整型长度相乘,而后再与指针相加,但这里存在一个重大区别:循环每次执行时,执行乘法运算的部分都是两个相同的数(1和4).结果,这个乘法只在编译时执行一次——程序如今包含了一条指令,把4与指针相加,程序在运行时并不执行乘法运算。

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

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

我以为楼主的问题须要更具体一些,咱们区分以下三种状况:

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

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

三、定义了数组 a[n],令指针 p = a,分别经过 p 和 a 来访问 


对于状况 一、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 能够指优化

相关文章
相关标签/搜索