0
votes

Comment faire une dynamique alors que le programme de boucle en C?

Comment faire une dynamique tandis que la boucle de boucle en C?

À cause de cette suivante: P>

#include <stdio.h>

typedef void (*FunctionName)();

void fun1();
void fun2();

int main() {

    int x = 1, i = 1;
    FunctionName y;

    y = (x == 1) ? fun1 : fun2;

    while (i <= 10) {
        y();
        i++;
    }
    return 0;
}

void fun1() {
    printf("1\n");
}

void fun2() {
    printf("2\n");
}

c

9 commentaires

Les lignes commençant par # sont des directives de préprocesseur. Les préprocesseurs ne savent pas ce que si sont.


Je pense que c'est une mauvaise pratique d'écrire des programmes à l'aide d'une telle construction. Si il y en a un.


Cela sent un peu comme xy-problème. Quel est le problème que vous essayez de résoudre?


Vous pouvez simplement exécuter différentes fonctions avec un si dans le moment.


Bien que non dans la norme C, mais dans POSIX, un Void * peut contenir n'importe quel pointeur de fonction que vous souhaitez. Votre problème sera comment savoir quelle distribution vous devez utiliser la fonction qu'elle contient.


@CACAHUETEFRITOO Je ne suis pas au courant de Posix définissant les extensions de langue C; Mais de toute façon dans la norme C, il n'est pas ub de jeter un pointeur de fonction tant que vous vous retrouvez avec l'original. Vous pouvez donc les stocker avec une étiquette et les transporter dans un type de pointeur opaque.


J'ai des fonctions avec presque la même boucle. Je veux combiner ces fonctions en une. Ensuite, je peux me débarrasser des codes dupliqués.


@ACorn Stackoverflow.com/a/5579907/6872717


@CACAHUETEEFRITOO Oui, j'ai explicitement dit des pointeurs de fonction (non à / de ceux-ci), ce que vous le feriez de manière portable. La standard C mentionne comme une extension commune (J.5.7) des pointeurs de fonction de moulage de / à Void * . Vérification de cette réponse (merci!), En effet, POSIX semble explicitement exiger une telle extension de fonctionner (bien que de la section Changelog, elle ressemble à une surveillance; ils ne pouvaient probablement pas espérer changer le type de retour ou la norme C, Donc, ils sont allés cette route). Pas sûr si le J.5.7 bit a été ajouté après posix "corrigé" que :)


3 Réponses :


1
votes

Je ne suis pas sûr de ce que vous essayez de résoudre, mais vous pourriez absorber le fonctionnement en envoyant les arguments avec un pointeur vide.

void *args;

struct fooArgs a = { 5, 6.7, NULL };

if(x == 1) {
    y = foo;
    args = a;
} else if (x == 2) {
    y = bar;
    args = NULL; // For a function without arguments;
}  

while (i <= 10) {
    y(args);
    i++;
}  


1 commentaires

Merci. Cela ressemble à la réponse que je cherche. Je pense avoir besoin d'un peu de temps pour étudier et voir si cela peut être utilisé. Merci encore.



1
votes

Mais, il ne peut accepter que le même type de fonctions. Dans ce cas, le y (). Il ne peut pas accepter deux ou plusieurs types de fonctions en même temps. Par exemple: F1 (a) et F2 (A, B). Donc, je dois faire toutes les fonctions au même type car elle ne peut pas accepter les types de diff. P>

Oui, car sinon, quels seraient les arguments? En d'autres termes, votre fun1 code> et fun2 code> ne prend aucun paramètre. Si vous souhaitez appeler un Fun3 CODE> qui prend 1 paramètre, quel serait l'argument? P>

En d'autres termes, envisagez: P>

void g() {
    fun3(42);
}

y = g;
y();


0 commentaires

1
votes

Mettez le commutateur ou si sinon pour des conditions plus complexes à l'intérieur de la boucle tandis que:

while(i <= 10)
{
   if(condition 1)
      //call f1();
   ...
   else if (condition n)
   {
      // call fn;
   ...
   else
   {
      // nothing of the prevous cases
   }
   i ++
}


2 commentaires

Merci. Je l'ai déjà fait ça. Mais, je ne veux tout simplement pas que la boucle fonctionne si sinon à chaque fois. Donc, j'utilise si, alors que d'autre. Et puis j'ai trouvé que j'ai tellement de codes dupliqués.


@Frank Si vous vous souciez de performances, dupliquez le code et vérifiez s'il est plus rapide. Si vous ne vous souciez pas, utilisez simplement cette solution. La folie impliquée dans l'obtention d'une solution performante avec des pointeurs de fonction n'en vaut pas la peine. Laissez le compilateur faire son travail optimiser en utilisant -O3.