數組的下標訪問和指針訪問方式效率分析比較

一、
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 能夠指優化

相關文章
相關標籤/搜索