2016-11-13 41 views
3

對指針使用索引括號是否也對它進行解引用?爲什麼打印這個指針的第0個索引最終會打印兩個不同的東西?是否使用索引括號作爲指針取消引用?

#include <cstdlib> 
#include <iostream> 
#include <cstring> 

using namespace std; 

int *p; 

void fn() { 
    int num[1]; 
    num[0]=99; 
    p = num; 
} 

int main() { 
    fn(); 
    cout << p[0] << " " << p[0]; 
} 

回答

9

確實使用索引括號作爲指針還提取它嗎?

正確,指針算術等同於數組索引。 p[index]*(p+index)相同。

爲什麼打印這個指針的第0個索引最終會打印兩個不同的東西?

因爲使用p指向一個局部變量(num),其範圍在fn()函數結束結束。你觀察到的是未定義的行爲。返回一個指向局部變量的指針是不好的做法,必須避免。

順便說一句,只是爲了看到範圍效應,如果您將num數組的定義移動到fn()函數之外,那麼您將看到一致的cout行爲。

或者,如@ Marc.2377所示,爲避免全局變量(這是不好的做法),您可以在堆中分配變量(int* num = new int[1];)。然後返回指針pfn()即可,但請勿忘記在main()之後再撥打delete[] p

+2

謝謝你會接受這個答案,當它允許 – Austin

+1

或者'int * num = new int [1];'在'fn()'內(儘管這肯定不是推薦和應該只用於確認範圍效應) –

+0

@ Marc.2377這是避免全局變量的一個好點,我在你的評論之後編輯了答案 - tks – artm

3

不會使用索引括號內爲指針也提領呢?

是的,它的確如此。 ptr[i]相當於*(ptr + i)

訪問超出範圍局部變量num是未定義的行爲。基本上p指向一個局部變量num。從fn()返回後,num超出範圍,因此可以在其地址處存儲任何內容。

+0

是不是全球範圍? – Austin

+1

'p'不是局部變量。這是全球性的。 –

+1

'num'是本地的,它是由'p'指向的 –

3

數組分配連續的存儲單元(所有元素都連續存儲),所以A [i](存在於數組第i個索引處的元素)將離開數組A的基地址爲i個存儲單元。
因此A [i]等於*(A + i)。

指針存儲的地址,而不是內部的內容。因此,局部變量不再存在於函數外(局部範圍),從而在函數之外給出不同的結果。