<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    so true

    心懷未來,開創未來!
    隨筆 - 160, 文章 - 0, 評論 - 40, 引用 - 0
    數據加載中……

    有關指針方面的一些問題!

    首先要說明的是,在C語言中,()、[]運算符的優先級別要高于*指針運算符。
    因此,下面基于運算符優先級來討論一下C語言中指針用法里很容易混淆的幾種情況:
    int *p;//p為指向整型數據的指針變量
    int *p[4];//p為一個指針數組,里面有4個元素,每個元素都是一個指向整型變量的指針。因為[]運算符的優先級別高,因此p首先與[4]結合,也就是說p是一個數組名,接下來再看該數組中的元素究竟是什么,從前面的int *可以看出數組中的元素是指向整型變量的指針。
    int (*p)[4];//p是一個指針,它指向的是一個含有4個整型元素的數組。因為()運算符優先級別高,因此p先與*結合,這樣就確定了p肯定是一個指針,接下來的工作就是看看究竟p這個指針指向什么,拋開(*p)不看,假如是int a[4]的話,那大家都會知道這個數組a是一個包含4個整型變量元素的一維數組,因此指針p就是指向這樣一個數組——包含4個整型元素的數組。
    int *p();//p是一個函數名稱,該函數沒有任何參數,該函數返回一個指針,該指針指向一個整型變量。同樣,先從優先級來分析,因為()的優先級別高,因此p首先與()結合成p(),因此p就是一個函數名字,接下來再看該函數的一些特性,比如參數以及返回值之類的東西。
    int (*p)();//p是一個指針,該指針指向一個函數,該函數沒有參數,且返回一個整型變量。利用優先級來分析,p先與*結合,因此就能夠首先確定出p是一個指針了,下面再看該指針指向什么東西,就像分析int (*p)[4]一樣,拋開(*p)不看,如果是int fun()的話,就能夠知道這是一個不帶參數且返回整型變量的函數,因此指針p就是指向這樣一個函數。
    好了,有了上面的分析,相信大家對指針里這幾個比較容易混淆的用法必然很清楚了,當然在指針的使用中還有指向指針的指針,比如int **p;以及指向多維數組的多重指針,但是相信有了以上基礎之后,只要認真分析,肯定就能把問題迎刃而解了吧?
    下面就來看一個稍微復雜些的指針方面的應用:
    int (*p(char op))(int, int);
    不知道大家是否可以看懂上面這一行中定義的東西,你能告訴我p是什么嗎?呵呵,我先把謎底給大家,讓大家一睹為快,p是一個函數名字。下面就來分析一下:
    根據優先級來看p會首先與(char op)結合,因此p必定是一個函數名字,由p來表征的這個函數只含有一個字符型的參數op,并且該函數返回一個指針,如果是
    int *p(char op)的話,大家都會很清楚的知道該函數會返回一個指針,且該指針會指向一個整型變量,但是對于int (*p(char op))(int, int);而言,p表征的這個函數肯定會返回一個指針,那么該指針到底會指向什么東西呢?呵呵,如果給你int (指針哈哈)(int,int),你肯定也會知道“指針哈哈”是指向一個函數的,該函數還有兩個整型參數,且返回一個整型值,那么好了,知道了這一點就應該能夠知道這里的p表示的真正含義了吧:p為一個函數名字,該函數帶有一個char型參數,且返回一個指向函數的指針,該指針指向的函數包含兩個整型參數、返回一個整型變量。哈哈,看懂沒?
    通常情況下,如果遇到類似問題時,我們不會把問題一次性搞得如此復雜,而是會拆解開來,一般都是先用typedef定義一個指向函數的指針,再用它定義好的這個東東去再定義一個函數,這個函數的返回值就是我們用typedef定義的那個東東喲,呵呵,請看下面的示例:
     
    // 定義指向這類函數的指針
    typedef int (*FP_CALC)(int, int);
    FP_CALC s_calc_func(char op);//聲明一個函數
    其實,上面的兩行就相當于下面的這一行啊:
    int (*s_calc_func(char op))(int, int);//完成同樣的功能——聲明一個函數
    但是如果我們不是來聲明一個函數,而是來定義一個指向函數的指針變量時,
    如果不用typedef的方式,那么將會是如下的樣子:
    int (*s_fp)(int, int);
    這多少讓大家不太容易接受,因為我們熟知并常見的定義變量的方式是:類型 變量名,如int a;
    而上面這種方式定義變量,看似有點像函數聲明了,呵呵,因此在使用到指向函數的指針時,通常都先采用typedef的方法來聲明一個指向函數的指針,然后就可以用“類型 變量名”這種方式來定義了:
    typedef int (*FP_CALC)(int, int);
    FP_CALC s_fp;//這多好看呀,看得舒服吧?

    下面再給出一個完整的引用,有興趣的讀者可以仔細研究研究,真的很有趣味:
    -----------------------------------------------------------------------------------
    typedef的使用中,最麻煩的是指向函數的指針,如果沒有下面的函數,你知道下面這個表達式的定義以及如何使用它嗎?
     
    int (*s_calc_func(char op))(int, int);
     
    如果不知道,請看下面的程序,里面有比較詳細的說明

    // 定義四個函數
    int add(int, int);
    int sub(int, int);
    int mul(int, int);
    int div(int, int);
    // 定義指向這類函數的指針
    typedef int (*FP_CALC)(int, int);
     
    // 我先不介紹,大家能看懂下一行的內容嗎?
    int (*s_calc_func(char op))(int, int);
     
    // 下一行的內容與上一行完全相同,
    // 定義一個函數calc_func,它根據操作字符 op 返回指向相應的計算函數的指針
    FP_CALC calc_func(char op);
     
    // 根據 op 返回相應的計算結果值
    int calc(int a, int b, char op);
     
    int add(int a, int b)
    {
        return a + b;
    }
    int sub(int a, int b)
    {
        return a - b;
    }
    int mul(int a, int b)
    {
        return a * b;
    }
    int div(int a, int b)
    {
        return b? a/b : -1;
    }
    // 這個函數的用途與下一個函數作業和調用方式的完全相同,
    // 參數為op,而不是最后的兩個整形
    int (*s_calc_func(char op)) (int, int)
    {
        return calc_func(op);
    }
     
    FP_CALC calc_func(char op)
    {
        switch (op)
        {
        case '+': return add;
        case '-': return sub;
        case '*': return mul;
        case '/': return div;
        default:
            return NULL;
        }
        return NULL;
    }
     
    int calc(int a, int b, char op)
    {
        FP_CALC fp = calc_func(op); // 下面是類似的直接定義指向函數指針變量
           // 下面這行是不用typedef,來實現指向函數的指針的例子,麻煩!
            int (*s_fp)(int, int) = s_calc_func(op);
            // ASSERT(fp == s_fp);  // 可以斷言這倆是相等的
        if (fp) return fp(a, b);
        else return -1;
    }
     
    void test_fun()
    {
        int a = 100, b = 20;
        printf("calc(%d, %d, %c) = %d\n", a, b, '+', calc(a, b, '+'));
        printf("calc(%d, %d, %c) = %d\n", a, b, '-', calc(a, b, '-'));
        printf("calc(%d, %d, %c) = %d\n", a, b, '*', calc(a, b, '*'));
        printf("calc(%d, %d, %c) = %d\n", a, b, '/', calc(a, b, '/'));
    }
     
    運行結果
       calc(100, 20, +) = 120
       calc(100, 20, -) = 80
       calc(100, 20, *) = 2000
       calc(100, 20, /) = 5

    posted on 2007-12-20 23:47 so true 閱讀(161) 評論(0)  編輯  收藏 所屬分類: C&C++

    主站蜘蛛池模板: 亚洲精品在线不卡| 亚洲国产成人精品久久久国产成人一区二区三区综 | 国产性爱在线观看亚洲黄色一级片 | 亚洲网站在线免费观看| 两个人看的www高清免费视频| 91成人在线免费视频| 24小时日本在线www免费的| 亚洲人妻av伦理| fc2成年免费共享视频18| 日韩av无码成人无码免费| 亚洲一区二区三区免费在线观看| 97视频免费观看2区| 亚洲中文久久精品无码1| 亚洲精品免费网站| 亚洲乱码中文字幕综合| 亚洲成a人片在线观看无码| 亚洲Av永久无码精品黑人 | 久久99久久成人免费播放| 久久精品网站免费观看 | EEUSS影院WWW在线观看免费| 亚洲熟妇无码另类久久久| 少妇人妻偷人精品免费视频| 亚洲免费福利视频| 国产午夜无码视频免费网站| 久久久久久亚洲精品成人| v片免费在线观看| 亚洲中文字幕无码久久精品1| 免费黄色电影在线观看| 国产成人综合亚洲AV第一页 | 波多野结衣中文字幕免费视频| 亚洲人成亚洲人成在线观看 | 日本免费观看网站| 久久精品无码专区免费| 久久亚洲国产精品成人AV秋霞| 成人免费a级毛片| a免费毛片在线播放| 亚洲一欧洲中文字幕在线| 亚洲AV成人精品日韩一区18p| 亚洲国产aⅴ成人精品无吗| 午夜免费福利在线| 亚洲AV成人一区二区三区在线看|