簡體   English   中英

了解如何使用帶有指針作為參數的 typedef void 函數

[英]Understanding how to use typedef void function with pointers as params

我試圖理解用 C 編寫的固件,它驅動超寬帶連接的芯片。

固件大量使用typedef和指針。 我已經理解了固件背后的大部分想法,但是有一個我無法理解的typedef void函數。

基本上,固件創建了一個結構來保存設備數據

typedef struct
{
   //some data
   dwt_cb_t    cbTxDone; // Callback for TX confirmation event
   //some other data
} dwt_local_data_t ;

我知道該結構名為dwt_local_data_t並包含一些變量,包括這種奇怪的dwt_cb_t類型。

在 .h 文件中dwt_cb_t被命名為

// Call-back type for all events    
typedef void (*dwt_cb_t)(const dwt_cb_data_t *);

其中dwt_cb_data_t是另一種形式的結構

typedef struct
{
    uint32 status;      //initial value of register as ISR is entered
    uint16 datalength;  //length of frame
    uint8  fctrl[2];    //frame control bytes
    uint8  rx_flags;    //RX frame flags, see above
} dwt_cb_data_t;

現在,我試圖理解typedef void (*dwt_cb_t)(const dwt_cb_data_t *);

據我所知, typedef void是一個指向函數的類型。 它定義了一個變量dwt_cb_t指向一個函數,該函數接收一個常量結構dwt_cb_data_t作為輸入

我不知道我的推理是否正確,因為我不明白為什么dwt_cb_data_t末尾有一個*間隔。 是不是表示函數的輸入是結構體的指針? 這種情況下為什么不寫typedef void (*dwt_cb_t)(const *dwt_cb_data_t); 反而?

不要再考慮typedef void 您正在以這種方式截斷定義。

定義的符號是dwt_cb_t並且是void (*)(const dwt_cb_data_t *)類型的別名,它是:指向采用const dwt_cb_data_t *參數並返回void函數的指針。

在 C++ 中,你會寫:

using dwt_cb_t = void (*)(const dwt_cb_data_t *);

這是非常清楚的。

為了更清楚,讓我們假設有一個函數聲明如下

void f( int *x );

函數的類型是void( int * )

您可以為此函數類型引入別名,例如

typedef void Func( int * );

並使用別名聲明(但不定義)函數

這是一個演示程序。

#include <stdio.h>

typedef void Func( int * );

Func f;

int main(void) 
{
    int x = 0;
    
    printf( "x = %d\n", x );
    
    f( &x );

    printf( "x = %d\n", x );
    
    return 0;
}

void f( int *x )
{
    ++*x;
}

程序輸出是

x = 0
x = 1

請注意,您還可以通過以下方式聲明函數別名

void typedef Func( int * );

現在讓我們為指向函數類型的函數指針聲明一個別名。

你可以簡單地寫

typedef void Func( int * );

typedef Func *FuncPtr;

這是一個演示程序。

#include <stdio.h>

typedef void Func( int * );

Func f;

typedef Func *FuncPtr;

int main(void) 
{
    int x = 0;
    
    printf( "x = %d\n", x );
    
    FuncPtr fp = f;

    fp( &x );

    printf( "x = %d\n", x );
    
    return 0;
}

void f( int *x )
{
    ++*x;
}

另一方面,您可以為指向函數類型的指針聲明別名,而不使用函數類型的別名。

#include <stdio.h>

typedef void Func( int * );

Func f;

typedef void ( *FuncPtr )( int * );

int main(void) 
{
    int x = 0;
    
    printf( "x = %d\n", x );
    
    FuncPtr fp = f;

    fp( &x );

    printf( "x = %d\n", x );
    
    return 0;
}

void f( int *x )
{
    ++*x;
}

現在比較這些別名聲明

typedef void ( *FuncPtr )( int * );
typedef void (*dwt_cb_t)(const dwt_cb_data_t *);

唯一的區別是參數的類型。 在第一個聲明中,參數的類型是int *而在第二個聲明中,參數的類型是const dwt_cb_data_t *

在 C++ 和 typedef(s) 中,您可以使用 using 聲明,例如

using dwt_cb_t = void (*)(const dwt_cb_data_t *);

在 C++ 中使用別名聲明更加靈活,因為您可以使用模板別名聲明。

這是一個演示程序。

#include <iostream>

template <typename T>
using FuncPtr = void ( * )( T * );

template <typename T>
void f( T *t )
{
    ++*t;
}

int main() 
{
    FuncPtr<int>  fp1 = f;
    FuncPtr<char> fp2 = f;
    
    int x = 0;
    char c = 'A';
    
    fp1( &x );
    fp2( &c );
    
    std::cout << "x = " << x << '\n';
    std::cout << "c = " << c << '\n';
    
    return 0;
}

程序輸出是

x = 1
c = B

是不是表示函數的輸入是結構體的指針?

是的,它表明函數的參數是指向結構的指針。

在這種情況下,為什么不寫

typedef void (*dwt_cb_t)(const*dwt_cb_data_t);

反而?

這是因為指針符號*必須放在標識符之前,而不是標識符的類型之前。 在這種情況下,您可以看到函數如下:

typedef void (*dwt_cb_t)(const dwt_cb_data_t *var);

唯一的事情是省略了var

現在,我試圖理解typedef void (*dwt_cb_t)(const dwt_cb_data_t *);

typedef void (*dwt_cb_t)(const dwt_cb_data_t *);

意味着,定義一個dwt_cb_t類型,它是一個指向函數的指針,該函數返回void並接受一個const dwt_cb_data_t *類型的參數。

如果你有一個功能,比如

 void func(const dwt_cb_data_t * data); // func accepts argument type 
                                           const dwt_cb_data_t * , returns void 

你可以寫

 dwt_cb_t f = func;
typedef void (*dwt_cb_t)(const dwt_cb_data_t *);

這只是意味着dwt_cb_data_t是一種數據類型,而dwt_cb_data_t *只不過是一個指向它的指針。

函數原型只是缺少它的形式參數名稱,這很好。 降級版本將是:

int myFunc(int, char*);  // no formal parameter name, just its datatype

然后,在它的實現中,你會看到

int myFunc(int var1, char* var_ptr){
//function body 
}

沒有參數名稱更容易閱讀。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM