2017-06-30 2 views
3

Je travaillais des exemples de pointeurs de fonctions et j'ai développé 4 fonctions simples et les ai assignées à un tableau de pointeurs de fonction, puis j'ai couru le code et travaillé pour les 4 fonctions, mais j'ai pensé imprimer les noms des fonctions.Comment imprimer des noms en cascade de pointeurs de fonctions?

J'ai appris environ __func__ et il imprime seulement le nom de la fonction courante, ainsi est-il de toute façon assigner __func__ au pointeur de fonction ou à une autre méthode pour imprimer les noms des fonctions?

C'est l'exemple que je travaille en ce moment:

#include <stdio.h> 
#include <stdlib.h> 
#include <inttypes.h> 


int add(int x, int y); 
int sub(int x, int y); 
int mul(int x, int y); 
int divide(int x, int y); 


int main() { 
    int m = 6; 
    int n = 10; 
    int res,i; 


    int (*fun[4])(int,int)={add,sub,mul,divide}; 

    for (i=0;i<4;i++) 
    { 
     printf("result of %s operation\n",__func__=fun[i]); 
    } 
} 

int add(int x, int y) { 
int result = x + y; 
return result; 
} 

int sub(int x, int y) { 
int result = x - y; 
return result; 
} 

int mul(int x, int y) { 
int result = x * y; 
return result; 
} 

int divide(int x, int y) { 
int result = x/y; 
return result; 
} 

Comme vous pouvez le voir, je suis en train d'affecter le __func__ aux fonctions pointeur mais bien sûr, cela ne fonctionne pas.

+2

« je l'ai appris func », que voulez-vous dire par là? Que voulez-vous dire par "func"?Au lieu de décrire le code, essayez de créer un [Exemple minimal, complet et vérifiable] (http://stackoverflow.com/help/mcve) et * show * us à la place. –

+0

Le code compilé ne contient pas les noms des fonctions et des symols par défaut. Vous pouvez utiliser certaines macros pour créer des chaînes constantes contenant les noms de fonctions inclus dans le fichier binaire compilé. –

+1

S'il vous plaît fournir votre code ma boule de cristal ne fonctionne pas aujourd'hui. –

Répondre

3

La __func__ constante dans toutes les fonctions ne sont accessibles que dans l'exécution. Ce qui signifie que si vous voulez utiliser celui-là, vous devez l'attraper en appelant la fonction. Comme ceci:

typedef int calc_func_t (int x, int y, const char** func); 

int add(int x, int y, const char** func); 
... 

calc_func_t* fun[4] = {add,sub,mul,divide}; 

for (i=0;i<4;i++) 
{ 
    const char* func; 
    int result = fun[i](1,1,&func); 
    printf("result of %s operation %d\n", func, result); 
} 

... 

int add(int x, int y, const char** func) 
{ 
    int result = x + y; 
    *func = __func__; 
    return result; 
} 

... 

Si vous souhaitez savoir ce que les fonctions sont nommées à la compilation, puis plus tard sur l'utilisation de cette information, le plus facile et le meilleur moyen serait de créer une table de consultation:

typedef struct 
{ 
    calc_func_t* func; 
    const char* name; 
} calc_func_info_t; 

const calc_func_info_t func_info [] = 
{ 
    {add, "add"}, 
    {sub, "sub"}, 
    ... 
}; 
0

Fondamentalement, il n'y a aucun moyen.

// A function declaration 
void MyFunction(void); 

// a pointer to the function 
void (*fnPointer)(void) = MyFunction; 

// No way to retrieve function name "MyFunction" from fnPointer 

Ofcourse, si vous avez un ensemble connu de fonctions possibles qui pourraient être affectées au pointeur, vous pouvez les comparer explicitement.

Vous pouvez également modifier le pointeur de fonction stocké à associer au nom de la fonction. Pourrait être quelque chose de similaire à ce qui suit:

struct FunctionPointerContainer 
{ 
    void (*fnPointer)(void); 
    char* fnName; 
}; 

#define MakeFunctionPointer(fn) FunctionPointerContainer { fn, #fn } 

// later 
struct FunctionPointerContainer myPointer = MakeFunctionPointer(MyFunction); 
myPointer.fnPointer(); // call 
myPointer.fnName; // the function name 
2

Le code compilé ne contient pas les noms de fonctions et de symols par défaut. Vous pouvez utiliser des macros pour créer des chaînes constantes contenant les noms de fonctions à inclure dans le binaire compilé:

#include <stdio.h> 

// function call type 
typedef void fn_call(); 

// record describing one function 
typedef struct fn_record { 

    const char *name; // function's name as a constant string 
    fn_call *call; // function call 

} fn_record; 

// the functions to be called and named 
void fna() { printf("called fna\n"); } 
void fnb() { printf("called fnb\n"); } 
void fnc() { printf("called fnc\n"); } 

// macro, that generates record for each function, it creates 
// string like { "fna", fna } to save You typing 
#define FN_RECORD(f) { #f, f } 

// now define array of functions records 
fn_record fns[3] = { 
    FN_RECORD(fna), 
    FN_RECORD(fnb), 
    FN_RECORD(fnc) 
}; 

// ... which becomes: 
// fn_record fns[3] = { 
//  { "fna", fna }, 
//  { "fnb", fnb }, 
//  { "fnc", fnc } 
// }; 


int main(void) { 

    int i; 

    // ... use it whatever You like 
    for (i = 0; i < 3; i++) { 

     printf("%s\n", fns[i].name); 
     fns[i].call(); 
    } 

    return 0; 
} 
+2

Ce n'est pas une bonne idée. "Eviter de taper" n'est pas une raison valable pour utiliser des macros fonctionnelles, mais dans ce cas, vous utiliserez quelque chose comme "x macros" et l'appliquerez à tout le programme, pas seulement à la liste d'initialisation. , 'FN_RECORD (fna)' devrait être remplacé par le plus lisible et moins cryptique '{" fna ", fna}'. – Lundin

+0

(Ironiquement, quelqu'un a posté une solution macros ax juste quelques secondes après avoir posté ce commentaire) – Lundin

+0

@Lundin Eh bien, ce La macro évite en fait la répétition du code Si vous renommez la fonction, le compilateur détectera l'entrée de la table incorrecte, mais elle ne pourra pas détecter l'oubli en ajustant la chaîne .. La macro s'occupe implicitement de vous ... – Aconcagua

0

je travaillais des fonctions pointeurs exemples

donc, si je comprends, votre exemple est fait à des fins éducatives, n'êtes-vous pas? Dans ce cas, je le ferais aussi simplement que possible pour ne pas confondre les étudiants qui utilisent votre exemple pour apprendre comment fonctionnent les pointeurs.

je l'ai appris __func__ et il imprime uniquement le nom de la fonction actuelle

Malgré d'autres réponses montrent des solutions très agréable et intelligent comment avoir le nom de la fonction en dehors de celui-ci, du point de vue simplicité je toujours utiliser le __func__ comme il fonctionne normalement, dans la fonction appelée:

#include <stdio.h> 
#define print_info(format, ...) \ 
    printf("Function '%s' is called with parameters: "format"\n", \ 
    __func__, __VA_ARGS__) 

int add(int x, int y); 
int sub(int x, int y); 
int mul(int x, int y); 
int divide(int x, int y); 

int main() { 
    int m = 6, n = 10, i;  
    int (*fun[4])(int,int) = { add, sub, mul, divide }; 

    for (i = 0; i < 4; ++i) 
     printf("-- result is: %d\n", fun[i](n, m)); 

    return 0; 
} 

int add(int x, int y) { 
    print_info("%d, %d", x, y); 
    return x + y; 
} 

int sub(int x, int y) { 
    print_info("%d, %d", x, y); 
    return x - y; 
} 

int mul(int x, int y) { 
    print_info("%d, %d", x, y); 
    return x * y; 
} 

int divide(int x, int y) { 
    print_info("%d, %d", x, y); 
    return x/y; 
} 
+0

Pas à des fins éducatives, c'est pour moi. J'ai des problèmes avec ma programmation embarquée, je veux programmer ma carte Arduino en C pour communiquer avec HMC5883L, j'ai fait du bon travail pour développer les librairies I2C et HMC5883L, mais j'ai un problème avec la fonction qui lit les données de le capteur, il se bloque réellement lorsque l'axe des x atteint une valeur positive, si vous aimez je vous envoie mon lien de sujet dans le forum d'échange Arduino. –

+0

J'ai fait cet exemple de pointeurs de fonction de cette façon parce que je veux avoir autant de maniabilité que je peux en C; aimer, faire les choses de différentes manières ou comme je le veux. –