이 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. 일 원인 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

Modern C , n1570 Draft C 표준, GCC 및 GDB 및 CPP 문서를 읽으십시오 . 이 C 참조 웹 사이트를 참조 하십시오 .

github 또는 GNU 소프트웨어 와 같은 기존 오픈 소스 프로젝트에서 영감을 얻습니다 .

최근으로 GCC의 컴파일러 를 호출 로 gcc -Wall -Wextra -g. -C -E옵션을 사용 하여 전처리 된 양식을 가져 오십시오.

GCC 의 statement-expr 확장에 관심이있을 수도 있습니다 .

하신 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한 번 증가하십시오 !).

BTW, GPP 또는 GNU m4 (또는 자체 생성기 또는 GNU bison )를 사용하여 C 코드를 생성 할 수 있습니다. 경험상 AST로 생각하십시오 . C 코드를 생성 할 때, 예를 들어 Chicken Scheme , SWIG 또는 CAIA 또는 my manydl.c 에서 와 같이 쓸모없는 괄호를 많이 내 보냅니다.

코드에 Clang 정적 분석기 를 사용할 수도 있습니다 (그리고 Frama-C ).

MISRA C 또는 GNU 와 같은 코딩 지침을 읽는 데 관심이있을 수 있습니다 .