Typedef函数指针?

我正在学习如何动态加载DLL,但我不明白的是这一行

typedef void (*FunctionFunc)();

我有几个问题。如果有人能回答这些问题,我会很感激。

  1. 为什么使用typedef ?
  2. 语法看起来很奇怪;在void之后不应该有函数名或其他东西吗?它看起来像一个匿名函数。
  3. 函数指针是用来存储函数的内存地址的吗?

所以我现在很困惑;你能给我解释一下吗?

542657 次浏览
  1. typedef用于别名类型;在这种情况下,你将FunctionFunc混叠到void(*)()

  2. 的确,语法看起来很奇怪,看看这个:

    typedef   void      (*FunctionFunc)  ( );
    //         ^                ^         ^
    //     return type      type name  arguments
    
  3. No, this simply tells the compiler that the FunctionFunc type will be a function pointer, it doesn't define one, like this:

    FunctionFunc x;
    void doSomething() { printf("Hello there\n"); }
    x = &doSomething;
    
    
    x(); //prints "Hello there"
    

如果没有typedef字,在c++中,声明将声明一个类型为指针的变量FunctionFunc,指向无参数的函数,返回void

对于typedef,它将FunctionFunc定义为该类型的名称。

typedef是一个将名称与类型关联起来的语言构造 使用它的方式与使用原始类型相同,例如

typedef int myinteger;
typedef char *mystring;
typedef void (*myfunc)();

像这样使用它们

myinteger i;   // is equivalent to    int i;
mystring s;    // is the same as      char *s;
myfunc f;      // compile equally as  void (*f)();

如你所见,你可以用上面给出的定义替换类型定义名称

难点在于C和c++中指向函数的指针语法和可读性,而typedef可以提高这种声明的可读性。但是,语法是合适的,因为函数与其他更简单的类型不同,它可能有一个返回值和参数,因此有时对函数指针的声明冗长而复杂。

对于指向函数数组的指针和其他一些更间接的类型,可读性可能会变得非常棘手。

来回答你的三个问题

  • 为什么使用typedef ?

    . 0 .

    . 0 .

    . 0 . 0
  • 语法看起来很奇怪(在函数声明的指针中) 这种语法读起来并不明显,至少在开始时是这样。使用typedef声明可以简化

    的读取
  • 创建一个函数指针来存储函数的内存地址? 是的,函数指针存储函数的地址。这与typedef构造无关,typedef构造只是简化程序的写入/读取;编译器只是在编译实际代码之前展开typedef定义

例子:

typedef int (*t_somefunc)(int,int);


int product(int u, int v) {
return u*v;
}


t_somefunc afunc = &product;
...
int x2 = (*afunc)(123, 456); // call product() to calculate 123*456
#include <stdio.h>
#include <math.h>


/*
To define a new type name with typedef, follow these steps:
1. Write the statement as if a variable of the desired type were being declared.
2. Where the name of the declared variable would normally appear, substitute the new type name.
3. In front of everything, place the keyword typedef.
*/


// typedef a primitive data type
typedef double distance;


// typedef struct
typedef struct{
int x;
int y;
} point;


//typedef an array
typedef point points[100];


points ps = {0}; // ps is an array of 100 point


// typedef a function
typedef distance (*distanceFun_p)(point,point) ; // TYPE_DEF distanceFun_p TO BE int (*distanceFun_p)(point,point)


// prototype a function
distance findDistance(point, point);


int main(int argc, char const *argv[])
{
// delcare a function pointer
distanceFun_p func_p;


// initialize the function pointer with a function address
func_p = findDistance;


// initialize two point variables
point p1 = {0,0} , p2 = {1,1};


// call the function through the pointer
distance d = func_p(p1,p2);


printf("the distance is %f\n", d );


return 0;
}


distance findDistance(point p1, point p2)
{
distance xdiff =  p1.x - p2.x;
distance ydiff =  p1.y - p2.y;


return sqrt( (xdiff * xdiff) + (ydiff * ydiff) );
}

如果你可以使用c++ 11,你可能想要使用std::functionusing关键字。

using FunctionFunc = std::function<void(int arg1, std::string arg2)>;

对于语法的一般情况,您可以查看ANSI C标准的附录A

在这里的Backus-Naur表单中,您可以看到typedef的类型是storage-class-specifier

declaration-specifiers类型中,您可以看到您可以混合许多说明符类型,它们的顺序无关紧要。

例如,正确的说法是,

long typedef long a;

将类型a定义为long long的别名。因此,要了解详细使用的类型定义,您需要参考一些定义语法的backus-naur形式(有许多正确的ANSI C语法,而不仅仅是ISO语法)。

当您使用typedef定义函数类型的别名时,您需要将别名放在与函数标识符相同的位置。在本例中,您将类型FunctionFunc定义为一个函数指针的别名,该函数在调用时禁用类型检查,并且不返回任何内容。