c++面試題之數組與指針

    關於數組與指針的問題,常見的有,指向數組的指針,聲明數組指針和指針數組等,在這裏主要看看指向數組的指針是怎麼回事。
    指向數組的指針,總的來說,實際上可以歸納爲如下幾點:
    1、 有一個一維數組int a1[10],定義一個指針,指向一維數組名。
    2、 有一個一維數組int a2[10],定義一個指針,指向一維數組名的地址。
    3、 有一個二維數組int a3[3][4],定義一個指針,指向二維數組名。
    4、 有一個二維數組int a4[3][4],定義一個指針,指向二維數組名的地址。
    這四個問題,都是讓我們定義一個指針,指向一片連續的內存空間,只是說這片內存空間有的是一維,有的是二維而已。
    我們這次先分析下前面兩道題:
    那我們先看第一個題目,因爲a1本身就是連續空間的首地址,那麼我們就只需要定義一個地址變量p,讓p = a就可以了,既然要用“=”,那麼等號兩邊就需要的類型一樣,所以毫無疑問,p應該爲 <數據類型> *p了。現在不確定的就是數據類型了。根據指針的定義,應該有p[0]到p[1]的偏移和a[0]到a[1]的偏移一致,我們很容易看出,a[0]和a[1]的偏移是int類型。那麼對於第一個題目的數據類型就應該爲int了,第一題的答案爲int *p;
    接着看第二問題,這個問題的難點在,什麼叫數組名的地址,我們都知道C語言中的變量都有地址,但數組名是什麼,他是不是也在內存中實實在在的存在哪,回答是否定的(感興趣的同學,可以試着證明下,a的值和&a的值有什麼特點)。a是數組空間的一個標號,那對標號取地址,是什麼那,我們可以試着把&a和&a+1的地址都打印出來,然後看下他們的關係,我們會發現,&a和&a+1之間的偏移實際上是10個int的單位。那麼我們也可以推出數組名的地址原來標示了整個數組的空間。也就是說&a[0]和&a[1]的偏移實際上是一個int [10]的空間。那麼對於<數據類型> *p來說,數據類型就是指int [10]這個空間了。第二題的答案爲int (*p)[10];
    對於前2個問題,可以寫出如下實驗代碼:
int main(int argc,char *argv[])
{
int a1[10];
int *p;
int (*p1)[10];
printf(“the address of a1[0] is %p,the address of a1[1] is %p\n”,&a1[0],&a1[1]);
printf(“the &a1[0] is %p,the &a[1] is %p\n”,&(&a1)[0],&(&a1)[1]);
p = a1;
p1 = &a1;
}
    以上程序中p1,p即我們應該填的,如果編譯器編譯時沒有警告,那麼說明我們的這樣寫法是正確的。
    那麼在深入下的分析下,p1和p現在都要他訪問a1中的第二個元素,即a1[1],應該怎麼做那?
    大家可以思考下,答案是:p[1] p1[0][1],如何驗證那,只要執行if(p[1] = = p1[0][1]),如果這個邏輯爲真,那說明正確。
上次題目的內容爲:
1、 有一個一維數組int a1[10],定義一個指針,指向一維數組名。
2、 有一個一維數組int a2[10],定義一個指針,指向一維數組名的地址。
3、 有一個二維數組int a3[3][4],定義一個指針,指向二維數組名。
4、 有一個二維數組int a4[3][4],定義一個指針,指向二維數組名的地址。
    還記得前2道題的分析方法嗎,第一個題,應該定義一個int *p的指針來指向一維數組a1(這個是比較簡單的)。而第二個題目爲定義int (*p)[10]來指向一維數組a2的地址。
    我們分析後面面兩道題:
    int a3[3][4]爲二維數組,大家都知道他的物理意義是3行4列,但是我們都知道,計算機的內存是一維空間,即不可能按照一個面的方式存儲二維數組的,那麼計算機怎麼存儲呢,大家可以參考下C語言教材,二維數組是按照從上到下從左到右的順序放置到一維內存空間的。
    比如int a3[3][4] = {{1,2,3,4},{5,6,7,8}},在計算機分配了8個int空間按順序存儲1,2,3,4,5,6,7,8,那計算機怎麼知道1,2,3,4爲第一行那,而不是1,2爲一行,3,4爲一行那。看來a3中的“[4]”起到了很重要的作用。
    那麼我們還是回到題目上,定義一個指針指向a3,那麼我們就先看下a3是怎麼讀內存的?a3 和a3+1,我們分別用%p來查看下他們的地址偏移,程序大家可以自己寫,我們會發現他們兩者的差值爲16,我們又知道a3裏面存着都是4個字節的int類型,那麼可以知道,從a3到a3+1偏移了4個int單位,而這個4恰好是第二個方括號的數字。
    那麼我們定義的指針P偏移內存的方式也應該是4個int單位才能和a3匹配,所以很多同學在面試時給出int **p的結果是不對的,因爲二維指針的偏移還是4個字節爲一個偏移單位,跟我們分析的不一樣。那我們如果去寫一個指向4個int單位的指針那,大家可以考慮下使用小括號來幫助我們理解。
    答案爲:int (*p)[4]。看到這個答案,和我們的第二題的答案很類似,所以我們可以這樣認爲,一維數組名的地址實質就是一個二維數組的一行。
    下面我們看第四題,有涉及到數組名的地址的問題,二維數組名的地址,根據我們上次分析,可以知道,二維數組名的地址偏移實際上是一個二維數組對象,即偏移一個面,那麼對於指針的定義,應該容易的得到:
int (*p)[3][4];
這樣的答案。
綜合這幾道題目,我們能更深入的理解關於指針的含義了。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章