2010-02-12 5 views
5

int * (*) (int *, int * (*)())type de int * (*) (int *, int * (*)())

Je voudrais savoir ce que type est-ce? , quelqu'un peut-il donner un exemple d'une déclaration en utilisant ce type.

toute aide serait géniale.

merci.

+1

Quelle langue est-ce encore? C++? –

+1

J'ai deviné que c'est C et étiqueté comme tel. –

+0

wow, c'est plutôt sadique ... –

Répondre

19

Il est un pointeur vers une fonction qui retourne int* et accepte int* et pointeur vers une fonction qui retourne int* (et accepte nombre indéfini de paramètres, voir les commentaires).

Quelques exemples (ne semble pas très agréable, il est tout simplement construit pour contenir la déclaration mentionnée):

#include <stdio.h> 

static int a = 10; 
int* f1() { 
    return &a; 
} 

static int b; 
int* f2(int *j, int*(*f)()) { 
    b = *j + *f(); 
    // this is just for demonstrational purpose, such usage 
    // of global variable makes this function not thread-safe 
    return &b; 
} 


int main(int argc, char *argv[]) { 
    int * (*ptr1)(); 
    int * (*ptr2) (int * , int * (*)()); 
    ptr1 = f1; 
    ptr2 = f2; 

    int i = 42; 
    int *pi = ptr2(&i, ptr1); 
    printf("%d\n", *pi); 

    return 0; 
} 

// prints 52 
+6

Strictement puisque ceci est étiqueté C, il accepte un nombre indéfini de paramètres. En C++ et une liste de paramètres vide signifie pas de paramètres, en C, il faudrait être (void) pour le spécifier. Arcane mais vrai ;-) – Clifford

+0

en fait je pense que les paramètres ne sont pas spécifiés, en supposant que ce soit C. "(void)" n'accepterait aucun paramètre, comme le ferait "()" en C++. – aib

0
typedef int* (*fptr)();  
int* foo(int* p1, fptr p2); 

Vous pouvez mettre foo dans ce type.

7

cdecl est votre ami:

$ cdecl explain 'int * (*x) (int * , int * (*)())' 
declare x as pointer to function (pointer to int, pointer to function returning pointer to int) returning pointer to int 
+11

ouais, sauf que cela ne fonctionne pas sans ce 'x' vous avez ajouté et à moins que vous compreniez la déclaration en premier lieu, vous ne sauriez pas ajouter le' x';) – ezpz

+1

S'il n'y a pas d'identifiant (qui devrait être facile à repérer), alors vous pouvez obtenir 'cdecl' pour l'expliquer en le préfixant avec' ('et le suffixant avec') x'. Il dira alors "' cast x into ... '", suivi de l'explication du type. – caf

2

Hmmm ... selon cdecl.org qui était une erreur de syntaxe - laissez-moi essayer

 
int * (*) (int *,int *(*)()) 
  • (int *, int ()()) - inermost (*)() - un pointeur vers la fonction int ()() - poi nter pour fonctionner sans paramètre, retourner le pointeur à int
  • (int *, ...) - deux paramètres, l'un est un pointeur sur int, et l'autre est pointeur vers fonction-avec-no-paramètres- return-pointer-to-int
  • (*) (...) - un pointeur de fonction avec les paramètres
  • int * (*) (...) - une fonction-pointer-return-pointer-to- int

Alors: Il est une fonction pointeur qui a les deux paramètres que le premier paramètre est un pointeur vers int et l'autre est le pointeur à la fonction-sans-aucun-paramètres-retour-pointeur à -int, et son-return-pointer-à-int.

Edit: La déclaration C que j'ai utilisé dans ce site - je ne l'ai pas mis dans un nom de variable comme dans

 
int *(*x)(int *,int *(*)()) 

qui est revenu: déclare x comme pointeur à la fonction (pointeur vers int , pointeur vers pointeur de retour de fonction int) pointeur retour int

Hope this helps, Meilleures salutations, Tom.

1

Il existe une technique appelée "règle de droite-gauche" qui peut vous aider à déchiffrer des déclarations complexes comme celles-ci. La règle fonctionne en substituant des mots-clés anglais aux attributs qui apparaissent dans la déclaration. Ensuite, lorsque vous mettez les mots-clés ensemble, la phrase construite décrira la déclaration.

est ici les attributs et les mots-clés que vous devez utiliser:

  • Quand vous voyez l'attribut «() » fonction « qui retourne » mot-clé utilisé
  • Quand vous voyez l'attribut « [n] » utilisation mot-clé « tableau de n »
  • Quand vous voyez l'attribut « * » mot-clé utilisé « pointeur »

maintenant, voici la « règle droite-gauche »:

  1. Commencez par l'identifiant.
  2. Regardez vers la droite pour un attribut.
  3. Si aucun n'est trouvé, regardez vers la gauche.
  4. Une fois qu'un attribut est trouvé, remplacez son mot-clé anglais.
  5. Poursuivre les substitutions droite-gauche pendant que vous travaillez.
  6. Arrêtez lorsque vous avez atteint le type de données dans la déclaration.

Voici quelques exemples:

int n[10]; 

L'identifiant est n. L'attribut sur la droite est [10], utilisez le mot-clé "tableau de 10". Ensuite, vous atteignez le type de données int. Ainsi,

n est un "tableau de 10 nombres entiers".

int *n[10]; 

L'identificateur est n. L'attribut sur la droite est [10], utilisez le mot-clé "tableau de 10". Regardez vers la gauche et l'attribut est * alors utilisez le mot-clé "pointeur vers". Il n'y a plus d'attributs. Tout ce qui reste est le type de données, qui est int. Mettez les mots-clés ensemble pour obtenir:

n est un "tableau de 10 pointeurs aux entiers".

int (*pf)(); 

L'identifiant est pf. Il n'y a aucun attribut immédiatement à droite de pf. À la gauche de pf est *. Donc le premier mot-clé est "pointer vers". Ensuite, retournez à droite et l'attribut est (). Cela signifie que le mot clé suivant est "function that returns". Maintenant, revenez à gauche pour le type de données int. Mettez les mots-clés ensemble pour obtenir:

est un pf « pointeur vers une fonction qui retourne un entier »

int *(*pf)(); 

est l'identifiant pf. Il n'y a pas d'attributs à droite de pf. À gauche est *, donc le premier mot-clé est "pointer vers". Retour à la droite est (), de sorte que le mot-clé suivant est "fonction qui renvoie". Retour à gauche est *, le mot-clé suivant est "pointeur vers". Ensuite, atteignez le type de données int:

pf est un "pointeur vers une fonction qui renvoie un pointeur sur un int".

Cet exemple suivant est similaire au précédent, mais cette fois il y a des arguments à la fonction pf. Les arguments sont int *x et int *(*y)(). Vous devriez être capable de décrire chacun de ces arguments en fonction de tout ce qui se passe jusqu'à présent. Et une fois que vous faites cela, vous serez en mesure de décrire la chose:

int *(*pf)(int *x, int *(*y)()); 

est un pointeur PF à une fonction qui renvoie un pointeur vers un int. pf prend deux arguments. Le premier argument x est un pointeur sur un int. Le deuxième argument y est un pointeur vers une fonction qui renvoie un pointeur vers un int.

0

De telles déclarations sont vraiment utilisées! Considérons la fonction de signal de la bibliothèque standard C:

void (* 
    signal(int sig, void (*func)(int)))(int); 

la page de manuel de signal explique qu'il est équivalent à la version typedef suivante:

typedef void (*sig_t) (int); 
sig_t signal(int sig, sig_t func); 

Une fonction qui prend deux args et int et une fonction sig_t, et qui renvoie l'ancienne fonction sig.