이 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
. 일 원인 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;
}
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 와 같은 코딩 지침을 읽는 데 관심이있을 수 있습니다 .