天天看點

c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針

點選藍字關注,創智助你長姿勢

c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針

C 和 C++ 中最強大的功能莫過于指針(pointer)了,但是對于大多數人尤其是新手來說,指針是一個最容易出錯、也最難掌握的概念了。本文将從指針的方方面面來講述指針的概念和用法,希望對大家有所幫助。

記憶體模型

為了更好地了解指針,讓我們來看一下計算機的記憶體模型。

記憶體分為實體記憶體和虛拟記憶體,實體記憶體對應計算機中的記憶體條,虛拟記憶體是作業系統記憶體管理系統假象出來的。由于這些不是我們本文的重點,下面不做區分。

在不考慮 cpu 緩存的情況下,計算機運作程式本質上就是對記憶體中的資料的操作,通俗地來說,就是将記憶體條某些部分的資料搬進搬出或者搬來搬去,其中“搬進搬出”是指将記憶體中的二進制資料搬入 cpu 寄存器及運算器中進行相應的加減運算或者将寄存器中的資料搬回記憶體單元中,而“搬來搬去”是指将記憶體中的資料由這個位置搬到另外一個位置(當然,一般不是直接搬,而是借助寄存器作為中間存儲區)。如下圖所示:

c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針

計算機為了友善管理記憶體,将記憶體的每個單元用一個數字編号,如下圖所示:

c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針

圖中所示,是一個大小為128個位元組的記憶體空間,其中每一個空格代表一個位元組,是以記憶體編号是0~127。

對于一個 32 位的作業系統來說,記憶體空間中每一個位元組的編号是一個 32 位二進制數,是以記憶體編号從 0000 0000 0000 0000 0000 0000 0000 0000 至 1111 1111 1111 1111 1111 1111 1111 1111,轉換成 16 進制也就是 0x00000000 至  0xFFFFFFFF,由于是從 0 開始的,是以化成 10 機制就是從  0 至 2 的 32 次方減 1;對于 64 位作業系統,記憶體編号也就是從 64 個 0 至 64 個 1。

大家需要注意的是,從上面兩個圖我們可以發現,我們一般将編号小的記憶體單元畫在上面,編号大的畫在下面,也就是說從上至下,記憶體編号越來越大。

指針與指針變量

指針的本意就是記憶體位址,我們可以通俗地了解成記憶體編号,既然計算機通過編号來操作記憶體單元,這就造就了指針的高效率。

那麼什麼是指針變量呢?指針變量可通俗地了解成存儲指針的變量,也就是存儲記憶體位址(記憶體編号)的變量。首先指針變量和整型變量、字元型變量以及其他資料類型的變量一樣都是變量類型;但是,反過來,我們不應該按這樣的方式來分類,即:整型指針變量、字元型指針變量、浮點型指針變量等等。為什麼不推薦這樣的分類方法呢?首先,指針變量就是一個資料類型,指針資料類型,這種資料類型首先是一個變量資料類型,那麼它的大小是多少呢?很多同學理所當然地認為整型指針變量和一個字元指針變量的大小是不一樣的,這種認識是錯的。指針變量也是一個變量,它是一個用來存儲其他變量的記憶體位址的,更準确地說,指針變量時用來存儲其他變量的記憶體首位址的,因為不同的資料類型所占的記憶體大小不一樣。舉個例子,在 32 位機器上,假如 a 是 int 型變量,pa 是指向 a 的指針變量,b 是一個 double 型變量,pb 是指向 b 的指針變量,那麼 a 在記憶體中占四個位元組,b 在記憶體中占 8 個位元組,假如 a 在記憶體中分布是從 0x11111110~0x11111113,而 b 在記憶體中分布是 0x11112221 至 0x11112228,那麼指針變量 pa 中存儲的内容是 0x11111110,而 pb 中存儲就是 0x11112221,看到了吧,也就是說,pa 和 pb 中存儲的都是位址,而且都是  32 位的二進制位址;再者,因為存儲這樣的位址需要 4 個位元組,是以無論是 int 型指針變量 pa 或者是 double 型指針變量  pb,它們所占的記憶體大小都是四個位元組,從這點來說,不管什麼類型的指針都是一樣的,是以不論按整型指針變量、字元型指針變量、浮點型指針變量等等來區分指針變量。總結起來,指針變量和 int、float、char 等類型一樣同屬變量類型,指針變量類型占四個位元組(32 位機器下),存儲的是 32 位的記憶體位址。下面的代碼證明這一點:

c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針
c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針

上面介紹的是指針變量的一個方面,指針變量還有另外一層含義:在 C/C++ 中星号(*)被定義成取内容符号,雖然所有指針變量占的記憶體大小和存儲的記憶體位址大小都是一樣的,但是由于存儲的隻是資料的記憶體首位址,是以指針變量存儲的記憶體位址所指向的資料類型決定着如何解析這個首位址,也就是說對于 int 型指針變量,我們需要從該指針變量存儲的(首)位址開始向後一直搜尋 4 個位元組的記憶體空間,以圖中的變量 a 為例就是從 0x12ff60~0x12ff63,對于變量 b 就是  0x12ff44~0x12ff4b。是以從這個意義來上講,當我們使用 *pa,必須先知道 pa 是一個整型的指針,這裡強調“整型”,而 a 的值 1 也就存儲在從 0x12ff60~0x12ff63 這四個位元組裡面,當我們使用*pb,必須先知道 pb 是一個 double 型指針,這裡強調"double",也就是說值 2.0000 存儲在 0x12ff44~0x12ff4b  這八個位元組裡面。是以,我們對指針變量進行算術運算,比如  pa + 2,pb + + 之類的操作,是以資料類型大小為機關的,也就是說 pa+2,相當于 0x12ff60+sizeof(int) * 2 = 0x12ff60 + 4 * 2 = 0x12ff68,不是0x12ff60 + 2哦;而pb - -相當于 0x12ff44 +  sizeof(double) * 1 = 0x12ff44 + 8 * 1 = 0x12ff4c。了解這一點很重要。同理 &a + 2 和 &b - 1 也是一樣(注意由于 &b 是一個指針常量,是以寫成 &b - - 是錯誤的)。

指針變量和指針常量

指針變量首先是一個變量,由于指針變量存儲了某個變量的記憶體首位址,我們通常認為“指針變量指向了該變量”,但是在這個時刻指針變量 pa 指向變量 a,下個時候可能不存儲變量 a  的首位址,而是存儲變量 c 的首位址,那麼我們可以認為這個時候,pa 不再指向 a,而是指向 c。請别嫌我啰嗦,為了幫助你了解,我是故意說得這麼細的,後面我們讨論進階主題的時候,當你覺得迷糊,請回來反複咀嚼一下這段話。也就是說指針變量是一個變量,它的值可以變動的。

相反,指針常量可通俗地了解為存儲固定的記憶體單元位址編号的“量”,它一旦存儲了某個記憶體位址以後,不可再改存儲其他的記憶體位址了。是以指針常量是堅韌,因為它“咬定青山不放松”;說是“癡情”,因為它“曾經滄海難為水”。我這裡講的指針常量對應的是 const 關鍵字定義的量,而不是指針字面量。像  &a,&b,&a + 2 等是指針字面量,而 const int *p = &a;中的 p 才算是真正的指針常量,指針常量一般用在函數的參數中,表示該函數不可改變實參的内容。來看一個例子吧:

c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針

上面的函數由于修改了一個常指針(多數情況下等同指針常量),因而會編譯出錯:error C3892: “x” :不能給常量指派。

指針變量與數組

記得多年以前,我在學生會給電子技術部和地理資訊系統專業的同學進行 C 語言教育訓練時,這是一個最讓他們頭疼和感到一頭霧水的話題,尤其是指針變量與二維數組的結合,我永遠忘不了胡永月那一臉迷惑與無助的表情。今天我這裡給大家深入地分析一下。先看一個例子:

c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針

如果你能得出下面這樣的結果,說明你已經基本上對數組與指針的概念了解清楚了:

c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針

通過上圖,我們可以知道*(a + 1) = 2, *(ptr - 1) = 5。且不說很多同學根本得不到這樣的結果,他們看到 int *ptr = (int*)(&a+1);這樣的語句就已經懵了,首先,我們知道 C 語言中規定數組名表示這個數組的首位址,而這裡竟然出現了 &a 這樣的符号,本來 a 就是一個指針常量了,這裡對 &a 再次取位址難道不是非法操作嗎?哈哈,當你有這樣的疑問的時候,說明你對二維數組相關知識了解不深入。我這裡先給你補充下知識點吧:

看這樣一個二維數組:int arr[3][4],這個數組布局如下:

c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針

這是一個3行4列的數組,它在記憶體中的分布如下:

c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針

這裡每一個數組元素占 4 位元組空間,我們知道 C 語言規定,數組名 arr 是整個數組元素的首位址,比如是 0x0012ff08,而像 arr[0]、arr[1]、arr[2] 分别是數組第一行、第二行、第三行的首位址,也就是 0x0012ff08、0x0012ff18、0x0012ff28。

我們把 arr、arr[0] 和 &arr[0][0] 單獨拿出來分析,因為數組的首位址也是第一列的首位址,同時也是第一個元素的首位址,是以 arr 和 arr[0] 和 &arr[0][0] 表示的都是同一個位址,但是這三個首位址在進行算術運算時是有差別的。如果 &arr[0][0] + 1,這裡的相當于跳一個元素的記憶體位元組數,也就是 4 個;但是 arr[0] + 1,移動的記憶體位元組數是一列元素所占的位元組數,也就是 4 * 4 = 16 個;最後,也是最讓人迷惑的的就是 arr + 1,這個時候移動的記憶體數目是整個數組占的記憶體位元組數,也就是  48 個位元組數,是以 a + 1 所表示的記憶體位址已經不屬于這個數組了,這個位址位于數組最後一個元素所占記憶體空間的下一個位元組空間。

光有這些知識還是不能解決上面的問題,我們再補充一個知識點。

C++ 是一種強類型的語言,其中有一種類型叫 void 類型,從本質上說 void 不是一種類型,因為變量都是“有類型”的,就好像人的性别,不是男人就是女人,不存在無性别的人,是以  void 更多是一種抽象。在程式中,void 類型更多是用來“修飾”和“限制”一個函數的:例如一個函數如果不傳回任何類型的值,可以用 void 作傳回類型;如果一個函數無參數清單,可以用 void 作為參數清單。

跟 void 類型”修飾“作用不同,void 型指針作為指向抽象資料的指針,它本質上表示一段記憶體塊。如果兩個指針類型不同,在進行指針類型指派時必須進行強制類型轉換,看下面的例子:

c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針

但是可以将任何指針類型指派給 void 類型而無須進行強制類型轉換:

c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針

當然,如果把 void 型指針轉換成并不是它實際指向的資料類型,其結果是不可預測的。試想,如果把一個 int 型指針賦給  void 型,然後再把這個 void 型指針強制轉換成 double 型指針,這樣的結果是不可預測的。因為不同資料類型所占記憶體大小不一樣,這樣做可能或截斷記憶體資料或者會增加一些未知的額外資料。是以,最好是将 void 類型指針轉換成它實際資料類型指針。

有了上面的說明,你應該能看懂 C 函數庫中下面這個函數的簽名含義了吧?

void *memcpy(void *dest,const void *src,size_t len);
           

在這裡,任何資料類型的指針都可以傳給這個函數,是以這個函數成為了一個通用的記憶體複制函數。

好了,說了這麼多,回答最初的那個問題上:

c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針

我們來分析一下。首先,我們可以将這個數組看成是一個特殊的二維數組,也就是 1 行 5 列的二維數組,現在 a 表示的是第一個元素的首位址,那麼 a + 1 指向的就是下一個元素的記憶體首位址,是以*(a + 1) = 2;而 &a 則是表示整個數組的首位址,那麼 &a + 1 移動的記憶體數目就是整個數組所占位元組數,假如這裡我們量化來說明,假如原先數組中第一個元素的首位址是 1,那麼 &a + 1 表示的就是 21,而這個位址已經不屬于數組了,接着通過(int*)(&a + 1)将數組指針轉換成整型指針,這樣原先 &a + 1 表示的資料範圍是 21~40 一下縮小到 21~24,正好是一個 int 型的大小,是以 ptr - 1 的存儲的位址就是 17 了,表示的資料記憶體範圍是 17~20,這樣*(ptr - 1)正好就是最後一個元素 5 了。

但是話說回來,首先這樣的轉換安全與否尚有争議,再次,這樣的程式晦澀難懂,難于了解,是以建議不要寫出這樣的程式。

上面的例子,隻是通過一些簡單的資料類型來說明記憶體分布,但是實際對于一些複雜的資料類型,尤其是一些自定義的類或者結構體類型,記憶體分布必須還要充分考慮到位元組對齊。比如下面的代碼:

c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針

這是輸出結果:

c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針

由于結構體 s1 中存在位元組對齊現象(以 sizeof(double) = 8 個位元組對齊),是以 s1 占據 24 位元組記憶體,而 s2 隻占 16 個位元組。知道這點,我們平常在設計結構體字段的時候,就可以合理安排字段順序來使用更少的記憶體空間了。

函數指針

函數指針是指向函數的指針變量。因而“函數指針”本身首先應是指針變量,隻不過該指針變量指向函數。這正如用指針變量可指向整型變量、字元型、數組一樣,這裡是指向函數。C/C++ 程式在編譯時,每一個函數都有一個入口位址,該入口位址就是函數指針所指向的位址。有了指向函數的指針變量後,可用該指針變量調用函數,就如同用指針變量可引用其他類型變量一樣,在這些概念上是一緻的。函數指針有兩個用途:調用函數和做函數的參數。

我們先來先使用函數指針調用函數。如下圖所示:

c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針

上面的代碼首先是定義了一個函數f,然後是定義一個函數指針 pf,接着在主函數裡面将函數f的位址指派給函數指針,這樣 pf 就指向了函數 f,這樣使用*pf 就可以直接調用函數了。但是上面的例子定義函數指針的方法在某些編譯器中是無法通過的,最好通過 typedef 關鍵字定義函數指針,推薦的寫法如下:

c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針

通過上面的例子,我們來總結下函數指針的定義和使用方法:

首先,通過 typedef 關鍵字定義一個函數指針類型,然後定義一個該函數指針類型變量,接着将函數的入口位址指派給該函數指針類型變量,這樣就可以通過這個函數指針變量調用函數了。

需要注意的是,定義函數指針類型時的函數簽名(包括函數傳回值和函數參數清單的類型、個數、順序)要将指派給該類型變量的函數簽名保持一緻,不然可能會發生很多無法預料的情況。還有一點,就是 C/C++ 規定函數名就表示函數入口位址,是以,函數名指派時函數名前面加不加取位址符 & 都一樣,也就是說 PF pf = f 等價于 PF pf = &f。這個 & 是可以省略的。但是這是單個函數的情況,在 C++ 中取類的方法函數的位址時,這個 & 符号式不能省略的,見下面的例子:

c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針

函數指針的另外一個用處,而且是用的最多的,就是作為一個函數的參數。也就是說某個函數的某個參數類型是一個函數,這在 windows 程式設計中作為回調函數(callback)尤其常見。我們來看一個例子:

c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針

上圖中,函數 f2 第一個參數類型是一個函數,我們傳入函數 f1 作為參數。這種函數參數是函數類型的用法很重要,建議大家掌握。

指針變量的定義方法

先插播一段廣告,說下main函數的傳回值問題,如下圖:

c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針

這種main函數無傳回值的寫法,在國内各大C/C++教材上屢見不鮮,這種寫法是錯誤的!

有一點你必須明确:C/C++ 标準中從來沒有定義過 void main()這樣的代碼形式。C++ 之父 Bjarne Stroustrup 在他的首頁 FAQ 中明确地寫了這樣一句話:

“在C++中絕對沒有出現過void main(){ } 這樣的函數定義,在C語言中也是。”

main 函數的傳回值應該定義為 int 型,在 C/C++ 标準中都是這樣規定的。在 C99 标準規定,隻有以下兩種定義方式是正确的:

int main(void);int main(int argc,char *argv[]);
           

雖然在 C 和 C++ 标準中并不支援 void main(),但是在部分編譯器中 void main()依舊是可以通過編譯并執行的,比如微軟的 VC++。由于微軟産品的市場占有率和影響力很大,因為在某種程度上加劇了這種不良習慣的蔓延。不過,并非所有犯人編譯器都支援 void main(),gcc 就站在 VC++ 的對立面,它是這一不良習氣的堅定抵制者,它會在編譯時明确地給出一個錯誤。

廣告播完,我們回到正題上來。我們來看下如何定義一個指針,首先看一個例子:

c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針

我來替你回答吧,你肯定認為 a 是一個指針變量,b 是一個整型變量,c 和 d 都是一個指針變量。好吧,恭喜你,答錯了!

其實定義指針變量的時候,星号(*)無論是與資料類型結合還是與變量名結合在一起都是一樣的!但是,為了便于了解,還是推薦大家寫成第一種形式,第二種形式容易誤導人,不是嗎?而且第一種形式還有一個好處,我們可以這樣看:

int *a;    //将*a 看成一個整體,它是一個 int 型資料,那麼 a 自然就是指向*a 的指針了。

說完定義指針的方法,下面我們來看下如何初始化一個指針變量,看下面的代碼:

c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針

上面的代碼有錯誤嗎?

錯誤在于我們不能這樣寫:int *p = 1; 由于 p 是一個匿名指針,也就是說 p 沒有正确的初始化,它可能指向一個不确定的記憶體位址,而這個記憶體位址可能是系統程式記憶體所在,我們将數值 1 裝入那個不确定的記憶體單元中是很危險的,因為可能會破壞系統那個記憶體原來的資料,引發異常。換另一個方面來看,将整型數值 1 直接指派給指針型變量 p 是非法的。

這樣的指針我們稱為匿名指針或者野指針。和其他變量類型一樣,為了防止發生意料之外的錯誤,我們應該給新定義的指針變量一個初始值。但是有時候,我們又沒有合适的初始值給這個指針,怎麼辦?我們可以使用 NULL 關鍵字或者 C++ 中的  nullptr。代碼如下:

c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針

通過上面的寫法就告訴編譯器,這兩個指針現在不會指向不确定的記憶體單元了,但是目前暫時不需要使用它們。 

C++中的引用

C++ 中不僅有指針的概念,而且還存在一個引用的概念,看下面的代碼:

c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針

我開始在接觸這個概念的時候,老是弄錯。當時這麼想的,既然 b 是 a 的引用,那麼 &b 應該等于 a 吧?也就是說,在需要使用變量 a 的時候,可以使用 &b 來代替。

上面的這種認識是錯誤的!所謂引用,使用另外一個變量名來代表某一塊記憶體,也就是說 a 和 b 完全是一樣,是以任何地方,可以使用 a 的,換成 b 也可以,而不是使用 &b,這就相當于同一個人有不同的名字,但是不管哪個名字,指的都是同一個人。

c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針

新手在剛接觸引用的使用,還有一個地方容易出錯,就是忘記給引用及時初始化,注意這裡的“及時”兩個字,C++ 規定,定義一個引用時,必須馬上初始化。看下面的代碼:

c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針

傳值還是傳引用(by value or by reference)

看下面的僞代碼:

c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針

在涉及到利用一個已有初值的變量給另外一個變量指派時,必須考慮這樣的情況。圖中變量 a 已經有了初值,然後利用 a 來給 b 賦初值,那麼最後改變 b 的值,a 的值會不會受影響呢?這就取決于 b 到底是 a 的副本還是和 a 同時指向同一記憶體區域,這就是我們常說的指派時是傳值還是傳引用。各大語言都是這樣規定的,也就是說不局限于 C/C++,同時 Java、C#、php、javascript 等都一樣:

如果變量類型是基中繼資料類型(基礎資料類型),比如 int、float、bool、char 等小資料類型被稱為基中繼資料類型(primitive data type),那麼指派時傳的是值。也就是說,這個時候 b 的值是 a 的拷貝,那麼更改 b 不會影響到 a,同理更改 a 也不會影響到 b。

但是,如果變量類型是複雜資料類型(complex data type),不如數組、類對象,那麼指派時傳的就是引用,這個時候,a 和 b 指向的都是同一塊記憶體區域,那麼無論更改 a 或者 b 都會互相影響。

讓我們來深入地分析下,為什麼各大語言都采取這種機制。對于那些基中繼資料類型,由于資料本身占用的記憶體空間就小,這樣複制起來不僅速度快,即使這樣的變量數目很多,總共也不會占多大空間。但是對于複雜資料類型,比如一些類對象,它們包含的屬性字段就很多,占用的空間就大,如果指派時,也是複制資料,那麼一個兩個對象還好,一旦多一點比如 10  個、100 個,會占很大的記憶體單元的,這就導緻效率的下降。

最後,提醒一點,在利用 C++ 中拷貝構造函數複制對象時需要注意,基中繼資料類型可以直接複制,但是對于引用類型資料,我們需要自己實作引用型資料的真正複制。

C/C++中的new關鍵字與Java、C#中的關鍵字對比

c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針

我大學畢業的時候癡迷于于網頁遊戲開發,使用的語言是 flash 平台的 actionscript 3.0(簡稱 as3,唉,如今已經沒落),我剛開始由 as3 轉行至 C/C++,對于 C/C++ 中 new 出來的對象必須通過指針對象來引用它非常不習慣。上圖中,Object 是一個類(class),在 Java 或者 C# 等語言中,通過 new 關鍵字定義一個對象,直接得到 Object 的執行個體,也就是說後續引用這個對象,我們可以直接使用 obj.property 或者 obj.method()等形式,但是在 C++ 中不行,比如用一個指針去接受這個 new  出來的對象,我們引用這個對象必須使用指針引用運算符 ->,也就是我們需要這樣寫:pObj->property 或 pObject->method()。代碼如下:

c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針

當然 C++ 中還有一種不需要使用指針就可以執行個體化出來類對象的方法,從 Java、C# 等轉向 C++ 的程式員容易誤解為未初始化對象變量的定義,看下列代碼:

c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針

這是 C++ 中利用 Object 類執行個體化兩個對象 obj1 和 obj2,obj2 因為調用構造函數傳了兩個參數 param1,param2 還好了解一點,對于 obj1 很多 Java 或者 C# 的程式員開始很難接受這種寫法,因為如果放在 Java 或者 C# 中,obj1 根本就沒有被執行個體化嘛,在他們看來,obj1 隻是一個簡單的類型申明。希望Java、C# 等程式員要轉換過思維來看待 C++ 中的這種寫法。

還有一點也容易出錯,在 C++ 中,this 關鍵字是一個指針,而不是像在 Java、C# 中是一個類執行個體。也就是說,在 C++ 中*this 才等價于 Java、C# 中的 this。是以寫法也就不一樣了:

c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針
c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針

Windows程式設計中的指針

windows 是作業系統是用 C 語言寫出來的,是以盡管你在  windows 中看到很多不認識的資料類型,但是這些資料類型也是通過基本的 C 語言類型組裝起來的。我們這裡隻介紹  windows 中指針型資料。

定義指針資料類型必須使用星号(*),但是 windows 為了開發的友善,通過宏定義将指針“隐藏起來”,嚴格地說應該是将星号隐藏起來了,下面給出一些例子:

c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針

原文連結:https://mp.weixin.qq.com/s/Ua1xi_K2GuYusM0e8HRNhg

c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針

創智俱樂部

微信:sziitlSA

c定義一個整型數組_轉載 | 深入了解 C/C++ 中的指針

一個讓你漲姿勢的社團

長按二維碼關注