指針解析(三)(原)


    不知不覺,指針解析來到了第三篇。本篇想講的內容是有點高級,也有晦澀。說到高級和晦澀,有些人就不同意了。不就些基礎內容嘛,何必用高級一次呢?我想我是假借高級一詞,重點在“有點”。我倒不能說有點猥瑣,有點惡心吧。吐舌鬼臉

    我們都知道,程序中的每個函數都位於內存的某個位置上,所以就存在指向那個位置上的指針。知道了這個道理之后呢,我們來看看以下這些聲明是怎么一回事?

int f;        // 整型變量,這個鬼都知道
int *f;    // 一個指向整型的指針,這個鬼也知道
 
int f();    // 返回類型為整型的函數
int *f();    // 返回類型為一個指向整型指針的函數
 
// 以上都很平常,都是正常情況
 
int (*f)();    // 這是神馬?.....這是函數指針,一個返回類型為整型的,不接受輸入參數的函數指針
int *(*f)();    // 這個也是函數指針,一個返回類型為指向整型指針的,不接受輸入參數的函數指針
 
int (*f[])();  // 這個有點暈!這是一個數組,其元素是函數指針
int *(*f[])(); // 這也是一個數組,其元素也是函數指針,只是返回類型和上面不一樣

    指針真是強大,傷不起破碎的心

    看過上面的聲明之后,我們可以進入函數指針的世界了。現在展示一個函數指針最基本的調用:

#include <stdio.h>
 
void MyFun(int );    // 要調用的函數聲明
 
void (*FunP)(int );    // 聲明的函數指針,接受一個int類型的參數,返回值為空的函數指針
 
int main(int argc, char* argv[])
{
    MyFun(1);        // 這里將直接調用MyFun函數
 
    FunP = &MyFun;    // 將MyFun函數的地址賦給FunP,其實,FunP = MyFun,也可以,好玩吧。
 
    (*FunP)(2);        // 這里通過函數指針FunP”變量“來調用MyFun函數,注意變量兩字啊。
    FunP(3);        // 你可以這樣調用
}
 
void MyFun(int x) 
{
    printf("%d\n",x);
}

    最近我發覺,有些東西還是直接貼代碼好。不然真不知道怎么表達尷尬?囧啊!以上的調用過程顯示了函數指針的奧妙啊。基於上面的思路,我們在進行拓展太陽。我們都知道typedef這個參數,其作用是聲明自定義數據類型,配合各種原有數據類型來達到簡化編程的目的的類型定義關鍵字。例如:

typedef char data_type;

    這個可幫了大忙了。我修改數據類型之類的,都可以灰常快速的進行。那時牽一發而動全身啊惡魔!當然,我現在不說它神馬牽一發而動全身的問題。我想讓大家看懂下面這個問題:

 typedef int (*Pfun) (const char *, const char *);    // 這個看起來有點暈吧!

    施主莫暈!吐舌鬼臉這樣只是定義一個函數指針類型,莫怕莫怕!這個聲明引入了 Pfun 類型作為函數指針的同義字,該函數有兩個 const char * 類型的參數以及一個 int 類型的返回值。當你適應了這個之后,我想介紹回調函數了。神馬是回調函數?用戶把一個函數指針做為一個參數傳遞給其他函數,后者將“回調”用戶的函數。尼瑪,這個解釋夠拗口的!直白點就是說與指針函數一致的函數可以通過這個回調動作,讓其他函數使用!這個還是有點拗口!書呆子看了下面這個例子就會好多:

#include <stdio.h>
 
int CompareImpl(void const *a, void const *b );            // 要調用的函數聲明
 
typedef int (*Compare) (void const *, void const *);    // 聲明的函數指針,接受一個void類型的指針參數,返回值為整型的函數指針
 
int Equal(int , int , Compare);                            // 回調函數的入口是Compare,至於怎么Compare那就要看傳入的函數是如何了。
 
int main(int argc, char* argv[])
{
    printf("結果為:%d\n", Equal(1, 2, CompareImpl));        // 這里我們傳入了CompareImpl,說明在*這個地方時調用CompareImpl函數來進行比較
    return 0;
}
 
int CompareImpl(void const *a, void const *b )
{
    if (*(int *)a == *(int *)b)        // 這里很好玩,我們將void指針轉換成int類型。這個函數就被我們改照成了接受
    {
        return 1;
    } 
    else
    {
        return 0;
    }
}
 
int Equal(int a, int b, Compare compare)
{
    return compare(&a, &b);                                // *
}

    以上的例子應該是最淺顯的回調解釋了太陽。如果還是不明白,去翻翻書和放狗出去查查相關的資料了吐舌笑臉。以上的compare讓大家想起神馬呢?我想說,這讓我想起了模板!用void指針和函數指針來模擬模板的一些初級功能!

    接下來要說的是轉移表,這個號稱是switch/case殺手!到底怎么殺呢?看看一下的代碼對比就知道了:

switch ()
{
case A:
    func1(1, 2);
    break;
case B:
    func2(1, 2);
    break;
case C:
    func3(1, 2);
    break;
case D:
    func4(1, 2);
    break;
 
default:
    break;
}
// 納尼,這么長!!
// 現在你可以用這樣來代替
 
void func1(double, double);
void func2(double, double);
void func3(double, double);
void func4(double, double);
 
void (*pfunc[])(double, double) = 
{func1, func2, func3, func4    };
 
// 調用的時候
pfunc[1](1,2);    // 調用的是func2(1, 2)

    明眼人就看出來了,這是函數指針數組的應用了太陽

    結了,就說到這里吧星星!睡覺了。。。。。沉睡的彎月

 

參考文獻

1. 《C語言程序設計》

2. 《C和指針》

3. 《C專家編程》

4. 百度百科的typdef的解釋。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM