Выход программы C - PullRequest
       30

Выход программы C

1 голос
/ 25 апреля 2010
#include<stdio.h>

#define a(x) (x * x) 

int main() 
{
    int i = 3, j;

    j = a(i + 1);
    printf("%d", j);

    return 0;
}

Я хочу знать, почему программа не выдает 16. (Я получаю вывод 7.)


Я очень хорошо понял смысл, но если программа такая:

#include<stdio.h>

#define a(x) (x * x)

int main()
{
    int i = 3, j, k;

    j = a(i++);
    k = a(++i);
    printf("%d\n%d", j, k);

    return 0;
} 

Тогда почему вышеуказанная программа выдает следующий вывод:

9
49

Ответы [ 7 ]

7 голосов
/ 25 апреля 2010

Потому что вы сделали плохой макрос:

a(i + 1)

расширяется до

i + 1 * i + 1

, что эквивалентно

i + i + 1

или

2 * i + 1

Используйте скобки:

#define a(x) ((x) * (x))

И тогда вы получите расширение до

(i + 1) * (i + 1)

который делает то, что вы хотите.

2 голосов
/ 25 апреля 2010

После предварительной обработки строки

j=a(i+1);

будет:

j=(i+1*i+1);

, который при оценке для i=3 даст j=7:

j=(3+1*3+1);

Чтобы получить желаемый результат, вам нужно определить макрос как:

#define a(x) ((x)*(x)) 

, что приводит к:

j=((i+1)*(i+1));

и дает результат 16 при i=3

2 голосов
/ 25 апреля 2010

Прочтите приоритет оператора C и подумайте о том, что макрос a раскрывает в этом случае.

1 голос
/ 25 апреля 2010

Поскольку a(i+1) предварительно обрабатывается в (i+1*i+1).

А 3 + 3 + 1 = 7.

Возможно, вы захотите использовать круглые скобки вокруг x.

править: Ух ты, это избыточно или что? : /

0 голосов
/ 25 апреля 2010

Поскольку (i + 1) предварительно обрабатывается в (i + 1 * i + 1).

А 3 + 3 + 1 = 7.

Возможно, вы захотите использовать круглые скобки вокруг x.

править: Ух ты, это избыточно или что? : /

ссылка | флаг

0 голосов
/ 25 апреля 2010

Потому что ваш макрос неправильный. Очевидно, что это работает, но ошибка более тонкая (не совсем, но все же), поскольку у расширенного кода есть некоторые проблемы, не соответствующие ожидаемому порядку операций.

j = a(i+1) расширится до j = i + 1 * i + 1, что составляет 7.

Если вы хотите решить вашу проблему, переопределите макрос как:

#define a(x) ((x)*(x))

Хорошо, что вы столкнулись с этой проблемой сейчас, а не позже. Ошибки такого типа иногда очень трудно отлаживать, но теперь вы будете знать, как писать «профессиональные» макросы:).

0 голосов
/ 25 апреля 2010

Еще одна статья для объяснения в http://en.wikipedia.org/wiki/C_preprocessor#Precedence

...