2010年2月17日 星期三

指標式的副程式

今天大年初四


又溼又冷的



還是到實驗室寫程式吧


 


過年前,許同學給了我2支有趣的程式


1個是指標式的副程式


1個是指標陣列的副程式


首先,先看指標式的副程式



int add(int,int);
int sub(int,int);
int multiply(int,int);
int divide(int,int);
int (*operation)(int,int);


int test;
int main(void)
{
  int x=10,y=2,output;


  operation=add;
  output=(*operation)(x,y);
  test=output;              
//test = 12


  operation=sub;
  output=(*operation)(x,y);
  test=output;             
//test = 8


  operation=multiply;
  output=(*operation)(x,y);
  test=output;             
//test = 20


  operation=divide;
  output=(*operation)(x,y);
  test=output;             
//test = 5



  return 0;   



}

int add(int a,int b)
{
 return a+b;
}


int sub(int a,int b)
{
 return a-b;
}


int multiply(int a,int b)
{
 return a*b;
}


int divide(int a,int b)
{
 return a/b;
}



說實在的,我不知道為什麼要這樣用,我覺得直接呼叫副程式就好了


不過許同學說,以後就會看到很多這樣的寫法了。


再來,指標陣列的副程式



unsigned char aa(unsigned char a);


unsigned char bb(unsigned char b);


 


unsigned char (*ns[])(unsigned char) =


{


 aa,


 bb


};


 


int test;


int main(void)


{


 


  unsigned char r;


  r=(*ns[0])(2);


  test=r;                        //test=3


  r=(*ns[1])(2);


  test=r;                        //test=4


  return 0;


}


unsigned char aa(unsigned char a)


{


  return a+1;


}


 


unsigned char bb(unsigned char b)


{


  return b+2;


}


 


說實在的,我也不知道為什麼要這樣用,我也覺得直接呼叫副程式就好了


不過許同學說,以後這樣的寫法可以在副程式裡減少switch case的判斷式。


蛤?



我也不懂


改天再問他看看到底怎麼回事好了


不過似乎C語言的世界還是有很多值得我去探索的



5 則留言:

  1. 這招哦!使用函式指標的高招。我通常是用來安插執行時的特殊函式。可以利用通信觸發需要執行的函式。拿來除錯也很好用。
    如果可以使用通信傳入機器碼,甚至可以在執行中更換程式。
    在8051上使用,為了效能,函式指標必須佔用register file空間比較好,這個是要注意的。

    [版主回覆02/18/2010 11:52:29]不知道是否有實際範例或是簡單的應用?
    謝謝

    回覆刪除
  2. 我使用在8051上做多工切換用,有使用在實際產品上。命名為8051簡單多工,但剛才發現原本在雷兒電子網上發表的文章消失了,目前重貼在我的部落格。
    8051簡單多工

    回覆刪除
  3. 這種方式,我是物件化的時候會用到。
    假設有OPEN,READ,WRITE的功能,宣告一個struct。
    typedef struct _Device
    {
        int (*open)();
        int (*write)(char data);
        int (*read)()
    }myDevice;
    透過不同的device的open,read,write函式實作,賦予不同的device有相同的行為。讓你在操作周邊(或其他資料結構),看起來有物件化的感覺。

    比如有一個UART裝置,我們已經寫好UART1_INIT()去初始化UART,
    宣告UART裝置物件  my_Device myUART;
    myUART.open()=UART1_INIT();

    範例:
    typedef struct _Device
    {
        int (*open)();
        int (*write)(char data);
        int (*read)();
        int (*close)();
    }myDevice;

    int UART1_INIT()
    {
        printf("uart1 opened!\n");
        return 0;
    }

    int UART1_READ()
    {
        return 12;
    }

    int UART1_WRITE(char data)
    {
        printf("Write function is called!\n");
        return 0;
    }

    int UART1_CLOSE()
    {
        printf("uart1-close function is not implemented!\n");
        return 0;
    }

    int main()
    {
        myDevice UART1;
        UART1.open = UART1_INIT;
        UART1.read = UART1_READ;
        UART1.write = UART1_WRITE;
        UART1.close = UART1_CLOSE;

        //TEST
        UART1.open();  //Open UART
        int result;
        result = UART1.read(); //should be 12
        printf("UART1 read value = %d\n",result);
        UART1.write('A');
        UART1.close();

        return 0;
    }

    回覆刪除
  4. 把裝置、資料結構物件化,對於後面寫單晶片程式,在面對程式碼日益肥大難以維護時,這類方式的可讀性、重用性、維護性會給你帶來很多幫助。

    回覆刪除
  5. CallBackfunction 就是常用的例子,google一下會有蠻多資料的.
     
    [版主回覆10/30/2012 21:29:56]真~的~~

    回覆刪除