在結構體中使用函數

//C語言技巧--在結構體中使用函數例子(定義一個指向函數的指針) .

#include <stdio.h>  
#include <malloc.h>  
#include <memory.h>  
#define DECLARATION int (*ptr)(int x,int y)  
#define DEFINITION(x,y) ptr(x,y)  
int sum(int x,int y)
{  
 printf("x:%d\n",x);
 printf("y:%d\n",y);

    return(x+y);  
}

typedef struct { 
        int r; 
    //    DECLARATION;  
  int (*ptr)(int x,int y);  
} mystr; 
void main() 

    int a,b,c; 
 
    scanf("%d,%d",&a,&b); 
     mystr stru;   
  stru.ptr=sum;  
  c=stru.ptr(a,b);  
     printf("a=%d,b=%d,sum=%d\n",a,b,c);
     
    /* mystr *stru1;   */
    /* stru1=(mystr *)malloc(sizeof(mystr));   */
    /* memset(stru1,0,sizeof(mystr));   */
    /* c=stru1->DEFINITION(a,b); */

 
  
    /* //c=stru->ptr(a,b);    */
    /* printf("a=%d,b=%d,sum=%d\n",a,b,c);   */
 /* memset(stru1,0,sizeof(mystr));   */
 /* free(stru1);  xz */
}  

保存文件到struct_fun.c

編譯:gcc -g -o struct_fun struct_fun.c

運行: ./struct_fun

 

 

2、

函數指針作爲結構體成員 - [C語言]

2011-05-05

版權聲明:轉載時請以超鏈接形式標明文章原始出處和作者信息及本聲明
http://cnmcu.blogbus.com/logs/125730496.html

       今天在看《C\C++快速進階教程》,看到一個“函數指針作爲結構體成員”的程序,功能近似C++中的類中的成員函數,用那樣的一種方法可實現定義的結構變量具有了方法的特性。

       程序如下(下面的程序運行於WinTC):

#include "stdio.h"
struct aa
{
     int a;
     int( *fun)(int,int);
};
int add(int x,int y);
main()
{
    struct aa bb;
    int cc;
    printf("%x\t",add);
    bb.a=1000;
    bb.fun=add;
    cc=bb.fun(3,5);
    printf("%d\t",cc);
    printf("%x\t",bb.fun);
    getch();
}
int add(int x,int y)
{
    return x+y;
}

       剛開始一看,覺得很茫然,是前所未見呀,很多教科書上也沒講,於是上百度搜了下,還真有怎麼回事。找到一些資料,覺得很不錯,貼出來分享一下:

++++++++++++++++++++++++++++++++++++++++++++++++++++++

       函數指針作爲結構體成員,實現函數註冊 作者:admin 日期:2010-02-04
有時我們需要將函數作爲結構體的成員,模擬C++類的情形,可應用於方法註冊。
#include

struct a
{
    void (*func)(char *);
};

void hello(char *name)
{
    printf ("hello %s\n",name);
}

int main()
{
    struct a a1;
    a1.func = hello;
    a1.func("illusion");
    system("PAUSE");
    return 0;
}

 


   #############################################################################################################
 
標 題: 
閱讀權限:公衆公開私有好友公開 
文章類型:原創 轉載 
文章關鍵詞(選填):     從已有的關鍵詞中選擇 
文章摘要(選填):查看文章摘要  struct file_operations {int (*seek) (struct inode * ,struct file *, off_t ,int);int (*read) (struct inode * ,struct file *, char ,int);int (*readdir) (struct inode * ,struct file *, struct dirent * ,int);int (*ioctl) (struct inode * ,struct file *, unsined int ,unsigned longint (*mmap) (struct inode * ,struct file *, struct vm_area_struct *);int (*fasync) (struct inode * ,struct file *,int); 確 定取 消
  
        

   文章正文:
  在C++中,我們很容易就可以實現函數重載,特別是類的同名方法(多態)。那麼,在C語言中我們可以有類似的應用嗎?
     呵呵,今天我找到了一種。
     下面先給出我的說明代碼,再做解釋:
//-----------------------------------------------------------//
#include
struct A
{
    void* (*fun)();
};
void myfun1()
{
    printf("this is fun()\n");
}
int myfun2(int a)
{
    printf("this is fun(%d)\n",a);
    return a;
}

char myfun3(int a)
{
    printf("this is fun(%c)\n",a);
    return a;
}
int main()
{
    struct A a;
    a.fun=myfun2;
    printf("AAA  %d\n",a.fun());
    printf("AAA1  %d\n",a.fun(4));
    printf("AAA2  %d\n",a.fun(43,"32423"));

    a.fun=myfun3;
    printf("AAA  %d\n",a.fun());
    printf("AAA1  %d\n",a.fun(4));
    printf("AAA2  %d\n",a.fun(43,"32423"));
    return 0;
}

//-----------------------------------------------------------//
在GCC4.0下編譯運行的結果如下:
//-----------------------------------------------------------//
hill@hill-laptop:~/Desk/temp$ gcc test4.c
test4.c: 在函數 ‘main’ 中:
test4.c:25: 警告:從不兼容的指針類型賦值
test4.c:30: 警告:從不兼容的指針類型賦值
hill@hill-laptop:~/Desk/temp$ ./a.out
this is fun(-1208768727)
AAA  -1208768727
this is fun(4)
AAA1  4
this is fun(43)
AAA2  43
this is fun(
AAA  -11
this is fun()
AAA1  4
this is fun(+)
AAA2  43
hill@hill-laptop:~/Desk/temp$
//-----------------------------------------------------------//

現在分析一下上面的代碼:
首先,這個程序的思路是想用一個結構體模擬一個類,通過函數指針來申明“類”方法,並模擬多態性。
        void* (*fun)();--------(1)
是一個函數指針,注意,這裏不要寫成
        void (*fun)();--------(2)
接下來寫了兩個函數
    void myfun1();
    int myfun2(int);
在接下來的main函數中,我們爲A實例a的fun域賦值,這裏我們直接賦值了myfun2,若上面方法申明中採用(2),那麼將不能把myfun2賦值給fun,因爲void*是可以指向任何類型的指針,那麼當然可以指向int。這裏又定義了myfun3就是爲類看看void*是否能自動的轉化爲char類型了。
    另外要說明的一點就是,調用a.fun時我實驗了幾種調用方法,如程序中所示,它對行參沒有任何要求,在本例中,由於傳入的是myfun2(int),若不加任何參數調用a.fun(),那麼輸入的int將隨機而定;若參數多於兩個,則只有第一個參數有效,其餘參數被呼略掉;若第一個參數與所傳入的函數不匹配,則雖然可以通過編譯,但結果一般會與期望的不同(錯誤)。
    那麼,它是否是多態呢?顯然不是的,多態是個運行時概念,若想在C裏面用同名函數則必須如此利用函數指針,在使用不同的重載形式前必須給函數指針賦上相應的函數纔行,在本例中,若要用重載型myfun3的話,在調用a.fun(...)前必須有這樣一行
    a.fun=myfun3;
這是因爲C畢竟還是一個靜態語言的原因。

    這種結構體與函數指針的結合使用還有很多用途,其實也可以將公用體與函數指針結合,方法一樣。這幾種結合功能相當強大。在定義接口時將非常有用。
    比如在寫一個設備驅動程序時,我們就要填寫一個數據結構file_operations,具體的定義如下:

struct file_operations {
int (*seek) (struct inode * ,struct file *, off_t ,int);
int (*read) (struct inode * ,struct file *, char ,int);
int (*write) (struct inode * ,struct file *, off_t ,int);
int (*readdir) (struct inode * ,struct file *, struct dirent * ,int);
int (*select) (struct inode * ,struct file *, int ,select_table *);
int (*ioctl) (struct inode * ,struct file *, unsined int ,unsigned long
int (*mmap) (struct inode * ,struct file *, struct vm_area_struct *);
int (*open) (struct inode * ,struct file *);
int (*release) (struct inode * ,struct file *);
int (*fsync) (struct inode * ,struct file *);
int (*fasync) (struct inode * ,struct file *,int);
int (*check_media_change) (struct inode * ,struct file *);
int (*revalidate) (dev_t dev);
}
    這個數據結構爲編程人員提供了一個訪問設備的公用接口,比如read,write等等。
具體設備驅動程序的編寫已經超出本文範圍,日後再說明。

小結:
    利用函數指針來模擬多太,討論出函數指針的一些特殊用法。以及調用函數指針的參數無關性。

 

 


#############################################################################################################
#include "stdio.h"  
struct DEMO   //遙控器實體
{  
    char x;   // 按鍵
    int (*func)(int x,int y); //函數指針    //按按鍵
};  
 
int add2(int x,int y)   //定義遙控器發送指令
{  
    return x+y;  
}  
 
int dec2(int x,int y)   //定義遙控器發送指令
{  
    return x-y;  
}  
 
struct DEMO demo[2] =   
{  
    {1,add2},       {2,dec2}  
};  
int main(void)
{  
    printf("func%d=%d\n",demo[0].x,demo[0].func(4,3));  
    printf("func%d=%d\n",demo[1].x,demo[1].func(4,3));  
    return 0;  

說明:demo[0],demo[1]可以看做兩種不同功能的遙控器實體,
demo[0].x爲獲取遙控器的固有屬性,可以是遙控器的品牌
demo[0].func(4,3)可以抽象爲同時按下4,3按鍵後遙控器的反應;

+++++++++++++++++++++++++++++++++++++++++++++++++++++

大致就是這樣。2011/05/05

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章