Вывод этого кода C - 49, но может кто-нибудь объяснить мне, как? [дубликат]
#include <stdio.h>
#define CUBE(x) (x * x * x)
int main() {
printf("%d", CUBE(4+5));
return 0;
}
Ответы
Макрос превратит код в:
printf("%d", (4+5 * 4+5 * 4+5));
что эффективно:
printf("%d", 4 + (5*4) + (5*4) + 5); // 29
Если хочешь куб 9
получить 729
, надо писать CUBE((4+5))
.
Вот как макрос раскрывается в процессе компиляции:
printf("%d", (4+5 * 4+5 * 4+5));
Поскольку *
имеет более высокий приоритет, чем +
, это выражение оценивается как (4 + (5 * 4) + (5 * 4) + 5)
, производя 49
вместо ожидаемого 729
.
Чтобы избежать таких проблем с приоритетом операторов, все аргументы макроса должны быть заключены в скобки в определении макроса, а также само выражение:
#define CUBE(x) ((x) * (x) * (x))
Отметим , однако , что это расширение CUBE
Равняется x
несколько раз, что является проблемой , если макро аргумент имеет побочные эффекты, такие как CUBE(i++)
.
Чтобы избежать всех этих проблем, используйте функцию и позвольте компилятору оптимизировать ее:
int cube(int x) {
return x * x * x;
}
Вы можете добавить static inline
перед этим определением функции, но современные оптимизаторы все равно будут встраивать функцию без этого.
Препроцессор C буквально заменит все экземпляры x на 4 + 5, в результате получится следующий код:
i = 4+5*4+5*4+5;
(сначала умножение, затем сложение)
вам нужно ввести ввод, например, CUBE((4+5))
если вы хотите добавить числа, а затем отправить их CUBE
. Причина th CUBE(4+5)
в основном расширена до, 4+5*4+5*4+5
поскольку она устанавливает целое 4+5
вместо x
. Итак, 4+5*4+5*4+5
= 4+20+20+5
поскольку сначала идет умножение, а затем их сложение даст 49
.
Определите макрос, как #define CUBE(x) ((x)*(x)*(x))
если бы он на самом деле сначала выполнял (4+5)
операцию для каждого, (x)
а затем выполнял *
операцию.
Другой способ - просто использовать CUBE((4+5))
при вызове макроса, он в основном сначала добавляет два числа и (4+5)
=, 9
а затем делает CUBE(9)
, например:
#include<stdio.h>
#define CUBE(x) (x * x * x)
int main( )
{
printf("%d", CUBE((4+5)));
return 0;
}
Read Modern C , то n1570 проект стандарта C, и документации GCC и GDB и CPP . См. Также этот справочный веб-сайт C.
Вдохновляйтесь существующими проектами с открытым исходным кодом, например, на github или программном обеспечении GNU .
Используя последний компилятор GCC , вызовите его как gcc -Wall -Wextra -g
. Используйте также -C -E
параметры для получения предварительно обработанной формы.
Вас также может заинтересовать расширение statement-expr для GCC.
Вы CUBE(4+5)
это макро-расширено , 4+5*4+5*4+5
которая вычисляется как в 4+(5*4)+(5*4)+5
соответствии с приоритетом операторов C .
Рассмотрим кодирование такой static inline
функции, как
static inline int cube(int x) { return x*x*x; }
или если вам нужен макрос, по крайней мере
#define CUBE(X) ((X)*(X)*(X))
что не будет хорошо работать CUBE(i++)
(в то время как inline
функция cube(i++)
делает то , что вы хотите: увеличивайте i
один раз!).
Кстати, вы можете использовать GPP или GNU m4 (или свой собственный генератор или GNU bison ) для генерации некоторого кода C. Как правило, думайте с помощью AST : когда вы генерируете код C, выдавайте много бесполезных скобок, например, в Chicken Scheme , SWIG , в CAIA или в моем manydl.c
Вы также можете использовать статический анализатор Clang в своем коде (и, возможно, Frama-C ).
Возможно, вам будет интересно прочитать некоторые рекомендации по кодированию, такие как MISRA C или GNU .