#define STR1 "s"
#define STR2 "1"
#define STR3 STR1 ## STR2
STR3 == "s1"을 연결하는 것이 가능합니까? args를 다른 매크로 함수에 전달하여이를 수행 할 수 있습니다. 그러나 직접적인 방법이 있습니까?
#define STR1 "s"
#define STR2 "1"
#define STR3 STR1 ## STR2
STR3 == "s1"을 연결하는 것이 가능합니까? args를 다른 매크로 함수에 전달하여이를 수행 할 수 있습니다. 그러나 직접적인 방법이 있습니까?
답변:
둘 다 문자열이면 다음과 같이 할 수 있습니다.
#define STR3 STR1 STR2
전처리 기는 인접한 문자열을 자동으로 연결합니다.
편집하다:
아래에서 언급했듯이 연결을 수행하는 것은 전처리 기가 아니라 컴파일러입니다.
L"a"
및 "b"
얻을에 L"ab"
,하지만 당신은 할 수 있습니다 연결할 L"a"
및 L"b"
수에 L"ab"
.
문자열 리터럴은 언어 수준에서 연결되기 때문에 이러한 종류의 솔루션이 필요하지 않으며 "s" "1"이 유효한 전 처리기 토큰이 아니기 때문에 어쨌든 작동하지 않습니다.
[편집 : 안타깝게도 여러 개의 찬성표를받은 아래의 잘못된 "Just for the record"주석에 대한 응답으로 위의 설명을 반복하고 프로그램 조각이
#define PPCAT_NX(A, B) A ## B
PPCAT_NX("s", "1")
gcc의 전처리 단계에서 다음 오류 메시지를 생성합니다. 오류 : ""s ""및 ""1 ""붙여 넣기는 유효한 전처리 토큰을 제공하지 않습니다.
]
그러나 일반적인 토큰 붙여 넣기의 경우 다음을 시도하십시오.
/*
* Concatenate preprocessor tokens A and B without expanding macro definitions
* (however, if invoked from a macro, macro arguments are expanded).
*/
#define PPCAT_NX(A, B) A ## B
/*
* Concatenate preprocessor tokens A and B after macro-expanding them.
*/
#define PPCAT(A, B) PPCAT_NX(A, B)
그런 다음 예를 들어 모두 PPCAT_NX(s, 1)
및 PPCAT(s, 1)
식별자를 생성합니다 . 이 경우 매크로로 정의 s1
되지 않는 한 .s
PPCAT(s, 1)
<macro value of s>1
주제에서 계속되는 것은 다음 매크로입니다.
/*
* Turn A into a string literal without expanding macro definitions
* (however, if invoked from a macro, macro arguments are expanded).
*/
#define STRINGIZE_NX(A) #A
/*
* Turn A into a string literal after macro-expanding it.
*/
#define STRINGIZE(A) STRINGIZE_NX(A)
그때,
#define T1 s
#define T2 1
STRINGIZE(PPCAT(T1, T2)) // produces "s1"
대조적으로
STRINGIZE(PPCAT_NX(T1, T2)) // produces "T1T2"
STRINGIZE_NX(PPCAT_NX(T1, T2)) // produces "PPCAT_NX(T1, T2)"
#define T1T2 visit the zoo
STRINGIZE(PPCAT_NX(T1, T2)) // produces "visit the zoo"
STRINGIZE_NX(PPCAT(T1, T2)) // produces "PPCAT(T1, T2)"
"s""1"
C (및 C ++)에서 유효합니다. 컴파일러가 자신을 연결하고 하나의 토큰으로 위협하는 두 개의 토큰 (문자열 리터럴)입니다.
"s""1" isn't a valid token
– 그것은 맞다; 말했듯이 두 개의 토큰입니다. 그러나 ##과 함께 붙이면 두 개의 토큰이 아닌 단일 전처리 토큰이되므로 컴파일러는 연결을 수행하지 않고 어휘 분석기가이를 거부합니다 (언어에는 진단이 필요함).
STRINGIZE_NX(whatever occurs here)
발생, 발생 또는 여기에 대한 매크로 정의에 관계없이 "여기서 발생하는 모든 항목"으로 확장됩니다.
if A is defined as FRED then STRINGIZE_NX(A) still expands to "FRED"
것은 거짓이며 당신의 시험과는 전혀 다릅니다. 당신은 이것을 이해하지 못하거나 옳게하기 위해 열심히 노력하고 있습니다.
힌트 : STRINGIZE
위 의 매크로는 멋지지만 실수하고 인수가 매크로가 아닌 경우 (이름에 오타가 있거나 #include
헤더 파일을 잊어 버린 경우) 컴파일러가 의도 한 매크로 이름을 오류가없는 문자열.
인수 STRINGIZE
가 항상 정상적인 C 값을 가진 매크로가 되도록하려면
#define STRINGIZE(A) ((A),STRINGIZE_NX(A))
한 번 확장하고 유효성을 확인하고 폐기 한 다음 다시 문자열로 확장합니다.
대신 ... 내가 포함하지 않은 STRINGIZE(ENOENT)
것처럼 끝나는 이유 를 알아내는 데 시간이 좀 걸렸 습니다 ."ENOENT"
"2"
errno.h
,
운영자의 적절한 사용을 위해 +1 . :)
((1),"1") "." ((2),"2")
"1" "." "2"대신에 같은 시퀀스로
STRINGIZE
정의에서는 "The value of ENOENT is " STRINGIZE(ENOENT)
작동하지만 "The value of ENOENT is" STRINGIZE_EXPR(X)
오류가 발생합니다.