sizeof
삼항 연산자를 사용 하는 연산자 에 대한 작은 코드 조각이 있습니다 .
#include <stdio.h>
#include <stdbool.h>
int main()
{
bool a = true;
printf("%zu\n", sizeof(bool)); // Ok
printf("%zu\n", sizeof(a)); // Ok
printf("%zu\n", sizeof(a ? true : false)); // Why 4?
return 0;
}
출력 ( GCC ) :
1
1
4 // Why 4?
하지만 여기는,
printf("%zu\n", sizeof(a ? true : false)); // Why 4?
삼항 연산자는 boolean
유형을 반환 하고 sizeof bool
유형은 1
C의 바이트입니다.
그렇다면 왜 sizeof(a ? true : false)
4 바이트의 출력을 제공합니까?
답변
당신이 있기 때문 #include <stdbool.h>
입니다. 그 헤더 를 정의 매크로 true
와는 false
할 수 1
와 0
,이 같은 명세서의 외모 때문에 :
printf("%zu\n", sizeof(a ? 1 : 0)); // Why 4?
sizeof(int)
귀하의 플랫폼에서 4입니다.
답변
여기서 삼항 연산자 반환
boolean
유형은
좋아, 그 이상이 있습니다!
C 에서이 삼항 연산 의 결과 는 유형 int
입니다. [아래 참고 사항 (1,2)]
따라서 결과는 sizeof(int)
플랫폼 에서 식과 동일 합니다.
참고 1 : 인용 C11
, §7.18,Boolean type and values <stdbool.h>
[….] 나머지 3 개의 매크로는
#if
전처리 지시문 에 사용하기에 적합 합니다. 그들은
true
정수 상수 1로 확장됩니다.
false
정수 상수 0으로 확장되는 [….]
참고 2 : 조건부 연산자의 경우 §6.5.15 장 ( 강조 표시 )
첫 번째 피연산자가 평가됩니다. 평가와 두 번째 또는 세 번째 피연산자 (둘 중 평가되는 것)의 평가 사이에 시퀀스 지점이 있습니다. 두 번째 피연산자는 첫 번째 피연산자가 0과 같지 않은 경우에만 평가됩니다. 세 번째 피연산자는 첫 번째 피연산자가 0과 동일한 경우에만 평가됩니다. 결과는 두 번째 또는 세 번째 피연산자 (둘 중 평가되는 것)의 값입니다. […]
과
두 번째와 세 번째 피연산자 모두 산술 유형을 갖는 경우 일반적인 산술 변환에 의해 결정되는 결과 유형은 두 피연산자에 적용되었으므로 결과 유형입니다. [….]
따라서 결과는 정수 유형이며 값 범위 때문에 상수는 정확하게 유형 int
입니다.
즉, 일반적인 조언 int main()
은 int main (void)
진정으로 표준을 준수하는 것이 좋습니다.
답변
삼항 연산자는 빨간 청어입니다.
printf("%zu\n", sizeof(true));
4를 인쇄합니다 (또는 sizeof(int)
플랫폼에있는 것).
다음은 크기가 1 인 bool
동의어 char
또는 유사한 유형 int
이며보다 큼을 가정합니다 char
.
이유 sizeof(true) != sizeof(bool)
와 이유 sizeof(true) == sizeof(int)
는 단순히 유형의 표현 true
이 아니기 때문 입니다bool
. 유형의 표현식입니다 int
. 이것은된다 #define
로서 거라고 1
에서 stdbool.h
.
편집 :이 단락은 사실이 아니며, 인수로 bool
C 에는 유형의 r 값이 전혀 없습니다 . 에 int
대한 인수로 사용되는 경우에도 이러한 모든 rvalue는 즉시로 승격 됩니다 sizeof
. sizeof
승격되지 않습니다 int
. 이것은 결론에 영향을 미치지 않습니다.
답변
C의 부울 유형에 대해
부울 형식은 1999 년 C 언어에서 상당히 늦게 소개되었습니다. 그 전에 C에는 부울 형식이 없었지만 대신 int
모든 부울 식에 사용 되었습니다. 따라서 > == !
etc 와 같은 모든 논리 연산자 는 int
의 값 1
또는0
.
응용 프로그램에서와 같은 집에서 만든 유형을 사용하는 것은 사용자 지정이었으며 typedef enum { FALSE, TRUE } BOOL;
,이 int
유형 은 크기가 큰 유형으로 분류됩니다.
C ++는 bool
1 바이트보다 크지 않은 훨씬 나은 명시 적 부울 형식을 가졌습니다 . C의 부울 유형 또는 표현식은 최악의 경우 4 바이트로 끝납니다. C ++와의 호환성 방식은 C에서 C99 표준으로 도입되었습니다. 그런 다음 C는 부울 유형 _Bool
과 헤더를 얻습니다 stdbool.h
.
stdbool.h
C ++과의 호환성을 제공합니다. 이 헤더는 bool
확장 가능한 매크로 (C ++ 키워드와 동일한 철자)를 정의합니다.이 _Bool
정수는 1 바이트의 큰 정수형 유형입니다. 마찬가지로 헤더는 두 개의 매크로 true
와 false
C ++ 키워드와 같은 철자를 제공 하지만 이전 C 프로그램과의 하위 호환성을 제공 합니다. 따라서 true
과 false
에 확장 1
및 0
C와 자신의 유형입니다int
. 이러한 매크로는 실제로 해당 C ++ 키워드와 같은 부울 유형이 아닙니다.
마찬가지로, 이전 버전과의 호환성을 위해, C의 논리 연산자는 여전히 를 반환 int
C는 현재 부울 타입을 가지고에도 불구하고, 오늘날까지. C ++에서 논리 연산자는을 반환합니다 bool
. 따라서와 같은 표현식 은 C sizeof(a == b)
의 크기를 제공 int
하지만 bool
C ++ 의 크기는 제공합니다 .
조건부 연산자에 대하여 ?:
조건부 연산자 ?:
는 몇 가지 단점이있는 이상한 연산자입니다. 100 %에 해당한다고 생각하는 것은 흔한 실수 if() { } else {}
입니다. 좀 빠지는.
첫 번째와 두 번째 또는 세 번째 피연산자의 평가 사이에는 시퀀스 지점이 있습니다. ?:
에만 두번째 또는 세번째 피연산자 중 하나를 평가하는이 평가되지 않습니다 피연산자의 부작용을 실행할 수 있도록 운영자가 보장됩니다. 같은 코드 true? func1() : func2()
는 실행되지 않습니다 func2()
. 여태까지는 그런대로 잘됐다.
그러나 일반적인 산술 변환 을 통해 두 번째와 세 번째 피연산자가 암시 적으로 형식을 승격하고 균형을 이루어야한다는 특수 규칙이 있습니다. ( C의 암시 적 유형 승격 규칙은 여기에 설명되어 있습니다 ). 이것은 두 번째 또는 세 번째 피연산자가 항상 최소한 int
.
그것은 그 문제되지 않도록 true
및 false
유형 될 일이 int
표현은 항상 적어도의 크기를주지 않기 때문에 C에 int
상관없이.
표현식을 다시 쓰더라도 여전히 !sizeof(a ? (bool)true : (bool)false)
int
이는 일반적인 산술 변환을 통한 암시 적 유형 승격 때문입니다.
답변
빠른 답변 :
sizeof(a ? true : false)
로 평가4
하기 때문에true
과false
에 정의<stdbool.h>
로1
하고0
, 각각에 식 팽창하므로sizeof(a ? 1 : 0)
유형의 정수 표현되는int
플랫폼에 4 바이트를 차지합니다. 같은 이유로 시스템sizeof(true)
에서도 평가4
합니다.
그러나 다음 사항에 유의하십시오.
-
sizeof(a ? a : a)
또한4
삼항 연산자가 정수 표현식 인 경우 두 번째 및 세 번째 피연산자에서 정수 승격을 수행 하기 때문에 평가됩니다 . 물론 동일에 대한 발생sizeof(a ? true : false)
하고sizeof(a ? (bool)true : (bool)false)
있지만, 같은 전체 표현식 캐스팅bool
예상대로 동작합니다을 :sizeof((bool)(a ? true : false)) -> 1
. -
또한 비교 연산자는 부울 값
1
또는로 평가0
되지만int
유형은 다음과 같습니다sizeof(a == a) -> 4
.
부울 특성을 유지하는 유일한 연산자 a
는 다음과 같습니다.
-
쉼표 연산자 : 모두
sizeof(a, a)
와sizeof(true, a)
로 평가1
컴파일시. -
대입 연산자 :
sizeof(a = a)
및sizeof(a = true)
의 값은 모두 입니다1
. -
증분 연산자 :
sizeof(a++) -> 1
마지막으로 위의 모든 내용은 C에만 적용됩니다. C ++에는 bool
유형, 부울 값 true
및 false
비교 연산자 및 삼항 연산자와 관련하여 다른 의미 가 있습니다. 이러한 모든 sizeof()
표현식 1
은 C ++에서 평가됩니다 .
답변
다음은 소스에 포함 된 스 니펫입니다.
#ifndef __cplusplus
#define bool _Bool
#define true 1
#define false 0
#else /* __cplusplus */
매크로가 true
있으며 false
각각 1과 0으로 선언됩니다.
그러나이 경우 유형은 리터럴 상수의 유형입니다. 0과 1은 모두 정수에 맞는 정수 상수이므로 유형은 정수입니다.
그리고 sizeof(int)
귀하의 경우는 4입니다.
답변
C에는 부울 데이터 형식이 없다, 대신 논리적 인 표현은 정수 값으로 평가 1
하는 경우는 true, 그렇지 않은0
.
조건식이 좋아 if
, for
, while
, 또는 c ? a : b
수는 간주 제로가 아닌 경우, 정수를 기대하는 true
특별한 경우를 제외하고, 여기 삼항 연산자가 평가하게하는 재귀 sum 함수의 true
때까지 n
손이 닿지 0
.
int sum (int n) { return n ? n+sum(n-1) : n ;
NULL
포인터 를 확인하는 데 사용할 수도 있습니다 . 여기에는 Singly-Linked-List의 내용을 인쇄하는 재귀 함수가 있습니다.
void print(sll * n){ printf("%d -> ",n->val); if(n->next)print(n->next); }