Typedef函数指针?

时间:2010-11-28 04:50:25

标签: c++ c pointers typedef

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

typedef void (*FunctionFunc)();

我有几个问题。如果有人能够回答他们,我将不胜感激。

  1. 为什么使用typedef
  2. 语法看起来很奇怪;在void后应该没有函数名称或什么?它看起来像一个匿名函数。
  3. 是否创建了一个函数指针来存储函数的内存地址?
  4. 所以我此刻感到困惑;你能为我澄清一下吗?

6 个答案:

答案 0 :(得分:422)

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)();

如您所见,您只需将 typedefed 名称替换为上面给出的定义。

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

对于函数数组的指针,以及其他一些更间接的风格,可读性可能开始变得非常棘手。

回答你的三个问题

  • 为什么要使用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

答案 1 :(得分:173)

  1. typedef用于别名类型;在这种情况下,您将FunctionFunc别名为void(*)()

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

    typedef   void      (*FunctionFunc)  ( );
    //         ^                ^         ^
    //     return type      type name  arguments
    
  3. 不,这只是告诉编译器FunctionFunc类型将是一个函数指针,它不会定义一个,如下所示:

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

答案 2 :(得分:30)

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

使用typedef代替FunctionFunc作为该类型的名称。

答案 3 :(得分:7)

如果您可以使用C ++ 11,则可能需要使用std::functionusing关键字。

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

答案 4 :(得分:1)

#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) );
}

答案 5 :(得分:1)

对于语法的一般情况,您可以查看annex A of the ANSI C standard

从那里的Backus-Naur表单中,您可以看到2019-05-07 13: 40: 31.103 123 aaa 456 bbb 2019-05-08 13: 40: 31.103 123 yyy 456 zzz 的类型为typedef

在类型storage-class-specifier中,您可以看到可以混合许多说明符类型,其顺序无关紧要。

例如,正确地说,

declaration-specifiers

定义类型long typedef long a; 作为a的别名。因此,要了解穷举用法的typedef,您需要查阅一些定义语法的backus-naur形式(ANSI C有很多正确的语法,而不仅仅是ISO的语法)。

使用typedef定义函数类型的别名时,需要将别名放在放置函数标识符的位置。在您的情况下,您将类型long long定义为指向该函数的指针的别名,该函数的类型检查在调用时被禁用并且不返回任何内容。