Typedef函数指针?

Jac*_*vin 428 c c++ pointers typedef

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

typedef void (*FunctionFunc)();
Run Code Online (Sandbox Code Playgroud)

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

  1. 为什么typedef用?
  2. 语法看起来很奇怪; 之后void应该有不是一个函数名还是什么?它看起来像一个匿名函数.
  3. 是否创建了一个函数指针来存储函数的内存地址?

所以我此刻很困惑; 你能为我澄清一下吗?

Rin*_*g Ø 438

typedef是一种将名称与类型相关联的语言结构.
例如,您可以像使用原始类型一样使用它

  typedef int myinteger;
  typedef char *mystring;
  typedef void (*myfunc)();
Run Code Online (Sandbox Code Playgroud)

使用它们就像

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

如您所见,您可以使用上面给出的定义替换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
Run Code Online (Sandbox Code Playgroud)

  • 我想我只是对排序感到困惑.使用typedef`int(*func)(int)`,我理解func是一个别名,只是有点混乱,因为别名与类型纠缠在一起.以`typedef int INT`为例,如果typedef函数指针的形式为`typedef int(*function)(int)FUNC_1`,我会更容易.这样我就可以在两个单独的标记中看到类型和别名,而不是将其网格化为一个. (10认同)
  • 在最后一个例子中,不仅仅是'square'引用相同的东西,即指向函数的指针而不是使用&square. (6认同)
  • @ user814628:目前还不清楚你在问什么.使用`typedef int newname`,您将`newname`变为`int`的别名.使用`typedef int(*func)(int)`,你将`func`变成`int(*)(int)`的别名 - 一个指向函数的指针,它接受一个`int`参数并返回一个`int`值. (6认同)
  • 问题,在你的第一个typedef例子中,你有`typedef type alias`形式,但是函数指针只有两个参数,`typedef type`.别名是否默认为类型参数中指定的名称? (2认同)
  • @pranavk:是的,`square`和`&square`(实际上,`*square`和`**square`)都引用相同的函数指针. (2认同)
  • 关于"是否创建了一个函数指针来存储函数的内存地址?是的",**不**,不在此代码中.另外,声明`typedef`引入的名称是"关键字"是不正确的.关于评估"语法是否合适",C和C++语言创建者都不同意,称其为失败的实验. (2认同)

Jac*_*kin 179

  1. typedef用于别名类型; 在这种情况下,你混叠FunctionFuncvoid(*)().

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

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

    FunctionFunc x;
    void doSomething() { printf("Hello there\n"); }
    x = &doSomething;
    
    x(); //prints "Hello there"
    
    Run Code Online (Sandbox Code Playgroud)

  • `typedef`确实*不*声明一个新类型.你可以有许多`typedef`定义的相同类型的名称,它们*不*不同(例如wrt.函数重载).在某些情况下,关于如何使用名称,`typedef`定义的名称与其定义的名称并不完全等效,但多个`typedef`定义的名称相同. (27认同)
  • 对问题2的答案+1 - 非常清楚.其余的答案也很清楚,但那个对我来说很突出:-) (4认同)

Che*_*Alf 31

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

typedef它来定义FunctionFunc为该类型的名称.

  • 这是一个非常好的思考方式.如果你仔细阅读其他答案,他们并没有真正解决OP对别名和名称纠缠的困惑.我从阅读这篇文章中学到了一些新东西. (5认同)

Hal*_*lci 7

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

using FunctionFunc = std::function<void(int arg1, std::string arg2)>;
Run Code Online (Sandbox Code Playgroud)

  • 没有 C++11 `using` 关键字就像 `typedef std::function&lt;void(int, std::string)&gt; FunctionFunc;`,以防万一有人想要另一个没有 C++11 的函数包装器 (2认同)
  • `std::function` 本质上与函数指针不同,并且以其他功能换取了更差的性能 (2认同)

Amj*_*jad 6

#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) );
}
Run Code Online (Sandbox Code Playgroud)