Как сделать динамическую программу цикла while в C? - PullRequest
0 голосов
/ 06 мая 2019

Как создать динамическую программу while в C?

Из-за этого:

if {
    while
} else if {
    while
} else {
    while
}

Я хочу, чтобы программа выполняла динамический цикл while.Я сделал два подхода.

первый: (не работает)

#include <stdio.h>

#define aaa printf("0\n")

int main() {

    int x = 1, i = 1;

    if (x == 1) {
        #undef aaa
        #define aaa printf("1\n")
    }   else {
        #undef aaa
        #define aaa printf("2\n")
    }

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

второй: (работает)

#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");
}

, но он может принимать только тот же тип функций,в этом случае у ().он не может принимать два или более типов функций одновременно.например: f1 (a) и f2 (a, b).Итак, я должен сделать все функции одного типа, потому что он не может принимать различные типы.

эта динамика, в то время как программа цикла может принимать только один тип функций.тогда это не полная динамика.как я могу решить проблему?как я могу заставить его принимать все виды функций?любые комментарии приветствуются.спасибо.

Ответы [ 3 ]

1 голос
/ 06 мая 2019

но он может принимать только те же функции. в этом случае у (). он не может принимать два или более типов функций одновременно. например: f1 (a) и f2 (a, b). Итак, я должен сделать все функции одного типа, потому что он не может принимать различные типы.

Да, потому что иначе, каковы будут аргументы? Другими словами, ваши fun1 и fun2 не принимают параметров. Если вы хотите вызвать fun3, который принимает 1 параметр, каким будет аргумент?

Другими словами, рассмотрим:

void fun3(int);

y = fun3;
y(???);

Для некоторых значений y вам придется передавать различное количество аргументов. То же самое для типа возврата.

То, что вам нужно сделать, это создать функцию-обертку, которая выполняет то, что называется частичное приложение , например. fun3

void g() {
    fun3(42);
}

y = g;
y();

Здесь g несет ответственность за знание аргументов fun3 (они могут быть постоянными, как в этом примере, или поступать откуда-то еще).

В языках, которые поддерживают определяемые пользователем типы (и, возможно, ООП), таких как C ++, типичным решением является создание "Callable" объекта, который хранит аргументы как члены данных и может вызываться так, как если бы это была функция.

Кроме того, в некоторых из этих языков вы получаете некоторый синтаксический сахар для простого создания этих вызываемых объектов на месте, обычно называемых лямбдами или замыканиями.

1 голос
/ 06 мая 2019

вставьте переключатель или, если еще, для более сложных условий внутри цикла while:

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

вы также можете использовать swithch case внутри цикла while, если сравниваете с константами ... надеюсь, это поможет

1 голос
/ 06 мая 2019

Я не уверен, какую проблему вы пытаетесь решить, но вы могли бы заставить ее работать, отправив аргументы с пустым указателем.

typedef void (*FunctionName)(void *);

Затем (если вам нужно несколько параметров) создайте разные структуры для разных функций:

struct fooArgs {
    int x;
    double y;
    char *s;
};

Затем создайте такую ​​функцию:

void foo(void *args) {
    struct fooArgs *a = (struct fooArgs*)args;
    int x = a->x;
    double y = a->y;
    char *s = a->s;
    /* Do stuff */
}

Вам нужно написать что-то похожее на y = (x == 1) ? fun1 : fun2; для аргументов. Это может выглядеть примерно так:

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++;
}  

Однако я не рекомендую делать это, если вы действительно не уверены в том, что делаете. Если это из-за производительности, выигрыш, вероятно, очень низкий, и даже вероятно, что вы просто усложняете работу оптимизатора компилятора с худшей производительностью в результате. Используйте такие вещи для производительности в качестве абсолютного крайнего средства, и только если вам действительно нужны эти дополнительные миллисекунды.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...