정의를 항상 괄호 안에 C로 둘러싸야 하는 타당한 이유가 있습니까?
실히, 끔 clearly clearly가 있는 .#define
스테이트먼트에는 다음과 같은 괄호가 필요합니다.
#define WIDTH 80+20
int a = WIDTH * 2; // expect a==200 but a==120
그래서 항상 괄호 안에 넣었어요.단일 숫자일 때도요.
#define WIDTH (100)
접하는 이 작업을 번호 케이스를 .#define
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
그런 경우가 있나요?
예. 프리프로세서 연결 연산자(##
는 다음과 수 있습니다
#define _add_penguin(a) penguin ## a
#define add_penguin(a) _add_penguin(a)
#define WIDTH (100)
#define HEIGHT 200
add_penguin(HEIGHT) // expands to penguin200
add_penguin(WIDTH) // error, cannot concatenate penguin and (100)
도 .#
에 몰린 이므로, 하면 문제가WIDTH
아마 사용될 것입니다.다만, 프리프로세서에 대해서는 주의할 필요가 있습니다.
(두 번째 펭귄 추가가 실패한 이유는 C99의 전처리 규칙의 미묘한 세부 사항입니다. 두 개의 자리 표시자가 아닌 전처리 토큰에 연결하는 것은 항상 하나의 전처리 토큰을 생성해야 하기 때문에 실패합니다. 그러나 이것은 연결이 허용되더라도 여전히 unbr과 다른 결과를 제공할 것입니다.소켓이 달린#define
다른 모든 응답은 C++ 스캐너의 관점에서 문제가 되지 않는 한 정확합니다.실제로 숫자는 원자적이기 때문입니다.다만, 제가 질문을 읽어 본 결과, 프리프로세서의 확장이 없는 케이스만을 검토해야 한다는 징후는 보이지 않기 때문에, 그 어드바이스에 전적으로 동의하고 있습니다만, 다른 답변은 잘못된 것입니다.
코드가 숫자만 정의하면 @Alexander Gessler는 질문에 잘 답합니다.
그러나 많은 코더는 다음과 같은 단항 연산자를 인식하지 못합니다.
#define TEMPERATURE1M (-1)
#define TEMPERATURE1P (+1)
가 " " " 를 하는 #define
, 「 「」는 「」로 둘러싸여 있다.()
는 예상되는 수치 결과와 우선순위를 보증합니다.
#define TEMPERATURE_WITH (-1)
#define TEMPERATURE_WITHOUT -1
// Consider how these will compile
int w = 10-TEMPERATURE_WITH;
int wo = 10-TEMPERATURE_WITHOUT; // May not compile
코드의 마지막 행은 주어진 C99의 의미 변경 @Olaf를 컴파일할 수 있습니다.
경우에 따라서는 현재의 주의사항이 아닌 다음 주의사항을 고려하여 코드를 작성해야 할 수 있습니다.
현재 매크로는 단일 정수입니다.미래에 누군가가 그것을 편집한다고 상상해 보세요.그들이 당신이 아니라 덜 조심스럽거나 더 급한 사람이라고 합시다.괄호 안에 수정사항을 넣도록 사람들에게 상기시키기 위해 괄호가 있습니다.
이런 생각은 C에서 좋은 습관이다.저는 개인적으로 이런 식으로 '중복'을 느낄 수 있는 스타일로 코드를 작성합니다.특히 에러 처리에 관해서는요.용장성은 향후 편집의 유지 보수성과 컴포지터빌리티를 위한 것입니다.
Blagovest Buyukliev의 말처럼:
정의는 단일 토큰(1개의 오퍼랜드만, 연산자 없음)으로 구성됩니다.단일 토큰(100 등)은 렉스 및 해석 시 분할할 수 없는 원자이기 때문에 괄호는 필요하지 않습니다.
단, 매크로에 관해서는 다음 규칙을 권장합니다.
- Lundin의 코멘트를 참조해 주세요.
매크로와 같은 기능을 사용하는 경우는, 다음의 2개의 룰을 고려해 주세요.
- 매크로의 인수에는 항상 대괄호 사용
- 매크로 인수를 한 번만 사용합니다.
왜 규칙 1.(작업 순서를 올바르게 유지하기 위해)
#define quad(x) (x*x)
int a = quad(2+3);
다음과 같이 전개됩니다.
int a = (2+3*2+3);
왜 규칙 2인가?(부작용을 한 번만 적용하기 위해)
#define quad(x) (x*x)
int i = 1;
int a = quad(i++);
다음과 같이 전개됩니다.
int a = i++ * i++;
부터100
(단일 토큰의 경우) 괄호가 중요한 코너 케이스를 찾을 수 있을지 의문입니다.
토큰이 여러 개 있는 경우 IMO가 중요할 수 있기 때문에 IMO는 여전히 좋은 습관입니다.
정의가 단일 토큰(1개의 오퍼랜드만, 연산자 없음)으로 구성될 경우 단일 토큰(예:100
)는, 렉서링과 해석의 경우에 분할할 수 없는 원자입니다.
아니요. 그런 경우는 없습니다.#define WIDTH 100
모호하지 않거나 "구체적인" 확장이 가능합니다.이는 단일 토큰이 단일 토큰으로 대체되는 결과를 초래할 수 있기 때문입니다.
아시다시피 단일 토큰(예: 토큰)을 사용하면 매크로 혼동이 발생합니다.WIDTH
는 여러 개의 토큰을 생성합니다(예:80 + 20
내가 추측하건대, 그것이 치환에 괄호를 사용하는 유일한 이유이며, 첫 번째 단락에서 설명한 바와 같이 여기에는 해당되지 않는다.
그러나 이 기술적 사실은 차치하고라도 여전히 좋은 관행일 수 있습니다.그것은 습관을 촉진시키고, 만약 그 매크로가 더 복잡한 것으로 수정된다면 상기시켜주는 역할을 한다.
그것은 확실히 아프지 않을 것이고 좋은 습관이다.하지만 다른 점은 없다.(100)
그리고.100
수치 계산을 위해.
가끔은 그럴만한 이유가 있어
숫자 하나로는, 그럴만한 이유가 없어요.
또 다른 경우에는, 당신이 보여준 것처럼, 그럴 만한 이유가 있다.
어떤 사람들은 특별히 조심하기를 선호하고 항상 괄호를 사용한다(@aix가 추천한다).모릅니다만, 어려운 답은 없습니다).
언급URL : https://stackoverflow.com/questions/9081479/is-there-a-good-reason-for-always-enclosing-a-define-in-parentheses-in-c
'programing' 카테고리의 다른 글
vue 경로의 Bootstrap-vue 탭에서 특정 탭으로 이동하는 방법은 무엇입니까? (0) | 2022.07.30 |
---|---|
인스턴스화 시 Vue 인스턴스가 마운트되지 않음 (0) | 2022.07.30 |
TypeError: 정의되지 않은 속성 'rtl'을 읽을 수 없습니다. (0) | 2022.07.30 |
Vuetify v0.17.6: v-select에서 자동 완성 텍스트를 가져오는 방법 (0) | 2022.07.30 |
v-move 클래스를 사용할 때 Vue가 트리거되지 않습니까? (0) | 2022.07.30 |