char은 기본적으로 서명 또는 서명되지 않습니까?


158

"C의 완전한 참조"책 char에서 기본적으로 서명되지 않은 것으로 언급되어있다 .

그러나 Visual Studio뿐만 아니라 GCC로 이것을 확인하려고합니다. 기본적 으로 서명 된 것으로 간주 합니다.

어느 것이 맞습니까?


5
내가 신뢰하는 하나의 C 레퍼런스 북은 Harbison & Steele의 "C : A Reference Manual"( careferencemanual.com )입니다. 물론 표준은 최종 단어이지만, 읽기 쉽지는 않으며 표준 이외의 사전 표준 및 일반 (예 : POSIX) 사용에 대한 정보를 조금만 제공합니다. Harbison & Steele은 읽기 쉽고 상세하며 아마도 대부분의 참조보다 정확합니다. 그러나 그것은 또한 튜토리얼이 아니므로 학습의 초기 단계에 있다면 뛰어 들기에는 좋지 않을 것입니다.
— Michael Burr

15
나는 당신이 읽고있는 책이 Herbert Schildt의 C : The Complete Reference 라고 생각합니다 . 이 책에 대한 리뷰 ( accu.informika.ru/accu/bookreviews/public/reviews/c/c002173.htm ) : 나는이 책을 추천하지 않을 것입니다 (너무 많은 사람들이 내 의견에 너무 많은 비중을 두었습니다 ). 나는 그것이 그의 다른 일에 합법적으로 던져진 것과 같은 opprobrium을받을 가치가 있다고 생각하지 않습니다. Michael이 말했듯이 훨씬 나은 참조는 Harbison & Steele 입니다.
— Alok Singhal

내 두 센트 : char서명 할 수 없으므로 일반적으로을 사용하여을 사용하여 int값을 읽으면을 getchar()반환 할 수 있습니다 EOF. EOF은 일반적으로 -1또는 다른 음수 값 으로 정의되며 unsigned원하는 저장 값 이 아닙니다. 선언은 다음과 같습니다. extern int getchar();BTW,이 권장 사항은 "C : A Reference Manual"책에서도 제공됩니다.
— Maxim Chetrusca

6
내가 신뢰하는 C 참조는 ISO / IEC 9899 : 2011 :-)
— Jeff

3
@MaxChetrusca의 좋은 조언이지만 나쁜 근거 : 서명 된 char경우 에도 int반환 값을 저장하는 데 사용해야 합니다.
— Antti Haapala

답변:


204

책이 잘못되었습니다. 표준은 일반 char서명 여부를 지정하지 않습니다 .

실제로이 표준은 세 가지 유형 char인 signed char, 및을 정의합니다 unsigned char. 당신 #include <limits.h>을 본 다음 CHAR_MIN일반 char을 signed보거나 unsigned( CHAR_MIN0보다 작거나 0과 같은 경우 ) 알 수 있지만 세 가지 유형은 표준과 관련하여 구별 됩니다.

char이런 식으로 특별 하다는 점에 유의하십시오 . 변수를로 선언하면 int100 %에 해당하는 것으로 선언됩니다 signed int. 이것은 모든 컴파일러와 아키텍처에 항상 해당됩니다.


1
@ Alok : 다른 데이터 유형의 경우도 마찬가지입니다. 예를 들어 항상 int의미합니다 signed int. 을 제외하고 char어떤 다른 데이터 유형에 동일한 혼동이 C있습니까?
— Lazer

8
@eSKay : 예, char서명하거나 서명 할 수없는 유일한 유형입니다. int동등 signed int예.
— Alok Singhal

28
C의 초기에는 "표준"이 적어도 두 번 플립 플롭되었고 일부 인기있는 초기 컴파일러는 다른 방식으로 끝났다.
— 핫 릭

9
@AlokSinghal : 또한 비트 유형의 비트 필드에 int부호가 있거나 부호가 없는지 여부를 정의하여 구현합니다 .
— Keith Thompson

@KeithThompson 수정 해 주셔서 감사합니다. 비트 필드 유형을 많이 사용하지 않기 때문에 비트 필드 유형에 대한 세부 정보를 잊어 버리는 경향이 있습니다.
— Alok Singhal

67

로 알록 지적 , 표준 잎 구현에 그.

gcc의 경우 기본값은 부호가 있지만를 사용하여 수정할 수 있습니다 -funsigned-char. 참고 : Android NDK의 gcc의 경우 기본값은 unsigned 입니다. 로 서명 된 문자를 명시 적으로 요청할 수도 있습니다 -fsigned-char.

MSVC에서 기본값은 부호가 있지만를 사용하여 수정할 수 있습니다 /J.


2
그의 책은 대개 MSVC 사용자를 대상으로하기 때문에 Schildt의 설명이 MSVC의 동작과 일치하지 않는다는 점에 흥미가 있습니다. MS가 어느 시점에서 기본값을 변경했는지 궁금합니다.
— Michael Burr

1
컴파일러에 의존하지 않고 플랫폼에 의존한다고 생각했습니다. 나는 char가 당시의 시스템이 인쇄 가능한 문자로 사용하는 것을 준수하기 위해 "문자 데이터 유형"의 세 번째 유형으로 남아 있다고 생각했습니다.
— Spidey

10
GCC 문서 는 기계 의존적이라고 말한다 : " 각 종류의 기계는 기본적으로 부호가없는 문자 나 기본적으로 부호가있는 문자와 비슷하다. "
— Deduplicator

1
안드로이드에서 기본값은 서명되지 않은 문자라는 메모 소스를 제공 할 수 있습니까?
— phlipsy

1
@Spidey C 표준은 컴파일러, 플랫폼 및 CPU 아키텍처를 실제로 구분하지 않습니다. 그것은 단지 "구현"하에서 그들 모두를한데 묶습니다.
— plugwash

35

C99 N1256 draft 6.2.5 / 15 "Types"에는 다음과 같이 형식의 부호가 있습니다 char.

구현시 char을 signed char 또는 unsigned char와 동일한 범위, 표현 및 동작을 갖도록 정의해야합니다.

각주 :

CHAR_MIN에 정의 된 <limits.h>, 0또는 값 중 하나 SCHAR_MIN를 가지며이 옵션을 사용하여 두 옵션을 구별 할 수 있습니다. 선택에 관계없이 char다른 두 가지 유형과 별개이며 두 가지 유형과 호환되지 않습니다.


7

ANSI C의 사실상의 표준 책인 Dennis Ritchie의 C Programming Language book에 따르면 부호가 있거나 부호가없는 일반 문자는 기계에 따라 다르지만 인쇄 가능한 문자는 항상 양수입니다.


9
그것은 반드시 그 그렇지 않다 인쇄 가능한 문자는 항상 긍정적이다. C 표준은 기본 실행 문자 세트의 모든 멤버가 음이 아닌 값을 갖도록 보장합니다.
— Keith Thompson

7

C 표준에 따르면 일반 문자의 서명은 "구현 정의"입니다.

일반적으로 구현자는 아키텍처에서 구현하기에 더 효율적인 것을 선택했습니다. x86 시스템에서 char은 일반적으로 서명됩니다. arm 시스템에서는 일반적으로 서명되지 않습니다 (Apple iOS는 예외).



2
@plugwash Tim Post가 열쇠를 잃어 버렸기 때문에 답이 다운 보트되었을 것입니다 . 진지하게, 당신은 당신의 대답이 정확하다고 확신하는 한 (이 경우에 맞는) 단일 공감대에 대해 걱정해서는 안됩니다. 정당한 이유없이 내 게시물을 다운 보트하는 것이 여러 번 발생했습니다. 걱정하지 마십시오. 때로는 사람들이 이상한 일을합니다.
— Donald Duck

1
x86에서 서명 된 문자가 더 효율적인 이유는 무엇입니까? 어떤 소스?
— martinkunev

2

Bjarne Stroustrup의 "C ++ 프로그래밍 언어"에 따르면 char"구현 정의"입니다. 그것은 할 수 있습니다 signed char또는 unsigned char구현에 따라. char를 사용하여 서명 여부를 확인할 수 있습니다 std::numeric_limits<char>::is_signed.


9
이것은 C 질문입니다. C ++은 다른 언어이며 C ++ 참조는 C와 관련이 없습니다.
— MM

1

이제 우리는 표준이 구현에 달려 있음을 알고 있습니다.

그러나 어떻게 유형이 확인 signed또는 unsigned같은 char?

나는 이것을하기 위해 매크로를 썼다 :

#define IS_UNSIGNED(t) ((t)~1 > 0)

와 함께 테스트 gcc, clang및 cl. 그러나 다른 경우에는 항상 안전한지 확실하지 않습니다.


일반적인 CHAR_MIN <0 (또는 wchar_t의 경우 WCHAR_MIN <0)에 어떤 문제가 있습니까?
— Öö Tiib
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.