天天看點

c語言指針函數和函數指針整理

一、 函數指針

格式如下: 類型說明符 (*函數名)(參數)

說明:

(1)其實這裡不能稱為函數名,應該叫做指針的變量名。

(2)首先它是一個指針,隻是這個指針指向的是一個函數。指針變量可以指向變量的位址、數組、字元串、動态配置設定位址,同時也可指向一個函數,每個函數在編譯的時候,系統會配置設定給該函數一個入口位址,函數名表示這個入口位址,那麼指向函數的指針變量稱為函數指針變量。

(3)備注: 指針名和指針運算符外面的括号改變了預設的運算符優先級。如果沒有圓括号,就變成了一個傳回整型指針的函數的原型聲明。

例子:

int (*select) (struct inode * ,struct file *, int ,select_table *);

int (*ioctl) (struct inode * ,struct file *, unsinedint ,unsigned long);

int (*mmap) (struct inode * ,struct file *, structvm_area_struct *);

***注意int(*read)是加上括号的。

二、指針函數

 格式:類型說明符 * 函數名(參數)

說明:

(1)由于傳回的是一個位址,是以類型說明符一般都是int。

(2)首先它是一個函數,隻不過這個函數的傳回值是一個位址值。函數傳回值必須用同類型的指針變量來接受,也就是說,指針函數一定有函數傳回值,而且,在主調函數中,函數傳回值必須賦給同類型的指針變量。

例子:

float *fun();

float *p;

p = fun(a);

***注意指針函數與函數指針表示方法的不同,千萬不要混淆。最簡單的辨識方式就是看函數名前面的指針*号有沒有被括号()包含,如果被包含就是函數指針,反之則是指針函數。

代碼:

int *f(int a, int b); // 聲明指針函數  

int *f(int a, int b) {  

   int *p = (int *)malloc(sizeof(int));  /*建立(動态申請)一塊記憶體空間,建立的記憶體空間為一個整型變量的長度,并把建立的空間位址轉化成指向整型的指針指派給前面的整型指針變量p*/      

   printf("The memeory address of p = 0x%x \n", p);  

   memset(p, 0, sizeof(int));  /*把第0到第sizeof(int)個位元組全替換為p類型 */      

   *p = a + b;  

    printf("*p = %d \n", *p);  

    return p;  //傳回指針

}  

推薦參考部落格網址:

http://blog.csdn.net/ameyume/article/details/8220832

三、指針的指針

指針的指針看上去有些令人費解。它們的聲明有兩個星号。

例子:char ** cp;

如果有三個星号,那就是指針的指針的指針,四個星号就是指針的指針的指針的指針,依次類推。當你熟悉了簡單的例子以後,就可以應付複雜的情況了。當然,實際程式中,一般也隻用到二級指針,三個星号不常見,更别說四個星号了。

    指針的指針需要用到指針的位址。

        char c='A';

        char*p=&c;

        char**cp=&p;

    通過指針的指針,不僅可以通路它指向的指針,還可以通路它指向的指針所指向的資料。下面就是幾個這樣的例子:

        char *p1=*cp;

        char c1=**cp;

        voidFindCredit(int **);

        main()

        {

           int vals[]={7,6,5,-4,3,2,1,0};

           int *fp=vals;

           FindCredit(&fp);

           printf(%d\n,*fp);

        }

        voidFindCredit(int ** fpp)

        {

           while(**fpp!=0)

           if(**fpp<0) break;

           else (*fpp)++;

        }

    首先用一個數組的位址初始化指針fp,然後把該指針的位址作為實參傳遞給函數FindCredit()。FindCredit()函數通過表達式**fpp間接地得到數組中的資料。為周遊數組以找到一個負值,FindCredit()函數進行自增運算的對象是調用者的指向數組的指針,而不是它自己的指向調用者指針的指針。語句(*fpp)++就是對形參指針指向的指針進行自增運算的。但是因為*運算符高于++運算符,是以圓括号在這裡是必須的,如果沒有圓括号,那麼++運算符将作用于二重指針fpp上。

四、指向指針數組的指針

    指針的指針另一用法舊處理指針數組。有些程式員喜歡用指針數組來代替多元數組,一個常見的用法就是處理字元串。

        char *Names[]=

        {

            Bill,

            Sam,

            Jim,

            Paul,

            Charles,

        };

        main()

        {

           char **nm=Names;

           while(*nm!=0) printf(%s\n,*nm++);

        }

    先用字元型指針數組Names的位址來初始化指針nm。每次printf()的調用都首先傳遞指針nm指向的字元型指針,然後對nm進行自增運算使其指向數組的下一個元素(還是指針)。注意完成上述認為的文法為*nm++,它首先取得指針指向的内容,然後使指針自增。

    注意數組中的最後一個元素被初始化為0,while循環以次來判斷是否到了數組末尾。具有零值的指針常常被用做循環數組的終止符。程式員稱零值指針為空指針(NULL)。采用空指針作為終止符,在樹種增删元素時,就不必改動周遊數組的代碼,因為此時數組仍然以空指針作為結束。

繼續閱讀