Что я делаю не так с моим макросом в C? - PullRequest
0 голосов
/ 18 февраля 2019
#include <stdio.h>
#include <stdlib.h>

#define MAXIMUM(a,b) (a>b ? a:b)
#define MAX(a,b,c) (MAXIMUM(MAXIMUM(a,b),c))
#define MINIMUM(a,b) (a<b ? a:b)
#define MIN (a,b,c) (MINIMUM(MINIMUM(a,b),c))
#define MID(a,b,c) (MAX(a,b,c)+ MIN(a,b,c))/2


int main()
{
    int a=0; int b=0; int c=0;
    scanf("%d",&a);
    scanf("%d",&b);
    scanf("%d",&c);
    float t = MID(a,b,c);
    printf("%f\n",t);
    return 0;
}

Я получаю ошибку

left operand of comma has no operator in #define MID(a,b,c)
The expression cannot be used as a function in #define MIN

Ответы [ 3 ]

0 голосов
/ 18 февраля 2019

Убрать пробел после MIN, должно быть:

#define MIN(a,b,c) (MINIMUM(MINIMUM(a,b),c))

Работает.

0 голосов
/ 20 февраля 2019

Существует несколько проблем с использованием макросов таким, какой вы есть.Идея, лежащая в основе макросов, заключается в том, чтобы упростить кодирование, поскольку нет проверок типов, которые чреваты опасностью:

Проблема - нет проверок типов:

#include <stdio.h>

#define max(a,b)  ((a) > (b) ? (a):(b))
int main()
{
    int a = -1;
    unsigned int b = 2;
    printf("The max is: %d\n", max(a,b));

    return 0;
}

Вывод довольно неопределенный.gcc выводит -1

Проблема - двойная оценка

Двойная оценка происходит, когда ваши макропараметры НЕ являются простыми переменными, например:

#include <stdio.h>

#define max(a,b)  ((a) > (b) ? (a):(b))

int main() {
     int a = 1, b = 2;
     printf("max(%d, %d) = %d\n", a, b, max(a, b));
     printf("max(%d, %d) = %d\n", a, b, max(a++, b++));
     printf("max(%d, %d) = %d\n", a, b, max(a, b));
     return 0;
 }

Если вы смотрите наmid(a,b,c) это еще хуже.

Заключение

Пожалуйста, не пишите такой код.

Если вы придерживаетесь компилятора, где нет нестандартный оператор typeof, тогда лучше использовать stdtypes.h и stdint.h и объявить функции:

#define __declare_min(__type) __inline__ static __type min_ ## __type(__type a, __type b) { return a < b ? a : b;  } 

__declare_min(uint32_t)
__declare_min(int64_t)

, и вы можете использовать их явно:

int main() {
     printf("%u", min_uint32_t(3, -5));
     printf("%d", min_int64_t(-1, -5));
} 

Если у вас есть компилятор с оператором типа typeof, вы можете использовать:

#define max(a,b) \
  ({ typeof (a) _a = (a); \
      typeof (b) _b = (b); \
    _a > _b ? _a : _b; })

GCC-специфичный

Если вы используете достаточно новую версию gcc - скорее всего,если вы используете gcc, то вы - вы должны использовать __auto_type вместо typeof:

#define max(a,b) \
  ({ __auto_type _a = (a); \
      __auto_type _b = (b); \
    _a > _b ? _a : _b; })

Для gcc typeof справочной страницы] 1 :

Использование __auto_type вместо typeof имеет два преимущества:

  1. Каждый аргумент макроса отображается только ве в расширении макроса.Это предотвращает экспоненциальный рост размера макроса, когда вызовы таких макросов вложены в аргументы таких макросов.

  2. Если аргумент макроса имеет изменяемый тип, он оценивается только один раз при использовании __auto_type, но дважды, если используется typeof.

C ++

Это совсем другое обсуждение :-)

0 голосов
/ 18 февраля 2019

О!Я знаю, в чем ваша проблема:

#define MIN (a,b,c) (MINIMUM(MINIMUM(a,b),c))

должно быть

#define MIN(a,b,c) (MINIMUM(MINIMUM(a,b),c))

Препроцессор чувствителен к пробелам;между токеном MIN и списком его параметров не должно быть пробелов (a,b,c)

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