SIGN Macro в C препроцессоре - PullRequest
0 голосов
/ 29 января 2020

Я пытался написать макрос SIGN, который возвращает либо -, либо +.

Однако он работает не так, как я ожидал, кто-нибудь знает, как это сделать?

#include <stdio.h>
#define ABS(x) (((x) < 0) ? (-(x)) : (x))
#define MAX(x,y) (((x) < y) ? (y) : (x)
#define MIN(x,y) (((x) < y) ? (x) : (y))
#define DIFF(x,y) (ABS(x-y))
#define SIGN(x) (((x) < 0) ? (-) : (+))

int main(){

  int i = -45;
  int j = -5;
  printf("%c\n", SIGN(i) );

  return 0;
}

Все остальные макросы работают, но с SIGN я получаю ошибку

"error: ожидаемое выражение перед ')" токен #define SIGN (x) (((x) <0)? (-): (+ )) "</p>

Ответы [ 2 ]

1 голос
/ 29 января 2020

Возможны две версии:

  • #define SIGN(x) ( (x) < 0 ? '-' : '+' )
    Это наивное решение. Возвращает int, соответствующий символам '-' и '+'. Он не обрабатывает ноль правильно. Скорее всего, это просто хорошо для начинающих.

  • #define SIGN(x) ( "+- "[((x)<=0) + !(x)] )
    Это слишком сложное решение. Возвращает char со значением '-' или '+', или, в случае нуля, пробел ' '. Он использует логическую арифметику c в соответствии с этой таблицей истинности:

    x     x<=0   !x
    pos   false  false
    neg   true   false
    0     true   true
    

    Добавление результата двух логических выражений дает значение 0, 1 или 2, которое затем используется как индекс поиска в строковый литерал "+- ". Пример:

    #include <stdio.h>
    
    #define SIGN(x) ( "+- "[((x)<=0) + !(x)] )
    
    int main (void)
    {
      int a = -123;
      int b = +123;
      int c = 0;
      printf("%c\n", SIGN(a));
      printf("%c\n", SIGN(b));
      printf("%c\n", SIGN(c));
    }
    
0 голосов
/ 29 января 2020
#define SIGN(x) (((x) < 0) ? ('-') : ('+'))

printf("%c\n", SIGN(i) );  // Will print either - or + followed by NewLine(\n)
...