[c] “sizeof (a? true : false)”가 4 바이트의 출력을 제공하는 이유는 무엇입니까?

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유형은 1C의 바이트입니다.

그렇다면 sizeof(a ? true : false)4 바이트의 출력을 제공합니까?



답변

당신이 있기 때문 #include <stdbool.h>입니다. 그 헤더 를 정의 매크로 true 와는 false할 수 10,이 같은 명세서의 외모 때문에 :

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.

boolC 에는 유형의 r 값이 전혀 없습니다 . 에 int대한 인수로 사용되는 경우에도 이러한 모든 rvalue는 즉시로 승격 됩니다 sizeof. 편집 :이 단락은 사실이 아니며, 인수로 sizeof승격되지 않습니다 int. 이것은 결론에 영향을 미치지 않습니다.


답변

C의 부울 유형에 대해

부울 형식은 1999 년 C 언어에서 상당히 늦게 소개되었습니다. 그 전에 C에는 부울 형식이 없었지만 대신 int모든 부울 식에 사용 되었습니다. 따라서 > == !etc 와 같은 모든 논리 연산자 는 int의 값 1또는0 .

응용 프로그램에서와 같은 집에서 만든 유형을 사용하는 것은 사용자 지정이었으며 typedef enum { FALSE, TRUE } BOOL;,이 int유형 은 크기가 큰 유형으로 분류됩니다.

C ++는 bool1 바이트보다 크지 않은 훨씬 나은 명시 적 부울 형식을 가졌습니다 . C의 부울 유형 또는 표현식은 최악의 경우 4 바이트로 끝납니다. C ++와의 호환성 방식은 C에서 C99 표준으로 도입되었습니다. 그런 다음 C는 부울 유형 _Bool과 헤더를 얻습니다 stdbool.h.

stdbool.hC ++과의 호환성을 제공합니다. 이 헤더는 bool확장 가능한 매크로 (C ++ 키워드와 동일한 철자)를 정의합니다.이 _Bool정수는 1 바이트의 큰 정수형 유형입니다. 마찬가지로 헤더는 두 개의 매크로 truefalseC ++ 키워드와 같은 철자를 제공 하지만 이전 C 프로그램과의 하위 호환성을 제공 합니다. 따라서 truefalse에 확장 10C와 자신의 유형입니다int . 이러한 매크로는 실제로 해당 C ++ 키워드와 같은 부울 유형이 아닙니다.

마찬가지로, 이전 버전과의 호환성을 위해, C의 논리 연산자는 여전히 를 반환 intC는 현재 부울 타입을 가지고에도 불구하고, 오늘날까지. C ++에서 논리 연산자는을 반환합니다 bool. 따라서와 같은 표현식 은 C sizeof(a == b)의 크기를 제공 int하지만 boolC ++ 의 크기는 제공합니다 .

조건부 연산자에 대하여 ?:

조건부 연산자 ?:는 몇 가지 단점이있는 이상한 연산자입니다. 100 %에 해당한다고 생각하는 것은 흔한 실수 if() { } else {}입니다. 좀 빠지는.

첫 번째와 두 번째 또는 세 번째 피연산자의 평가 사이에는 시퀀스 지점이 있습니다. ?:에만 두번째 또는 세번째 피연산자 중 하나를 평가하는이 평가되지 않습니다 피연산자의 부작용을 실행할 수 있도록 운영자가 보장됩니다. 같은 코드 true? func1() : func2()는 실행되지 않습니다 func2(). 여태까지는 그런대로 잘됐다.

그러나 일반적인 산술 변환 을 통해 두 번째와 세 번째 피연산자가 암시 적으로 형식을 승격하고 균형을 이루어야한다는 특수 규칙이 있습니다. ( C의 암시 적 유형 승격 규칙은 여기에 설명되어 있습니다 ). 이것은 두 번째 또는 세 번째 피연산자가 항상 최소한 int.

그것은 그 문제되지 않도록 truefalse유형 될 일이 int표현은 항상 적어도의 크기를주지 않기 때문에 C에 int상관없이.

표현식을 다시 쓰더라도 여전히 !sizeof(a ? (bool)true : (bool)false) int

이는 일반적인 산술 변환을 통한 암시 적 유형 승격 때문입니다.


답변

빠른 답변 :

  • sizeof(a ? true : false)로 평가 4하기 때문에 truefalse에 정의 <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유형, 부울 값 truefalse비교 연산자 및 삼항 연산자와 관련하여 다른 의미 가 있습니다. 이러한 모든 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); }