Вопрос

ПРИВЕТ ,

Может ли кто-нибудь помочь мне понять, почему значение SQUARE(x) равно 49?

Я использую Visual C++ 6.0.

#define SQUARE(X) X * X

int main(int argc, char* argv[])
{
    int y = 5;

    printf("%d\n",SQUARE(++y));
    return 0;
}
Это было полезно?

Решение

Нил Баттерворт, Марк и Павел правы.

SQUARE(++y) расширяется до ++y * ++y, что увеличивает значение y в два раза.

Еще одна проблема, с которой вы можете столкнуться:SQUARE(a + b) расширяется до a + b * a + b, что не (a+b)*(a+b), а a + (b * a) + b.При необходимости при определении макросов следует позаботиться о добавлении круглых скобок вокруг элементов:#define SQUARE(X) ((X) * (X)) немного менее рискован.(Ян Кемп первым написал это в своем комментарии)

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

template <class T>
inline T square(T value)
{
    return value*value;
}

Вы можете проверить, работает ли это:

int i = 2;
std::cout << square(++i) << " should be 9" << std::endl;
std::cout << square(++i) << " should be 16" << std::endl;

(не нужно писать

square<int>(++i)

потому что тип int является неявным для i)

Другие советы

Потому что макрос расширяется до:

++y * ++y

что приводит к неопределённому поведению в C++ - результат может быть чем угодно.Эта очень известная проблема должна быть описана в любом приличном учебнике по использованию макросов.Какой из них вы используете?

Поскольку макросы выполняют текстовую замену, поэтому написанный вами код расширяется до

printf("%d\n",++y * ++y );

и тогда порядок операций не определен, поэтому компилятор видит 2 приращения, а затем умножение

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

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

Макросы не являются функциями:они просто изменяют текст программы.Эта операция называется предварительная обработка и он автоматически выполняется перед компиляцией вашего кода.Люди пишут макросы, чтобы сэкономить время и внести некоторую вариативность в исходный код.

Когда ты пишешь SQUARE(x), фактического вызова функции не происходит, изменяется только текст.Операция довольно тупая, поэтому в таких случаях, как ваш, придется принимать дополнительные меры предосторожности.Обратитесь к другим ответам для объяснения вашего случая.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top