天天看點

【C語言】大廠指針筆試題(1碼+1圖)詳解——程式結果判斷題

【C語言】大廠指針筆試題(1碼+1圖)詳解——程式結果判斷題

1.一篇就夠了(建議收藏)——超詳解sizeof與strlen的用法

2.C語言之深入指針進階(建議收藏以備不時之需)

3.回爐重造的C之指針+結構體

【C語言】大廠指針筆試題詳解(1碼+1圖)——程式結果判斷題

筆試題1

筆試題2

筆試題3

筆試題4

筆試題5

筆試題6(重點難題)

【C語言】大廠指針筆試題(1碼+1圖)詳解——程式結果判斷題

代碼分析:

int a[4] = { 1, 2, 3, 4 };

【C語言】大廠指針筆試題(1碼+1圖)詳解——程式結果判斷題

由于本人電腦是小端(将低位位元組存儲在起始位址)存儲,是以數組在記憶體中的儲存如圖

【C語言】大廠指針筆試題(1碼+1圖)詳解——程式結果判斷題

int *ptr1 = (int *)(&a + 1);

【C語言】大廠指針筆試題(1碼+1圖)詳解——程式結果判斷題

&a+1

的類型是

int(*)[4]

,強制轉化成

int*

類型,賦給

int*

型指針變量

ptr1

int *ptr2 = (int *)((int)a + 1);

如圖所示,将00位置的位址賦給了

int*

ptr2

【C語言】大廠指針筆試題(1碼+1圖)詳解——程式結果判斷題

printf( "%x,%x", ptr1[-1], *ptr2);

因為

ptr1[-1

]等價于

*(ptr1-1)

ptr1

又是

int*

類型的指針,大小為4位元組,-1往回跳過4個位元組

【C語言】大廠指針筆試題(1碼+1圖)詳解——程式結果判斷題

是以按16進制輸出

ptr1[-1]

就是 4

指針

ptr2

裡存的是

00

這個位置的位址,又因為這個位址是

int*

類型的,大小為4位元組

【C語言】大廠指針筆試題(1碼+1圖)詳解——程式結果判斷題

是以

*ptr2

之後結果為0x02 00 00 00,按16進制列印出來是2000000

【C語言】大廠指針筆試題(1碼+1圖)詳解——程式結果判斷題

① int a[3][2] = { (0, 1), (2, 3), (4, 5) };

這句代碼有個坑,就是二維數組裡是小括号,小括号裡的是逗号表達式(逗号表達式的取值是最後一個元素的值,計算後的最終值是一個元素),是以這裡初始化二維數組時

(0,1)結果是1

(2,3)結果是3

(4,5)結果是5

最終存入二維數組的隻有1,3,5 結果如圖

【C語言】大廠指針筆試題(1碼+1圖)詳解——程式結果判斷題

② int *p;

定義一個指針變量p

③ p = a[0];

a[0]是第一行數組的數組名,單獨放在這裡表示的就是是第一行首元素的位址,将第一行首元素的位址賦給指針變量p

④ printf( "%d", p[0]);

p是個指針,p[0]等價于*(p+0)等價于*(a[0]+0)等價于*a[0],是以這裡列印的其實是第一行第一列的元素1,結果如下

【C語言】大廠指針筆試題(1碼+1圖)詳解——程式結果判斷題

int a[5][5];

初始化一個5×5的二維數組,在記憶體中是這樣存放的

【C語言】大廠指針筆試題(1碼+1圖)詳解——程式結果判斷題

② int(*p)[4];

聲明一個指向4個整型元素的數組指針

③ p = a;

a單獨使用表示的是二維數組首元素位址,也就是第一行a[0]的位址,把這個位址指派給數組指針p

④ printf( "%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);

逐個分析

如圖&a[4][2],取a[4][2]的位址

【C語言】大廠指針筆試題(1碼+1圖)詳解——程式結果判斷題

如下圖

&p[4][2]

注意:指針減去指針,結果是指針之間元素的個數

【C語言】大廠指針筆試題(1碼+1圖)詳解——程式結果判斷題

分别按将變量值以位址形式即16進制形式 和整型列印結果 -4,-4的原反補碼如下

【C語言】大廠指針筆試題(1碼+1圖)詳解——程式結果判斷題

列印結果如圖所示

【C語言】大廠指針筆試題(1碼+1圖)詳解——程式結果判斷題

int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

【C語言】大廠指針筆試題(1碼+1圖)詳解——程式結果判斷題

int *ptr1 = (int *)(&aa + 1);

&aa

是取整個二維數組的位址,+1跳過整個數組之後,再強制類型轉化成 

int*

 類型,并指派給指針變量

ptr1

如圖

【C語言】大廠指針筆試題(1碼+1圖)詳解——程式結果判斷題

③ int *ptr2 = (int *)(*(aa + 1));

aa單獨放,表示二維數組第一行的位址,因為指針類型是int(*)[5],+1之後其實就是第二行的位址,再将其解引用,得到的是第二行數組名,數組名單獨放在這又表示數組首元素位址,将這個首元素位址強制轉換成int*類型,指派給ptr2

【C語言】大廠指針筆試題(1碼+1圖)詳解——程式結果判斷題

printf( "%d,%d", *(ptr1 - 1), *(ptr2 - 1));

ptr1和ptr2的指針類型都是int*, -1後 , 表示的是上一個位址,如圖

【C語言】大廠指針筆試題(1碼+1圖)詳解——程式結果判斷題

列印結果為

【C語言】大廠指針筆試題(1碼+1圖)詳解——程式結果判斷題

代碼分析

char *a[] = {"work","at","alibaba"};

定義一個

char*

類型的指針數組,包含三個字元串

char**pa = a;

a

單獨使用表示的是數組首元素位址,将首元素位址指派給一個二級指針

pa

pa++;

【C語言】大廠指針筆試題(1碼+1圖)詳解——程式結果判斷題

printf("%s\n", *pa);

*pa

(pa已經自增過一次)得到的是字元串“

at\0

”的位址,是以通過

%s

列印字元串

結果是

【C語言】大廠指針筆試題(1碼+1圖)詳解——程式結果判斷題

char *c[] = {"ENTER","NEW","POINT","FIRST"};

char**cp[] = {c+3,c+2,c+1,c};

char***cpp = cp;

前三行代碼可以畫圖表示為

【C語言】大廠指針筆試題(1碼+1圖)詳解——程式結果判斷題

printf("%s\n", **++cpp);

cpp

前置++,相當于

c+2

的位址,

*++cpp

表示

c+2

**++cpp

表示得到字元串“POINT\0”的位址,%s列印出來就是POINT

【C語言】大廠指針筆試題(1碼+1圖)詳解——程式結果判斷題

printf("%s\n", *--*++cpp+3);

這時候需要注意,cpp已經+1過了,現在指向的是c+2

現在看這行代碼的符号操作順序,方框由内向外的順序

【C語言】大廠指針筆試題(1碼+1圖)詳解——程式結果判斷題

一步一步看:

①++cpp,指向c+1

②*++cpp,解引用得到c+1這個空間 裡存放的位址

③--* ++cpp,c+1裡的位址本來指向的是字元串NEW\0的位址,現在- -之後,位址實際上指向的是字元串ENTER\0的位址

④*--*++cpp+3 表示的就是對指向ENTER\0位址的位址(c+1- -)解引用,得到ENTER\0的位址,+3,就是字元E的位址,最終就是從E開始列印字元,%s列印得到結果ER

⑥ printf("%s\n", *cpp[-2]+3);

cpp[-2]等價于*(cpp-2),整體表達式替換成**(cpp-2)+3

由于cpp經過上邊語句的變化,現在指向的是c+1,-2之後指向的應該是c+3,兩次解引用之後得到的是FIRST\0的位址,再+3,得到的就是字元S的位址,%s列印結果為ST

⑦ printf("%s\n", cpp[-1][-1]+1);

cpp[-1][-1]可以替換成*(*(cpp-1)-1)+1

cpp現在指向的c+1,-1之後指向c+2,解引用得到c+2裡的位址,裡邊位址原本指向POINT\0的位址,現在再-1,變成指向NEW\0的位址,再對這個位址解引用得到NEW\0的位址,+1之後,表示的就是字元E的位址,%s列印結果是EW

完整運作結果如下

【C語言】大廠指針筆試題(1碼+1圖)詳解——程式結果判斷題

繼續閱讀