Как передать не оцененное выражение логического условия в функцию? - PullRequest
1 голос
/ 19 апреля 2020

Код, который я написал ниже, повторяется 3 раза:

int foo = 3;
while (foo < 10) {
    printf("Hi!");
    foo++;
}
foo = 12;
while (foo % 8 != 0) {
    printf("Hi!");
    foo++;
}
foo = 25
while (foo <= 38) {
    printf("Hi!");
    foo++;
}

Это можно упростить до функциональной панели (foo, условие ); Эта функция будет выглядеть следующим образом:

while (foo <= 38) {
    printf("Hi!");
    foo++;
}

, и я бы назвал ее так:

print_hi(3, foo < 10);
print_hi(12, foo % 8 != 0);
print_hi(25, foo <= 38);

Ответы [ 3 ]

2 голосов
/ 19 апреля 2020

Как передать логическое условие в функцию?

В качестве близкой альтернативы код может использовать указатели на функции. Создайте это условие как функцию.

bool f_lt(int a, int b) {
  return (a < b);
}

bool f_rem(int a, int b); // definition left for OP
bool f_le(int a, int b); // definition left for OP

void print_hi(int foo, int bar, bool (*condition)(int, int));
  while(condition(foo, bar)){
    printf("Hi!");
    foo++;
  }
}

Вызовите их как:

print_hi(3, 10, f1_lt);
print_hi(12, 8, f1_rem);
print_hi(25, 38, f1_le);
1 голос
/ 19 апреля 2020

«Как передать логическое условие в функцию?»

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

Вы не можете передавать не оцененные выражения в функцию.

Если логические выражения являются константными и ограничиваются только тремя, указанными в примере, и вы явно хотите использовать выражение в вызове функции (для удобства чтения), вы можете использовать строковый литерал и сравнивать строковый литерал внутри функции как альтернатива вместо. Обратите внимание, что вам нужно заключить выражение в "", например "exp" в этом случае:

#include <stdio.h>
#include <string.h>

void print_hi(int, const char const *);

int main(void)
{
   print_hi(3, "val < 10");
   print_hi(12, "val % 8 != 0");
   print_hi(25, "val <= 38");

   return 0;
}

void print_hi(int val, const char const * str)
{
   int exp = 0;

   if(strcmp(str, "val < 10") == 0);
   {
       exp = 1;
   }
   else if(strcmp(str, "val % 8 != 0") == 0);
   {
       exp = 2;  
   }
       else if(strcmp(str, "val <= 38") == 0)
       {
          exp = 3;
       }
          else
            return;

   switch(exp)
   {
      case 1:
      while (val < 10) 
      {
         printf("Hi!");
         val++;
      }      
      break;

      case 2:
      while (val % 8 != 0)
      {
        printf("Hi!");
        val++;
      }
      break;

      case 3:
      while (val <= 38) {
        printf("Hi!");
        val++;
      }
      break;

      default:
      break;
   }

   return;
}

Или вы также можете просто использовать значение для него в качестве альтернативы, и внутри функции определите путь на основании этого значения:

#include <stdio.h>

void print_hi(int, unsigned short int);

int main(void)
{
   print_hi(3,1);
   print_hi(12,2);
   print_hi(25,3);

   return 0;
}

void print_hi(int val, unsigned short int exp)
{
   switch(exp)
   {
      case 1:
      while (val < 10) 
      {
         printf("Hi!");
         val++;
      }      
      break;

      case 2:
      while (val % 8 != 0)
      {
        printf("Hi!");
        val++;
      }
      break;

      case 3:
      while (val <= 38) {
        printf("Hi!");
        val++;
      }
      break;

      default:
      break;
   }

   return;
}
1 голос
/ 19 апреля 2020

Подобное решение, как и в ответе chux, только в синтаксисе может быть немного ближе к желаемой форме, заданной в вопросе.

Как это работает:

EXPR - это макрос с двумя параметрами. Первый параметр - это имя указателя функции. Второе - это выражение для оценки. Функция ничего не делает, кроме как выполняет выражение и возвращает результат bool.

#include <stdio.h>
#include <stdbool.h>

#define EXPR(a, b) bool (a)(int foo) { return (b); }

void print_hi(int foo, bool (*expr_ptr)(int)) {
    while (expr_ptr(foo)) {
        printf("Hi!");
        foo++;
    }
}

EXPR(expr1, foo < 10)
EXPR(expr2, foo % 8 != 0)
EXPR(expr3, foo <= 38)

int main(void) {
    print_hi(3, expr1);
    print_hi(12, expr2);
    print_hi(25, expr3);

    return 0;
}
...