深入理解C指標

2021-09-29 20:48:26 字數 2067 閱讀 1983

指標使用分析:

提及指標早已不再感覺到陌生,大一初識c語言,老師就一再強調指標的重要性。而然一直以來對其的認識僅停留在「指標:指向其他資料的記憶體位置的變數」。現在我們不妨以指標如何用開始,再次**指標。

先來看一段**:

#include

using

namespace std;

intmain()

宣告乙個int型指標,不妨先看一下其裡有什麼?編譯控制台列印:一串十六進製制數值。不禁疑問這串十六進製制數值是什麼?

對編譯原理有簡單了解的都清楚,上述c++**經過編譯器,首先會編譯為彙編**,彙編**大概如以下形式:

mov  8

(%rsp)

,%rax;

取出記憶體棧幀位址為:rsp(初始位址->堆疊暫存器)+8(偏移量)中的內容,然後放入rax暫存器中。彙編**又會經過編譯鏈結等步驟,最終變成可執行檔案。

根據上述分析,可以推出:列印的結果應該是p記憶體中的內容。驗證推斷:我們不妨改變其記憶體位址中的內容,若與我們期望的內容一致,則推斷成立。

int a =10;

cout <<

&a << endl;

#include

using

namespace std;

intmain()

推論得證!

在此基礎上,我們不妨再來**一下指標的指標,加深一下對指標的印象。

p也是c的一種型別,像上述a一樣,其在記憶體中也占有位址空間(彙編**)。因此不妨先以上述類似的過程來理解指標的指標。

#include

using

namespace std;

intmain()

結論同上述一樣。

#include

using

namespace std;

intmain()

上述**,又新增了驗證pp指向的記憶體空間的內容。此過程是否同計組原理中的間接定址極為相似。通過上述分析,不難推斷出指標的一般行為。

進一步理解指標:

問題一:

存在整型變數a,以下等式是否成立?

a = *&a
不妨通過編譯器試驗一下:

if

(x ==

*&x)

printf

("yes\n");

else

printf

("no\n"

);

指標型別分析:
#include

using

namespace std;

intmain()

#include

using

namespace std;

#define n 6

intmain()

執行上述**,可以發現兩次列印內容相同。為什麼會出現這種情況?

如上圖所示,我們可以將記憶體抽象理解為乙個超大的陣列,給定初始位址(也就是陣列第乙個元素的記憶體位址),每次加上偏移量也就可以確定陣列中的其他元素。例如訪問ars[2],即為ars+(2*4),ars為陣列初始位址,2為訪問第二個元素,4為int型別所佔位元組大小。看到這我們似乎可以得出指標為什麼存在不同型別的答案了,如上述例子,資料型別為int型別,所以計算其偏移位址時最終會再乘上4,若陣列型別為double,自然其偏移量會再乘上8,。原來其區別不同型別的原因是為了方便計算定址。這種區分僅作用於彙編層面(c**->編譯器->彙編->彙編編譯器->鏈結->可執行檔案)。就像機器語言並不知道源運算元和目的運算元是有符號還是無符號一樣,只能通過具體指令區別。

參考文獻《深入理解計算機系統》

深入理解C語言 深入理解指標

關於指標,其是c語言的重點,c語言學的好壞,其實就是指標學的好壞。其實指標並不複雜,學習指標,要正確的理解指標。指標也是一種變數,占有記憶體空間,用來儲存記憶體位址 指標就是告訴編譯器,開闢4個位元組的儲存空間 32位系統 無論是幾級指標都是一樣的 p操作記憶體 在指標宣告時,號表示所宣告的變數為指...

深入理解C語言 深入理解指標

關於指標,其是c語言的重點,c語言學的好壞,其實就是指標學的好壞。其實指標並不複雜,學習指標,要正確的理解指標。指標也是一種變數,占有記憶體空間,用來儲存記憶體位址 指標就是告訴編譯器,開闢4個位元組的儲存空間 32位系統 無論是幾級指標都是一樣的 p操作記憶體 在指標宣告時,號表示所宣告的變數為指...

深入理解指標

指標 是乙個特殊的變數 它裡面儲存 的數值被解釋成為記憶體裡的乙個位址 指標也是一種資料型別,並且也是有值的。要搞清乙個指標需要搞清指標的四方面的內容 指標的型別,指標所指向的型別,指標的值或者叫指標所指向的記憶體區,還有指標本身所佔據的記憶體區。讓我們分別說明。先宣告幾個指標放著做例子 例一 1 ...