結構體與函數指針


結構體指針變量的定義

定義結構體變量的一般形式如下:
形式1:先定義結構體類型,再定義變量
struct 結構體標識符
{
  成員變量列表;…
};
struct 結構體標識符 *指針變量名;
變量初始化:struct 結構體標識符 變量名={初始化值1,初始化值2,…,初始化值n };

形式2:在定義類型的同時定義變量
struct 結構體標識符
{
  成員變量列表;…
} *指針變量名;

形式3:直接定義變量,用無名結構體直接定義變量只能一次
struct
{
  成員變量列表;…
}*指針變量名;

其中“指針變量名”為結構體指針變量的名稱。形式1是先定義結構體,然后再定義此類型的結構體指針變量;形式2和形式3是在定義結構體的同時定義此類型的結構體指針變量。

函數指針的定義
一般的函數指針可以這么定義:
  int (*func)(int,int);
表示一個指向含有兩個int參數並且返回值是int形式的任何一個函數指針. 假如存在這樣的一個函數:
int add2(int x,int y)
{
  return x+y;
}
那么在實際使用指針func時可以這樣實現:
func=&add2;  //指針賦值,或者func=add2; add2與&add2意義相同
printf("func(3,4)=%d\n",func(3,4));

事實上,為了代碼的移植考慮,一般使用typedef定義函數指針類型.
typedef int (*FUN)(int,int); //參考下面

/* typedef int (*funcptr)(); 這個的意思是:定義一個返回值為int,不帶參數的函數指針,
就是說funcptr 是 int (*)()型的指針
funcptr table[10]; 
定義一個數組,這個數組是funcptr類型的。就是說這個數組內的內容是一個指針,這個指針指向一個返回值為int,不帶參數的函數 */
FUN func=&add2;
func();

結構體中包含函數指針
其實在結構體中,也可以像一般變量一樣,包含函數指針變量.下面是一種簡單的實現.

復制代碼
復制代碼
#include <stdio.h>
struct DEMO  
{  
    int x,y;  
    int (*func)(int,int); //函數指針  
};  
  
int add1(int x,int y)  
{  
    return x*y;  
}  

int add2(int x,int y)  
{  
    return x+y;  
}  

void main()  
{  
    struct DEMO demo;  
    demo.func=add2; //結構體函數指針賦值  
    //demo.func=&add2; //結構體函數指針賦值  
    printf("func(3,4)=%d\n",demo.func(3,4));  
    demo.func=add1;  
    printf("func(3,4)=%d\n",demo.func(3,4));  
}
執行后終端顯示:
func(3,4)=7 
func(3,4)=12
復制代碼
復制代碼

結構體中指向函數的指針

C語言中的struct是最接近類的概念,但是在C語言的struct中只有成員,不能有函數,但是可以有指向函數的指針,這也就方便了我們使用函數了。舉個例子,如下:

復制代碼
復制代碼
#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
      
typedef struct student  
{  
    int id;  
    char name[50];   
    void (*initial)();  
    void (*process)(int id, char *name);  
    void (*destroy)();  
}stu;  
      
void initial()  
{  
    printf("initialization...\n");  
}  
      
void process(int id, char *name)  
{  
    printf("process...\n%d\t%s\n",id, name);  
}  
     
void destroy()  
{  
    printf("destroy...\n");  
}  
      
int main()  
{  
    stu *stu1;  
    //在VC和TC下沒有malloc也可以正常運行,但是linux gcc下就會出錯,為段錯誤,必須使用malloc  
    stu1=(stu *)malloc(sizeof(stu));  
    //使用的時候必須要先初始化  
    stu1->id=1000;  
    strcpy(stu1->name,"C++");  
    stu1->initial=initial;  
    stu1->process=process;  
    stu1->destroy=destroy;  
    printf("%d\t%s\n",stu1->id,stu1->name);  
    stu1->initial();  
    stu1->process(stu1->id, stu1->name);  
    stu1->destroy();  
    free(stu1);  
    return 0;  
}
終端顯示:
1000    C++
initialization...
process...
1000    C++
destroy..
復制代碼
復制代碼

c語言中,如何在結構體中實現函數的功能?把結構體做成和類相似,讓他的內部有屬性,也有方法,
這樣的結構體一般稱為協議類,提供參考: 
struct { 
  int funcid; 
  char *funcname; 
  int (*funcint)();   /* 函數指針 int 類型*/ 
  void (*funcvoid)();  /* 函數指針 void類型*/ 
}; 
每次都需要初始化,比較麻煩

復制代碼
復制代碼
#include <stdio.h>  
      
typedef struct  
{  
    int a;  
    void (*pshow)(int);  
}TMP;  
      
void func(TMP *tmp)  
{  
    if(tmp->a >10)//如果a>10,則執行回調函數。  
    {  
        (tmp->pshow)(tmp->a);  
    }  
}  
      
void show(int a)  
{  
    printf("a的值是%d\n",a);  
}  
      
void main()  
{
    TMP test;  
    test.a = 11;  
    test.pshow = show;  
    func(&test);  
}  
終端顯示:
a的值是11 /*一般回調函數的用法為: 甲方進行結構體的定義(成員中包括回調函數的指針) 乙方定義結構體變量,並向甲方注冊, 甲方收集N個乙方的注冊形成結構體鏈表,在某個特定時刻遍歷鏈表,進行回調。 當函數指針做為函數的參數,傳遞給一個被調用函數, 被調用函數就可以通過這個指針調用外部的函數,這就形成了回調<p>一般的程序中回調函數作用不是非常明顯,可以不使用這種形式</p><p>最主要的
用途就是當函數不處在同一個文件當中,比如動態庫,要調用其他程序中的函數就只有采用回調的形式,通過函數指針參數將外部函數地址傳入來實現調
用</p><p>函數的代碼作了修改,也不必改動庫的代碼,就可以正常實現調用便於程序的維護和升級</p>*/
出處:https://www.cnblogs.com/lvjunjie/p/8961731.html


免責聲明!

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



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