Wskaźnik funkcji Typedef?

Uczę się dynamicznie wczytywać DLL, ale nie rozumiem tej linii

typedef void (*FunctionFunc)();
Mam kilka pytań. Jeśli ktoś jest w stanie na nie odpowiedzieć, będę wdzięczny.
  1. Dlaczego typedef jest używany?
  2. składnia wygląda dziwnie; po void nie powinno być nazwy funkcji lub czegoś takiego? Wygląda na anonimową funkcję.
  3. czy wskaźnik funkcji jest tworzony do przechowywania adresu pamięci funkcji?

Więc jestem zdezorientowany w chwila, możesz mi coś wyjaśnić?

Author: Claudio, 2010-11-28

6 answers

typedef jest konstrukcją języka, która kojarzy nazwę z typem.
Używasz go w ten sam sposób, w jaki używasz oryginalnego typu, na przykład

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

Używanie ich jak

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

Jak widzisz, możesz po prostu zastąpić wpisaną nazwą z jej definicją podaną powyżej.

Trudność polega na wskaźniku do składni i czytelności funkcji w C i C++, a {[3] } może poprawić czytelność takich deklaracji. Jednak składnia jest właściwe, ponieważ funkcje-w przeciwieństwie do innych prostszych typów - mogą mieć zwracaną wartość i parametry, stąd czasem długa i złożona deklaracja wskaźnika do funkcji.

Czytelność może zacząć być naprawdę trudna ze wskaźnikami do tablic funkcji i innymi, jeszcze bardziej pośrednimi smakami.

Aby odpowiedzieć na twoje trzy pytania

  • Dlaczego stosuje się typedef? Aby ułatwić odczyt kodu-szczególnie dla wskaźników do funkcji, czy struktury nazwiska.

  • Składnia wygląda dziwnie (w deklaracji wskaźnika do funkcji) Ta składnia nie jest oczywista do odczytania, przynajmniej na początku. Użycie deklaracji typedef ułatwia czytanie

  • Czy wskaźnik funkcji jest tworzony do przechowywania adresu pamięci funkcji? Tak, Wskaźnik funkcji przechowuje adres funkcji. Nie ma to nic wspólnego z konstrukcją typedef, która tylko ułatwia pisanie/czytanie programu ; kompilator po prostu rozszerza definicję typedef przed kompilacją rzeczywistego kodu.

Przykład:

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
 499
Author: e2-e4,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-09 08:59:18
  1. typedef jest używany do aliasów typów; w tym przypadku aliasujesz FunctionFunc do void(*)().

  2. Rzeczywiście składnia wygląda dziwnie, spójrz na to:

    typedef   void      (*FunctionFunc)  ( );
    //         ^                ^         ^
    //     return type      type name  arguments
    
  3. Nie, to po prostu mówi kompilatorowi, że typ FunctionFunc będzie wskaźnikiem funkcji, to nie definiuje jeden, jak to:

    FunctionFunc x;
    void doSomething() { printf("Hello there\n"); }
    x = &doSomething;
    
    x(); //prints "Hello there"
    
 198
Author: Jacob Relkin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-26 17:42:53

Bez słowa typedef, W C++ deklaracja deklaruje zmienną FunctionFunc typu wskaźnik do funkcji bez argumentów, zwracając void.

Z typedef zamiast tego Definiuje FunctionFunc jako nazwę dla tego typu.

 35
Author: Cheers and hth. - Alf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-24 13:57:40

Jeśli możesz używać C++11, możesz użyć słów kluczowych std::function i using.

using FunctionFunc = std::function<void(int arg1, std::string arg2)>;
 11
Author: Halil Kaskavalci,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-21 08:20:05
#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) );
}
 2
Author: Amjad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-11 22:24:22

Dla ogólnego przypadku składni można spojrzeć na Załącznik A do standardu ANSI C .

W formie Backus-Naur stamtąd widać, że typedef mA typ storage-class-specifier.

W typie declaration-specifiers widać, że można mieszać wiele typów specyficznych, których kolejność nie ma znaczenia.

Na przykład, poprawne jest powiedzenie,

long typedef long a;

Aby zdefiniować typ a jako alias dla long long. Tak więc, aby zrozumieć typedef na wyczerpującym użyciu trzeba skonsultować się z niektórych forma backus-naur określająca składnię (istnieje wiele poprawnych gramatyk ANSI C, nie tylko ISO).

Kiedy używasz typedef do definiowania aliasu dla typu funkcji, musisz umieścić alias w tym samym miejscu, w którym umieścisz identyfikator funkcji. W Twoim przypadku definiujesz typ FunctionFunc jako alias dla wskaźnika do funkcji, której sprawdzanie typu jest wyłączone podczas wywołania i nic nie zwraca.

 2
Author: alinsoar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-05-17 06:43:57