Использование макросов в программе, которая вычисляет средний диапазон трех значений - PullRequest
0 голосов
/ 08 октября 2019

Я пытаюсь создать программу, которая использует макросы для определения среднего диапазона для трех значений. Средний диапазон определяется как:

midrange(a, b, c) = (min(a, b, c) + max(a, b, c)) / 2

Например:

midrange(3, 10, 1) = (min(3, 10, 1) + max(3, 10, 1)) / 2

                   =  (1 + 10) / 2 

                   =   11 / 2

                   =  5.5 

Я все еще новичок в программировании, и я не уверен, что синтаксис, который я использую для определений макросов, правильный,Мой первый вопрос: могу ли я определить макрос в основной функции? Мой второй вопрос, использовать ли фигурные скобки, нормальные круглые скобки или вообще ничего для тела макроса, то есть списка замены?

Вот так выглядит моя программа для вычисления среднего диапазона трех целочисленных значений:

#include <stdio.h>
#define MIN(A, B) {(A) < (B) ? (A) : (B);}
#define MAX(A, B) {(A) > (B) ? (A) : (B);}

int main(){
    //scans the three values
    int a, b, c;
    scanf("%d%d%d", &a, &b, &c);

    int min = MIN(MIN(a, b), c); 
    int max = MAX(MAX(a, b), c);

    //defines new macro for calculating the midrange
    //is this allowed/correct formatting and syntax?
    #define MIDRANGE((min + max) / 2);

    /* initializes variable mrange to equal to the value returned
    function-like macro, MIDRANGE */ 
    double mrange = MIDRANGE((min + max) / 2);

    printf("The mid-range is: %lf", mrange);

    return 0;

}

Причина, по которой я объявил переменную mrange как двойную, заключается в том, что я хочу получить значениеМакрос MIDRANGE, если быть точным, означает, что он будет сохранять десятичные разряды после деления на 2 в уравнении.

Любая помощь приветствуется:)

Ответы [ 2 ]

1 голос
/ 10 октября 2019

Вы можете объявить макрос в любом месте кода, но если у вас нет особых причин ограничивать его использование функцией, он обычно появляется в начале файла .c или в файле .h.

Макросы работают по подстановке. Поэтому, если у вас есть что-то похожее на следующее:

#define MIN(A, B) {(A) < (B) ? (A) : (B);}
int main(void)
{
    int min = MIN(MIN(a, b), c);
}

Это будет предварительно обработано в:

int min = {({(a) < (b) ? (a) : (b);}) < (c) ? ({(a) < (b) ? (a) : (b);}) : (c);};

Вы можете увидеть это сами, если используете GCC, с помощью командыgcc -E source.c. Это явно не то, что вы хотели, и это даст вам ошибку компиляции.

Мы никогда не используем ; в конце макросов, и не помещаем их в блоки. Чтобы избежать неожиданной связи оператора со сложными выражениями, мы защищаем параметры макроса и весь макрос в скобках.

Ваш макрос MIN должен выглядеть примерно так:

#define MIN(A, B) ((A) < (B) ? (A) : (B))

Наконец, естьдве вещи, происходящие с вашим макросом MIDRANGE. Во-первых, он должен принимать аргументы, как вы сделали с MIN. В идеале это должно быть три аргумента;в конце концов, вся причина сделать это макросом, чтобы пользователю макроса не приходилось все вычислять. Во-вторых, если вы хотите, чтобы результат был числом с плавающей запятой, вы должны разделить его на 2,0, а не на 2.

Вот мое первое предложение:

#define MIDRANGE(A, B, C) ((MIN(MIN(A, B), C) + MAX(MAX(A, B), C)) / 2.0)

Однако почему это так? макрос? Сделайте это функцией. Это более читабельно, и легче поддерживать. Итак, вот мое второе предложение:

double midrange(int a, int b, int c)
{
    int min = MIN(MIN(a, b), c);
    int max = MAX(MAX(a, b), c);
    return (min + max) / 2.0;
}
0 голосов
/ 08 октября 2019

относительно:

#define MIN(A, B) {(A) < (B) ? (A) : (B);}
#define MAX(A, B) {(A) > (B) ? (A) : (B);}

Давайте помнить, что макрос - это не что иное, как прямая замена текста.

Итак, взглянув на:

int min = MIN(MIN(a, b), c);

, мы получим:

int min = {{(a) <(b)? (a): (b);} <(c);}; </p>

, как очевидно из вышесказанного,

  1. min находится за скобками '{' и '}'поэтому будет трудно присвоить
  2. , результирующий оператор содержит два ложных символа ';'символов, на что жалуется компилятор

Предложить:

#define MIN( A, B ) ((A) < (B)) ? (A) : (B)

Аналогичные соображения существуют для макроса MAX

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