函數指針與指針函數的區別

1 函數指針

在程序運行中,函數代碼是程序的算法指令部分,它們和數組一樣也佔用存儲空間,都有相應的地址。可以使用指針變量指向數組的首地址,也可以使用指針變量指向函數代碼的首地址,指向函數代碼首地址的指針變量稱爲函數指針

1.1 函數指針定義

函數類型(*指針變量名)(形參列表);

“函數類型”說明函數的返回類型,由於“()”的優先級高於“*”,所以指針變量名外的括號必不可少,後面的“形參列表”表示指針變量指向的函數所帶的參數列表。例如:

int(*f)(int x);

double(*ptr)(double x);

在定義函數指針時請注意:

函數指針和它指向的函數的參數個數和類型都應該是—致的;函數指針的類型和函數的返回值類型也必須是一致的。

1.2 函數指針的賦值

函數名和數組名一樣代表了函數代碼的首地址,因此在賦值時,直接將函數指針指向函數名就行了。例如,

intfunc(int x);   /* 聲明一個函數 */

int(*f) (int x);    /* 聲明一個函數指針 */

f=func;            /* 將func函數的首地址賦給指針f */

賦值時函數func不帶括號,也不帶參數,由於func代表函數的首地址,因此經過賦值以後,指針f就指向函數func(x)的代碼的首地址。

1.3 通過函數指針調用函數

函數指針是通過函數名及有關參數進行調用的。

與其他指針變量相類似,如果指針變量pi是指向某整型變量i的指針,則*pi等價於它所指的變量i;如果指針變量pf是指向某浮點型變量f的指針,則*pf就等價於它所指的變量f。同樣地,fun是指向函數func(x)的指針,則*fun就代表它所指向的函數func。所以在執行了f=func;之後,(*f)和func代表同一函數。

由於函數指針指向存儲區中的某個函數,因此可以通過函數指針調用相應的函數。現在我們就討論如何用函數指針調用函數,它應執行下面三步:

 首先,要說明函數指針變量。

例如:int(*f)(int x);

其次,要對函數指針變量賦值。

例如:f=func;    (func(x)必須先要有定義)

最後,要用 (*指針變量)(參數表);調用函數

例如:    (*f)(x);(x必須先賦值)

【例】任意輸入n個數,找出其中最大數,並且輸出最大數值。

#include<stdio.h>

main()

{

        int f();

        int i,a,b;

        int (*p)();    /* 定義函數指針 */

       scanf("%d",&a);

        p=f;            /* 給函數指針p賦值,使它指向函數f */

        for(i=1;i<9;i++)

        {

               scanf("%d",&b);

                a=(*p)(a,b);    /* 通過指針p調用函數f */       

         }

        

zprintf("TheMax Number is:%d\n",a)

}

 

f(int x,int y)

{   

       int z;   

       z=(x>y)?x:y; 

       return(z);

}

運行結果爲:

343 -45 4389 4235 1 -534 988 555 789↙ The Max Number is:4389

 

2 指針函數

一個函數不僅可以帶回一個整型數據的值,字符類型值和實型類型的值,還可以帶回指針類型的數據,使其指向某個地址單元。

返回指針的函數,一般定義格式爲:        

類型標識符    *函數名(參數表)

如:int *f(x,y);

其中x,y是形式參數,f是函數名,調用後返回一個指向整型數據的地址指針。f(x,y)是函數,其值是指針。

如:char*ch();表示的就是一個返回字符型指針的函數,請看下面的例題:

【例】將字符串1(str1)複製到字符串2(str2),並輸出字符串2.

#include "stdio.h"

 main() //注意:這裏沒有聲明(定義)返回類型,在函數體內也沒有返回值。應該培養程序開發者良好的習慣,定義函數返回類型,如果程序執行正常,則向操作系統返回數值0,否則返回-1.

{

char*ch(char *,char *);

   char str1[]="I am glad to meet you!";    

   char str2[]="Welcome to study C!";    

   printf("%s\n",ch(str1,str2));

}

 

char *ch(char *str1,char *str2)

{   

 int i;    

char*p;    

p=str2     

if(*str2==NULL)exit(-1);    

do    

   { 

       *str2=*str1;  

       str1++; 

       str2++;

    }

while(*str1!=NULL);

*str2='\0';//注意:可以註釋這行查看代碼執行效果,分析原因。

return(p);

}

通過分析可得:

函數指針是一個指向函數的指針,而指針函數只是說明他是一個返回值爲指針的函數, 函數指針可以用來指向一個函數。

 

3 函數指針與指針函數的比較

函數指針與指針函數是兩個完全不同的概念,唯一有聯繫的地方就是叫法比較相似,實際上沒有任何關聯。

函數指針:本質上是一個指針,其類型爲函數類型,即該指針指向函數,其最根本的屬性:它就是一個變量或者常量。比如:int(*p)(int)這是一個參數爲int,返回值也是int型的函數指針。

指針函數:本質上是一個函數,返回值是指針的類型。比如:int *func(int a)就是一個指針函數,其返回值爲int型指針。

 

int *func(inta) //指針函數,其有函數體,被{}包括

{

   printf(“%d\n”,a);

   return &a;

}

 

int main()

{

   int *(*p)(int);//函數指針,就是一個變量,用法與普通變量區別不大

   p = func;//可以被賦值

   func(5);//函數的調用

  (*p)(5);//函數指針的調用到這裏應該理解爲什麼上面函數指針聲明爲“int *(*p)(int);

}

發佈了24 篇原創文章 · 獲贊 13 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章