C語言的那些小秘密之函式指標

2022-04-01 16:03:03 字數 4485 閱讀 2277

我們經常會聽到這樣的說法,不懂得函式指標就不是真正的c語言高手。我們不管這句話對與否,但是它都從側面反應出了函式指標的重要性,所以我們還是有必要掌握對函式指標的使用。先來看看函式指標的定義吧。

函式是由執行語句組成的指令序列或者**,這些**的有序集合根據其大小被分配到一定的記憶體空間中,這一片記憶體空間的起始位址就成為函式的位址,不同的函式有不同的函式位址,編譯器通過函式名來索引函式的入口位址,為了方便操作型別屬性相同的函式,c/c++引入了函式指標,函式指標就是指向**入口位址的指標,是指向函式的指標變數。 因而「函式指標」本身首先應該是指標變數,只不過該指標變數指向函式。這正如用指標變數可指向整形變數、字元型、陣列一樣,這裡是指向函式。c在編譯時,每乙個函式都有乙個入口位址,該入口位址就是函式指標所指向的位址。有了指向函式的指標變數後,可用該指標變數呼叫函式,就如同用指標變數可引用其他型別變數一樣,在這些概念上是一致的。函式指標有兩個用途:呼叫函式和做函式的引數。

函式指標的宣告方法為:

資料型別標誌符 (指標變數名) (形參列表);

「函式型別」說明函式的返回型別,由於「()」的優先順序高於「*」,所以指標變數名外的括號必不可少,後面的「形參列表」表示指標變數指向的函式所帶的引數列表。例如:

int function(int x,int y); /* 宣告乙個函式 */

int (*f) (int x,int y); /* 宣告乙個函式指標 */

f=function; /* 將function函式的首位址賦給指標f */

賦值時函式function不帶括號,也不帶引數,由於function代表函式的首位址,因此經過賦值以後,指標f就指向函式function(int x,int y);的**的首位址。

下面的程式說明了函式指標呼叫函式的方法:

例一、

#include

int max ( int x, int y)

int min ( int x, int y)

注意:以上**的紅色部分我們將會在接下來的**分析部分進行講解,讀者也可以思考下如果執行注釋部分,結果是否還是正確的呢?

f是指向函式的指標變數,所以可把函式max()賦給f作為f的值,即把max()的入口位址賦給f,以後就可以用f來呼叫該函式,實際上f和max都指向同乙個入口位址,不同就是f是乙個指標變數,不像函式名稱那樣是死的,它可以指向任何函式,就看你想怎麼做了。在程式中把哪個函式的位址賦給它,它就指向哪個函式。而後用指標變數呼叫它,因此可以先後指向不同的函式。不過注意,指向函式的指標變數沒有++和--運算,用時要小心。

函式括號中的形參可有可無,視情況而定,不過,在某些編譯器中這是不能通過的。這個例子的補充如下。

1.定義函式指標型別:

typedef int (*fun_ptr)(int,int);

2.申明變數,賦值:

fun_ptr max_func=max;

也就是說,賦給函式指標的函式應該和函式指標所指的函式原型是一致的。

例二、

#include

void filefunc()

void editfunc()

void main()

看了上面兩段**,應該都知道如何用函式指標來呼叫函式了,但是我們剛剛在上面的描述中留下過乙個問題,就是執行注釋部分f=&max;結果是否還是正確的呢?下面我就給出上面兩個執行結果的對別,然後來分析下原因。

有注釋前的執行結果為:

把注釋部分加進去的執行結果為:

對比以上的執行結果可以看出,f=&max語句被執行時的結果和沒有被執行時的結果是一樣的。為什麼會出現這樣的結果呢?答案是這是編譯器處理的,max本身就是個位址,它沒有放到任何變數裡,自然沒有取它的位址一說。所以我們可以看看在除錯的過程中&max的值和max的值是一樣的。除錯**如下:

root@ubuntu:/home/shiyan# gdb ss

gnu gdb (ubuntu/linaro 7.2-1ubuntu11) 7.2

license gplv3+: gnu gpl version 3 or later

this is free software: you are free to change and redistribute it.

there is no warranty, to the extent permitted by law. type "show copying"

and "show warranty" for details.

this gdb was configured as "i686-linux-gnu".

for bug reporting instructions, please see:

...reading symbols from /home/shiyan/ss...done.

(gdb) list

1 #include

2 int max ( int x, int y)

3 int min ( int x, int y)

(gdb) b 4

breakpoint 1 at 0x80483ec: file hanshu.c, line 4.

(gdb) r

starting program: /home/shiyan/ss

breakpoint 1, main () at hanshu.c:5

5 0x80483c4

(gdb) print f

$2 = (int (*)(int, int)) 0xbffff6c8

(gdb) s

7 printf ( "%d,%d\t", max (2,6), (f)(5,4));

(gdb)

max (x=5, y=4) at hanshu.c:2

2 int max ( int x, int y)

(gdb) print max

$3 = 0x80483c4

(gdb) print &max

$4 = (int (*)(int, int)) 0x80483c4

(gdb) print *max

$5 = 0x80483c4

(gdb) s

max (x=2, y=6) at hanshu.c:2

2 int max ( int x, int y)

(gdb) s

main () at hanshu.c:8

8 f=min;

(gdb) print min

$6 = 0x80483d3

(gdb) print &min

$7 = (int (*)(int, int)) 0x80483d3

(gdb) print *min

$8 = 0x80483d3

(gdb) s

9 printf (" %d,%d\t" , min (2,6), (f)(5,4));

(gdb) print f

$9 = (int (*)(int, int)) 0x80483d3

(gdb) print &f

$10 = (int (**)(int, int)) 0xbffff6ac

(gdb) print *f

$11 = 0x80483d3

(gdb) s

min (x=5, y=4) at hanshu.c:3

3 int min ( int x, int y) 0x80483d3

(gdb) s

main () at hanshu.c:10

10 }

在除錯的過程中我print了很多的資訊,細心的讀者肯定能獲得更多的收穫,尤其是對變數f的print,讀者可以自己閱讀,學到更多的東西。我給出的只是乙個參考的除錯方式,希望讀者能夠舉一反三,自己對**進行實際的除錯,加深理解。

上面說的都是用指標來實現函式的呼叫,接下來我們看乙個用函式指標作為引數的用法。

#include

using namespace std;

typedef int (*print)(int );

int fun1(int i)

void fun2(int j,print prt)

void main()

執行結果如下:

看了上面的描述,我想都對函式指標的概念有了大致的了解,另外乙個希望大家不要混淆的概念就是指標函式,,這兩個概念都是簡稱,指標函式是指帶指標的函式,即本質是乙個函式。我們知道函式都又有返回型別(如果不返回值,則為無值型,即為void),只不過指標函式返回型別是某一型別的指標。

其定義格式如下所示:

返回型別識別符號 *返回名稱(形式參數列)

返回型別可以是任何基本型別和復合型別。返回指標的函式的用途十分廣泛。事實上,每乙個函式,即使它不帶有返回某種型別的指標,它本身都有乙個入口位址,該位址相當於乙個指標。比如函式返回乙個整型值,實際上也相當於返回乙個指標變數的值,不過這時的變數是函式本身而已,而整個函式相當於乙個「變數」,關於函式的返回值問題我將在下一章來講解,本章到此為止。希望以上內容對你有所幫助!

**: 

C語言的那些小秘密之函式指標

我們經常會聽到這樣的說法,不懂得函式指標就不是真正的c語言高手。我們不管這句話對與否,但是它都從側面反應出了函式指標的重要性,所以我們還是有必要掌握對函式指標的使用。先來看看函式指標的定義吧。函式是由執行語句組成的指令序列或者 這些 的有序集合根據其大小被分配到一定的記憶體空間中,這一片記憶體空間的...

C語言的那些小秘密之函式指標

函式是由執行語句組成的指令序列或者 這些 的有序集合根據其大小被分配到一定的記憶體空間中,這一片記憶體空間的起始位址就成為函式的位址,不同的函式有不同的函式位址,編譯器通過函式名來索引函式的入口位址,為了方便操作型別屬性相同的函式,c c 引入了函式指標,函式指標就是指向 入口位址的指標,是指向函式...

C語言的那些小秘密之指標(一)

懂得c語言的人都知道,c語言之所以強大,以及其自由性,絕大部分體現在其靈活的指標運用上。因此,說指標是c語言的靈魂,一點都不為過。所以從我的標題加了個 一 也可以看出指標的重要性,我盡可能的向大家交代清楚我對於指標的理解。所以在講解的過程中我盡可能的用 加文字的描述方式,通過 的分析來加深我們對於指...