深入理解指標和陣列 指標和函式

2021-08-22 05:02:19 字數 3973 閱讀 6922

指向函式指標陣列的指標

在了解了指標之後,可以得出,指標就是乙個變數,用來存放位址的變數。位址就相當於門牌號,而指標就是存放它的變數,對指標進行解引用(*)則相當於拿一把鑰匙去開對應的門牌號的門,開啟門,訪問其中的變數。

指標的大小在32位平台上是4個位元組,在64位平台上是8個位元組。

如有以下**:

先看下面的例子:

int a[5] = ;

這裡定義了乙個陣列,放有5個int型的資料,a就是乙個陣列。陣列在記憶體中的儲存如下:

指標和陣列之間沒有任何關係!!!

指標就是指標,指標變數在32位系統下,永遠佔4個byte,其值為某乙個記憶體的位址。

陣列就是陣列,其大小與元素的型別和個數有關。

我們首先了解一下指標和陣列它們分別可以怎樣訪問:

在函式內部有以下定義:如:

a)char *p = 「abcdef」;

b)char a = 「abcdef」;

我們可以通過以指標的形式訪問和以下標的形式訪問來分別對指標和陣列進行訪問,結果如下:

通過上述分析,我們可以明白指標和陣列的訪問方式了。由此,我們可以進一步分析出指標和陣列沒有任何關係,它們是兩碼事。

定義為陣列,宣告為指標

檔案1中定義如下:

char a[100];

檔案2中宣告如下:

extern char *a;

那麼在檔案2中可以訪問到檔案1中陣列中的內容嗎,來看如下分析:

定義為指標,宣告為陣列

檔案1中定義如下:

char *p = 「abcdefg」;

檔案2中宣告如下:

extern char p;

在檔案1中,編譯器分配4個byte空間並命名為p,同時p裡儲存了字串的首字元的位址。而在檔案2中,編譯器認為p是乙個陣列,其大小為4個byte,陣列內儲存的是char型別的資料。在檔案2中使用p的過程如下:

經過上述對在不同檔案下的分析,我們可以看到,指標和陣列是兩碼事,它們沒有任何關係。

指標陣列,首先,它是乙個陣列,陣列的元素都是指標,陣列佔多少個位元組由陣列本身決定,它是用來儲存指標的陣列。

如: int *p[10];

「[ ]」 的優先順序比 「 * 」 高。

p要先與 「[ ]」 結合,構成乙個陣列,陣列名為p,「int *」表示的是存放在陣列中元素的型別為整型指標。由此,我們知道,這是乙個存放10個int型別的指標的陣列,即指標陣列。p在記憶體中的存放如下:

陣列指標,首先,它是乙個指標,它指向乙個陣列。只要是指標,在32位系統下永遠佔4個byte,它是用來儲存陣列的位址的。

如: int (*a)[10];

a先與 「 * 」結合,構成乙個指標,指標名為a,int [10]表示的是存放在指標中的位址的型別是存放有10個整型元素的陣列。由此,我們知道,這是乙個指向10個int型別資料的指標,即陣列指標。a在記憶體中的存放如下:

顧名思義,函式指標就是函式的指標。它是乙個指標,指向乙個函式。只要是指標,在32位系統下就是4個byte,它是用來儲存函式的位址的。

如: char*

(*fun)(char

*p1,char

*p2 );

fun先與 「 * 」 結合,構成乙個指標,指標名為fun,char * (char *p1,char

*p2)這是乙個函式。由此,我們知道,這是乙個指向函式的指標,函式的引數是兩個型別為char

*的p1和p2,函式的返回型別為char

*。讓我們來看兩段有趣的**:

1、(*(void(

*)())0)();

分析:void(*)(),可以明白這是乙個函式指標型別。這個函式沒有引數,沒有返回值。

(void(*)())0,這是將0強制轉換為函式指標型別,0是乙個位址,也就是說,乙個函式存在首位址為0的一段空間內。

(* (void(*)())0),這是取0位址開始的一段記憶體裡面的內容,其內容就是儲存在首位址為0的一段空間內的函式。

(* (void(*)())0)(),這是對上一步所拿到的函式進行呼叫。

2、void(*signal(int,void(

*)(int)))(int);

分析:void(*)(int),這是乙個函式指標,該函式指標指向的是函式引數為int,返回型別為void的函式。

void(*signal(int,void(

*)(int)))(int); signal是乙個函式宣告,它有兩個引數,乙個是int型別,另乙個是上述所說的函式指標型別;signal函式的返回型別是void(

*)(int)型別。

既然指標可以存放在乙個陣列裡,那麼函式指標也可以存放在陣列裡,根據上述函式指標所舉的例子:char*

(*fun)(char

*p1,char

*p2 );這是乙個函式指標,把該式修改一下,得到:

char

* (*fun[3])(char

*p1,char

*p2 );

分析:首先,fun先與中括號 「[ ]」 結合,說明fun是乙個存放三個元素的陣列,然後將fun[3]暫時拿開,可以看到剩下的是乙個函式指標,則說明,fun是乙個存有三個函式指標的陣列。函式指標陣列是用來存放函式的位址的。

有如下**:

#include #include char *fun1(char *p)

char *fun2(char *p)

char *fun3(char *p)

int main()

可以看到,在main函式中定義了乙個名為pf的函式指標陣列,用來存放函式的位址,通過對陣列中元素的使用來呼叫相對應的函式。

轉移表通過對函式指標陣列有了一定的了解之後,我們可以用它來實現乙個轉移表,即所謂的計算器。

**如下:

#include void menu()

int add(int x, int y)

int sub(int x, int y)

int mul(int x, int y)

int div(int x, int y)

int main()

; do

else if(input == 0)

else

}while(input);

return 0;

}

通過將函式的位址存放到乙個陣列裡,在使用時通過陣列裡存放的元素(即函式的位址)來呼叫該函式。

在前面,我們提到了函式指標陣列,它是用來存放函式位址的乙個陣列,那麼這裡的指向函式指標陣列的指標不就是指向上述陣列的指標嘛,存放的就是函式指標陣列的位址呀。根據上述函式指標陣列所舉的例子:

char

* (*fun[3])(char

*p1,char

*p2 );

把該式修改一下,得到:

char

* (*(

*fun)[3])(char

*p1,char

*p2 );

讓我們來解析一下這個式子,首先,fun先與 「 * 」 結合,構成乙個指標,再與 「 [ ] 」 結合,說明這個指標指向的是乙個存放三個元素的陣列(即fun中存放的是乙個存放有三個元素的陣列的位址),再根據其餘的符號可以得到,這三個元素的型別是函式指標。

根據函式指標陣列的**改寫如下:

#include #include char *fun1(char *p)

char *fun2(char *p)

char *fun3(char *p)

int main()

可以看到,在main函式裡先定義了乙個函式指標陣列,用來存放三個函式的位址,然後定義了乙個指向函式指標陣列的指標來存放這個陣列的位址(即陣列首元素的位址),通過找到陣列的位址來訪問陣列中的元素來實現對三個函式的呼叫。

上述內容均為學習過程中的總結,如有不足之處,請指正。

深入理解指標 陣列

指標的本質是乙個變數,也需要占用一定的空間一般為四個位元組不論其指向的型別。指標用來儲存記憶體位址的值。通過指標我們能做到不通過變數來改變變數的值。號的意義 在指標宣告時,代表宣告的變數為指標變數。int i 10 int p i 在指標使用時,表示取指標所指向的位址中的值。p 12 另外指標宣告時...

深入理解函式指標和函式陣列

理解函式指標首先理解它的型別,首先函式指標是個指標,他指向乙個函式。其次與普通變數指標相同重要的一點是函式指標的型別,如果兩個函式的引數個數 參數列 返回值型別都相同,則這兩個函式是同乙個型別。換句話說同一型別的函式指標可以指向這兩個函式 我們先看乙個例子 include using namespa...

深入理解指標函式

1.指標函式的定義 顧名思義,指標函式即返回指標的函式。其一般定義形式如下 型別名 函式名 函式引數表列 其中,字尾運算子括號 表示這是乙個函式,其字首運算子星號 表示此函式為指標型函式,其函式值為指標,即它帶回來的值的型別為指標,當呼叫這個函式後,將得到乙個 指向返回值為 的指標 位址 型別名 表...