Вывод этого кода C - 49, но может кто-нибудь объяснить мне, как? [дубликат]

Jan 20 2021
#include <stdio.h>

#define CUBE(x) (x * x * x)

int main() {
    printf("%d", CUBE(4+5));
    return 0;
}

Ответы

5 MarkSouls Jan 20 2021 at 14:31

Макрос превратит код в:

printf("%d", (4+5 * 4+5 * 4+5));

что эффективно:

printf("%d", 4 + (5*4) + (5*4) + 5); // 29

Если хочешь куб 9получить 729, надо писать CUBE((4+5)).

9 chqrlie Jan 20 2021 at 14:34

Вот как макрос раскрывается в процессе компиляции:

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перед этим определением функции, но современные оптимизаторы все равно будут встраивать функцию без этого.

3 Tecto Jan 20 2021 at 14:32

Препроцессор C буквально заменит все экземпляры x на 4 + 5, в результате получится следующий код:

i = 4+5*4+5*4+5;

(сначала умножение, затем сложение)

3 SahadatHossain Jan 20 2021 at 14:31

вам нужно ввести ввод, например, 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;
}
1 BasileStarynkevitch Jan 20 2021 at 14:29

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 .