? ? ? ? 上一期內容,大多數的解題思路寫在代碼中,沒有寫在正文中,這就導致系統判斷文章質量不高,沒有什么數據,這一期將思路寫在正文中。
注意:運行環境是x86?
?1.題目1
?思路:
? ? ? ? &a是取到了整個數組的地址,值為首元素的地址,+1的步長是整個數組,所以+1之后指針指向了下圖所示的位置,此時它的類型是Int(*)[5],是一個數組指針。
? ? ? ? 此時強轉指針的類型為int*,其實就是改變了指針移動的步長,跳過一個整型;查看輸出內容,a+1是第二個元素的地址再解引用是第二個元素2,指針ptr-1,剛剛已經說明步長已經發生改變,所以這里指針向前挪動一個元素,答案是5;
答案:2 5
?2.題目2
思路:
? ? ? ? 首先定義了一個結構體指針p,已知結構體變量是20字節。
①輸出結構體指針+1,這里步長是一個結構體,一個結構體是20字節,所以要加20,轉換成16進制就是:0x100014;
②將指針轉成整型,再加一,其實直接就是數值+1,0x100001;
③將指針轉換成整型指針,加一,就是加四個字節,0x100004
答案:0x100014;0x100001;0x100004
?3.題目3
思路:
? ? ? ? ? 第一個輸出結果是4,這是因為先取出整個數組的地址再+1,指針在4的后面,強轉成int*了,ptr[-1]等價于*(ptr - 1)?,就是元素4;
? ? ? ? 第二個輸出結果是2000000,首先將整個數組的地址強轉成整型再+1,這里的整型是直接+1,舉一個例子如下圖,如果是整型+1直接跳過一個整型,但是這里是轉換成整型+1,就跟數字加法一樣直接加一。
這里的每一個元素都是四個字節存儲,+1之后只是跳過了一個字節,記住vs是小端存儲,數字的低位在低地址,具體的內存圖如下。?int*解引用之后,得到了02 00 00 00,輸出就是20 00 000
4.題目4
答案:1
解析:易錯題,注意數組大括號的內部是小括號,這里考察逗號表達式,(0,1)這里的結果是1;(2,3)結果是3,以此類推...所以數組存放了三個元素:1,3,5;p指針指向第一行,p[0]是*(p+0)所以即求第一行第一個元素,即1;
5.題目5
分析:
? ? ? ? a是首元素地址,也就是一維數組的地址,類型是int(*)[5];p的類型是int(*)[4],這里顯然類型不匹配,但是依舊強行賦值;此時p+1會跳過4個整型;a[4][2]很容易找到,p[4][2]等價于*(*(p+4)+2)首先,p先加4,每加1跳過四個字節,解引用之后就是int*了,每次跳過一個字節,跳兩個字節,最后取地址。下圖藍色的部分就是p[4][2],紅色的部分是a[4][2]。
? ? ? ? 使用整型打印那就是小地址-大地址 = -4;如果按照指針打印就看-4如何在內存中存儲了;
-4的原碼反碼補碼如下,按照%d的格式進行打印的是原碼,按照%p格式打印的是地址,而內存中存儲的就是地址,也就是補碼,轉換成16進制輸出那就是:FFFFFFFC
答案;FFFFFFFC,-4
6.題目6
答案:10,5
分析:第一個取二維數組的地址+1,跳過整個數組,強轉int*輸出再-1,即輸出最后一個元素10;
第二個aa是首元素的地址,即第一行的地址,即一維數組的地址,+1之后就是第二行的地址,再解引用那就是第二行首元素的地址,即6的地址,再-1,最后輸出就是5;
7.題目7
分析:
內存示意圖如下,char* *pa,可以這么理解:指針*pa指向的是一個char*的元素,所以pa++的時候會跳過一個char*的,直接跳到了at的地址,所以輸出at。
答案:at
8.題目8(最難)
分析:畫出三種指針的內存圖;
①cpp自增1,指向c+2的地址,解引用拿到c+2(POINT的地址),,再解引用得到P的地址,打印得到:POINT。
②cpp自增1,從c+2到c+1,再解引用得到NEW的地址,再--得到ENTER的地址,再解引用得到E的地址,再+3得到E的地址,打印輸出ER。
③cpp[-2]等價于*(cpp-2),cpp從c+1的位置回到了c+3的位置,解引用得到c+3,即FIRST的地址,再解引用得到F的地址,最后+3得到S的地址,輸出ST。
④cpp[-1][-1]等價于*(*(cpp - 1) -1),cpp在c+1的位置-1之后在c+2的位置,解引用得到c+2,即POINT的地址,再-1得到NEW的地址,最后解引用得到N的地址,最后+1得到E的地址,輸出EW。