서명되지 않은 문자 란 무엇입니까?


479

C / C ++에서 어떤 unsigned char용도로 사용됩니까? 일반과 char어떻게 다릅니 까?

답변:


548

C ++에는 세 가지 고유 한 문자 유형이 있습니다.

  • char
  • signed char
  • unsigned char

text 문자 유형을 사용하는 경우 규정되지 않은 char다음을 사용하십시오 .

  • 이 같은 문자 리터럴의 유형 'a'이나 '0'.
  • C 문자열을 구성하는 유형입니다. "abcde"

또한 숫자 값으로도 작동하지만 해당 값이 부호있는 것으로 처리되는지 또는 부호없는 것으로 처리되는지는 지정되지 않습니다. 불평등을 통한 문자 비교에주의하십시오. ASCII (0-127)로 제한하면 안전합니다.

문자 유형을 숫자 로 사용하는 경우 다음을 사용하십시오.

  • signed char이 어댑터를 제공 적어도 -127 127 범위에서 동작한다. (-128 ~ 127이 일반적 임)
  • unsigned char, 최소 0 ~ 255 범위를 제공합니다.

"적어도"C ++ 표준은 각 숫자 유형이 포함하는 데 필요한 최소 범위의 값만 제공하기 때문입니다. sizeof (char)1은 1 (즉, 1 바이트)이어야하지만 이론적으로 바이트는 예를 들어 32 비트 일 수 있습니다. sizeof여전히 그 크기를보고1 있습니다 sizeof (char) == sizeof (long) == 1.


4
분명히하기 위해 32 비트 문자와 32 비트 정수를 가질 수 있고 sizeof (int)! = sizeof (char)? 나는 표준이 sizeof (char) == 1이라고 말하지만, 실제 크기 차이 또는 범위 차이를 기준으로 상대 sizeof (int)입니까?
Joseph Garvin

14
+1. 그러나 C ++에는 4 가지 고유 한 문자 유형이 있으며 wchar_t는 그 중 하나입니다.
Eric Z

11
C ++ 11부터는 char, signed char, unsigned char, wchar_t, char16_t, char32_t의 6 가지 유형이 있습니다.
marcinj

12
@unheilig sizeof함수가 아니라 연산자이므로 공백을 두는 것이 일반적 입니다. 변수의 크기를 취할 때 괄호를 생략하는 것이 더 나은 스타일입니다. sizeof *p또는 sizeof (int). 이것은 타입이나 변수에 적용되면 빠르게 명확 해집니다. 마찬가지로 뒤에 괄호를 붙여도 중복됩니다 return. 기능이 아닙니다.
Patrick Schlüter

3
" char:이 같은 문자 리터럴의 유형 'a'이나 '0'." C ++에서는 true이지만 C는 아닙니다. C에서는 'a'입니다 int.
chux-복원 Monica Monica

92

C 표준은의 부호를 정의하지 않으므로 구현에 따라 다릅니다 char. 플랫폼에 따라 char은 signed또는 unsigned일 수 있으므로 구현에 따라 달라 signed char지거나 명시 적으로 요청해야 unsigned char합니다. 그냥 사용 char하면 문자열에서 문자를 표현하려는 경우 문자열에 어떤 플랫폼 둔다 일치합니다이 같은.

의 차이 signed char와는 unsigned char예상대로입니다. 대부분의 플랫폼에 signed char이르기까지 8 비트 2의 보수 것 -128까지 127, 그리고 unsigned char(8 비트 부호없는 정수가됩니다 0255). 표준은 char유형에 8 비트가 필요하지 않으며 그 sizeof(char)반환 만 필요합니다 1. 당신과 함께 문자의 비트 수에서 얻을 수 있습니다 CHAR_BIT에서 limits.h. 그러나 오늘날 이외의 플랫폼이있는 플랫폼은 거의 없습니다 8.

이 문제에 대한 좋은 요약이 여기에 있습니다 .

나는이 게시 된 이후 다른 언급, 당신은 사용하는 것이 더 낫다 int8_t그리고 uint8_t당신이 정말로 작은 정수를 표현하려면.


2
서명 문자는 -128에서 127까지하지, -127 ~ 127의 최소 범위가
12,431,234,123,412,341,234,123

3
@ 12431234123412341234123 : 기술적으로 C 표준은 -127 ~ 127을 최소 범위로 정의합니다. 그래도 2의 보수 산술을 사용하지 않는 플랫폼을 찾는 것이 좋습니다. 거의 모든 최신 플랫폼에서 실제 서명 된 문자 범위는 -128 ~ 127입니다.
Todd Gamblin

CHAR_BIT표준에 따라 8 비트 이상이어야합니다.
martinkunev

39

나는 그것이 실제로 필요하다고 생각하기 때문에 C와 C ++의 규칙을 말하고 싶습니다 (이 점에서 동일합니다). 첫째, 부호없는 char 객체가 있으면 값을 결정하는 데 모든 비트unsigned char참여합니다. 둘째, unsigned char서명되지 않은 것으로 명시 적으로 언급됩니다.

이제 -1int 유형 의 값을로 변환 할 때 발생하는 일에 대해 누군가와 토론 했습니다 unsigned char. 그는 unsigned char부호 표현에 대해 걱정했기 때문에 결과 에 모든 비트가 1로 설정되어 있다는 아이디어를 거부했습니다 . 그러나 그는 필요하지 않습니다. 이 규칙에서 즉시 전환이 의도 한대로 수행됩니다.

새 유형에 부호가없는 경우 값이 새 유형의 범위에 올 때까지 새 유형에 표시 될 수있는 최대 값보다 하나 이상을 반복적으로 더하거나 빼서 값이 변환됩니다. ( 6.3.1.3p2C99 초안에서)

그것은 수학적 설명입니다. C ++은 모듈러스 미적분학으로 설명하며 동일한 규칙을 산출합니다. 어쨌든, 보장 되지 않는 것은 정수의 모든 비트 -1가 변환 전에 하나라는 것입니다. 결과적 unsigned char으로 모든 CHAR_BIT비트가 1로 바뀌 었다고 주장 할 수 있습니까?

  1. 모든 비트는 값을 결정하는 데 참여합니다. 즉, 객체에서 패딩 비트가 발생하지 않습니다.
  2. 한 번만 추가 UCHAR_MAX+1하는 -1즉, 범위의 값을 얻을 것입니다UCHAR_MAX

실제로 충분합니다! 따라서 unsigned char모든 비트 를 갖기를 원할 때마다

unsigned char c = (unsigned char)-1;

또한 변환은 단순히 고차 비트를 절단 하는 것이 아닙니다 . 2의 보수에 대한 운이 좋은 사건 은 그것이 단지 잘림이라는 것이지만 다른 부호 표현에 대해서도 반드시 같은 것은 아닙니다.


2
왜 사용하지 UCHAR_MAX않습니까?
Nicolás

1
(unsigned type)-1어떤 종류의 관용구 이기 때문 입니다. ~0그렇지 않습니다.
Patrick Schlüter

1
나는이 같은 경우 int x = 1234char *y = &x. 이진 표현은 1234 입니다 00000000 00000000 00000100 11010010. 내 컴퓨터는 리틀 엔디안이므로 리버스하여 메모리에 저장 11010010 00000100 00000000 00000000합니다. LSB가 우선입니다. 이제 주요 부분. 내가 사용하는 경우 printf("%d" , *p). printf첫 번째 바이트를 읽하는 11010010경우에만 출력은 -46있지만 11010010입니다 210그것은 인쇄 않습니다 왜 그렇게 -46. 정수 혼란에 약간의 문자가 뭔가를하고 있다고 생각하지만 모르겠습니다.
Suraj Jain

27

예를 들어 unsigned char의 사용법 :

unsigned char컴퓨터 그래픽에 자주 사용되며, 각 색상 구성 요소에 단일 바이트를 할당하는 경우가 종종 있습니다. RGB (또는 RGBA) 색상이 각각 24 비트 (또는 32 비트)로 표시되는 것이 일반적 unsigned char입니다. 이후 unsigned char값 범위는 [0,255]으로 하강 값은 일반적으로 해석된다 :

  • 0은 주어진 색상 구성 요소의 전체 부족을 의미합니다.
  • 255는 주어진 색소의 100 %를 의미합니다.

따라서 RGB 빨강은 (255,0,0)-> (100 % 빨강, 0 % 초록, 0 % 파랑)로 끝납니다.

왜 사용하지 signed char않습니까? 산술 및 비트 이동이 문제가됩니다. 이미 설명했듯이 signed char의 범위는 기본적으로 -128만큼 이동합니다. RGB를 그레이 스케일로 변환하는 매우 단순하고 순진한 (대부분 사용하지 않는) 방법은 세 가지 색상 구성 요소를 모두 평균화하는 것이지만 색상 구성 요소의 값이 음수이면 문제가 발생합니다. unsigned char산술을 사용할 때 빨강 (255, 0, 0)의 평균은 (85, 85, 85) 입니다. 그러나 값이 signed chars (127, -128, -128) 인 경우 unsigned char공간 에서 (29, 29, 29) 인 (-99, -99, -99)로 끝나게됩니다. .


13

문자를 작은 정수로 사용하려면 가장 안전한 방법은 int8_tuint8_t유형을 사용하는 것입니다.


2
안 좋은 생각이 : int8_tuint8_t바이트 크기가 정확히 8 비트없는 경우에는 옵션 및 아키텍처에 정의되지 않습니다. 반대로, signed char그리고 unsigned char항상 적어도 8 비트 가능한 길게 보장됩니다. 일반적인 방법 일 수도 있지만 가장 안전한 방법은 아닙니다 .
chqrlie

2
이것은 의견이며 질문에 대답하지 않습니다.
룬딘

@chqrlie 따라서 메모리를 절약하려면 작은 정수를 나타내는 가장 안전한 방법은 signed charunsigned char? 를 유지하는 것입니다 . 아니면 그 특정한 경우에 더 나은 "safer"대안을 추천 하시겠습니까? "진짜"정수 타입과 스틱 예를 들어 signed intunsigned int대신 어떤 이유로?
RobertS는 Monica Cellio를 지원합니다.

@ RobertS-ReinstateMonica : 모든 호환 구현을 사용 signed char하고 unsigned char이식 가능하며 저장 공간을 절약하지만 코드 크기가 약간 증가 할 수 있습니다. 어떤 경우에는 작은 값을 비트 필드 또는 일반 정수 유형의 단일 비트에 저장하여 더 많은 저장 공간을 절약 할 수 있습니다. 이 질문에 대한 절대적인 대답은 없으며,이 접근 방식의 적절성은 현재 상황에 따라 다릅니다. 그리고이 답변은 어쨌든 문제를 다루지 않습니다.
chqrlie

10

unsigned char0 에서 255 사이의 양수 값만 사용합니다.

어디서

signed char-128 ~ +127 과 같이 양수 값과 음수 값을 모두 사용합니다.


9

char그리고 unsigned char모든 8 비트 유형을 보장하지 않는 플랫폼 - 그들은 8 비트 이상을 보장한다. 일부 플랫폼에는 9 비트, 32 비트 또는 64 비트 바이트가 있습니다. 그러나 오늘날 가장 일반적인 플랫폼 (Windows, Mac, Linux x86 등)에는 8 비트 바이트가 있습니다.


8

signed char범위는 -128 ~ 127입니다. unsigned char범위는 0 ~ 255입니다.

char 컴파일러에 따라 부호있는 문자 또는 부호없는 문자와 동일하지만 고유 한 유형입니다.

C 스타일 문자열을 사용하는 경우을 사용하십시오 char. 산술에 문자를 사용해야하는 경우 (꽤 드문 경우) 이식성을 위해 명시 적으로 부호있는 또는 부호없는 것을 지정하십시오.


8

An unsigned char은 부호없는 바이트 값 (0 ~ 255)입니다. 당신은 char"캐릭터"라는 관점에서 생각할 수도 있지만 실제로는 수치입니다. 정규 기호 char는 부호가 있으므로 128 개의 값이 있으며이 값은 ASCII 인코딩을 사용하여 문자에 매핑됩니다. 그러나 두 경우 모두 메모리에 저장하는 것은 바이트 값입니다.


7

직접 값과 관련하여 값이 사이에 CHAR_MIN있고 CHAR_MAX부호없는 문자가 양수 범위의 두 배 범위를 제공 하는 경우 일반 문자가 사용됩니다 . 예를 들어, CHAR_BIT8 인 경우 일반 범위는 char[0, 127]이며 (서명 또는 부호 unsigned char가 없을 수 있음) [0, 255]이고 signed char[-127, 127]입니다.

용도에 따라 표준은 POD (일반 오래된 데이터)의 객체를 부호없는 문자 배열로 직접 변환 할 수 있도록합니다. 이를 통해 객체의 표현 및 비트 패턴을 검사 할 수 있습니다. char 또는 signed char에 대해 동일한 안전한 유형 제거 보장이 없습니다.


실제로는 대부분 [-128, 128]입니다.
RastaJedi

표준에만 공식적으로 객체 표현을 정의하는 일련unsigned char아니라, 어레이 즉, 모든 "변환"오직 공식적으로 정의 된 복사 실제의 물체로부터 선언 어레이unsigned char및 그 후자를 검사한다. OR이 그러한 배열로 직접 재 해석 될 수 있는지, 포인터 산술에 대한 허용치, 즉 ==이 사용법에서 "순서" "배열" 인지 여부는 명확하지 않습니다 . 이를 명확히하기 위해 핵심 이슈 # 1701이 열렸습니다. 고맙게도,이 모호성은 최근에 실제로 나를 괴롭 히고 있습니다.
underscore_d

1
@RastaJedi 아니요, 그렇지 않습니다. 할 수 없습니다. -128 ... + 128의 범위는 8 비트로 표현하기가 실제로 불가능합니다. 이 너비는 2 ^ 8 == 256 개의 이산 값만 지원하지만 0 = 257의 경우 -128 ... + 128 = 2 * 128 + 1입니다. 부호 크기 표현은 -127 ... + 127을 허용하지만 2 (바이폴라)를 갖습니다. 제로. 2의 보수 표현은 단일 0을 유지하지만 음수 측에 하나 이상의 값을 가짐으로써 범위를 구성합니다. -128 ... + 127을 허용합니다. (그리고 더 큰 비트 폭에서도 마찬가지입니다.)
underscore_d

두 번째 의견으로, OR 의 첫 번째 포인터를 가져 와서 모든 바이트를 읽는 데 사용할 수 있다고 가정하는 것이 합리적 입니다. 그러나 AFAICT는 허용되는 것으로 구체적으로 정의되지 않았으므로 우리는 직소 퍼즐과 유사하게 표준 의 많은 다른 구절들 (그리고 여러면에서 단순한 존재 )에서 '아마도 괜찮다'고 추론했습니다 . 어느 것이 이상적이지 않습니다. 글쎄, 어쩌면 결국 말이 좋아질 것입니다. 여기 언급 한 CWG 문제가 있지만 링크 할 공간이 부족합니다 -open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1701unsigned char++ptrmemcpy
underscore_d

@underscore_d 죄송합니다. 오타였습니다. [-128, 127]은 내가 : p를 입력하는 것을 의미합니다. 예, 부호 / 크기의 이중 제로 ( '긍정적'및 '음수'제로)에 대해 알고 있습니다. 나는 피곤했다 : p.
RastaJedi

5

unsigned char모든 속임수의 핵심입니다. 모든 플랫폼을위한 거의 모든 컴파일러에서 unsigned chara는 단순히 작은 정수 또는 비트 팩으로 취급 될 수있는 (보통) 8 비트 의 바이트 및 부호없는 정수입니다.

중독에서 다른 사람이 말했듯이 표준은 문자의 부호를 정의하지 않습니다. 그래서 당신은 3 개 별개의이 char유형 : char, signed char, unsigned char.


1
비트 속임수, 일명 비트 twiddling 또는 비트 해킹은 실제로 중독을 일으키는 것으로 알려져 있습니다 ;-)
chqrlie

3
문제를 일으키는 것은 0입니다. 꼬집음으로 인한 중독을 피하기 위해 불필요한 비트에서 멀리 떨어지십시오.
DragonLord

5

특정 길이와 부호의 다양한 유형을 사용하는 것과 같이, 당신은 아마 더 나은을 끈 경우 uint8_t, int8_t, uint16_t, 등 그들이 간단하기 때문에 그들이 말하는 정확히.


4

일부 인터넷 검색 에서 사람들이 이에 대해 토론 한 곳 에서 이것을 발견 했습니다.

부호없는 문자는 기본적으로 단일 바이트입니다. 따라서 1 바이트의 데이터가 필요한 경우이를 사용합니다 (예를 들어, Windows API에서 종종 수행되는 것처럼 플래그를 설정하여 함수에 전달되도록 플래그를 설정 및 해제하려는 경우).


4

부호없는 문자는 일반 문자의 부호를 위해 예약 된 비트를 다른 숫자로 사용합니다. [-128-127]과 반대로 범위를 [0-255]로 변경합니다.

일반적으로 부호없는 문자는 부호를 원하지 않을 때 사용됩니다. 이것은 문자를 숫자로 사용하지 않고 바이트로 처리 할 때 비트 이동 (시프트가 부호 확장)과 같은 작업을 수행 할 때 차이를 만듭니다.


4

unsigned char단지 양의 값을 취하면서 0 255 signed char양 및 음의 값을 취 -128 +127한다.


3

"C 프로그래밍 laugage"책에서 인용 :

한정자 signed또는 unsignedchar 또는 모든 정수에 적용될 수 있습니다. 부호없는 숫자는 항상 양수 또는 0이며 산술 모듈로 2 ^ n의 법칙을 따릅니다. 여기서 n은 유형의 비트 수입니다. 예를 들어, 문자가 8 비트 인 경우 부호없는 문자 변수의 값은 0에서 255 사이이고 부호있는 문자의 값은 -128에서 127 사이입니다 (2의 보수 시스템에서). 일반 문자의 부호 여부는 기계입니다. -종속되지만 인쇄 가능한 문자는 항상 양수입니다.


2

signed char그리고 unsigned char모두 1 바이트를 나타내지 만 서로 다른 범위를 가지고있다.

   Type        |      range
-------------------------------
signed char    |  -128 to +127
unsigned char  |     0 to 255

에서 signed char우리가 고려하는 경우 char letter = 'A', 'A'는 65의 바이너리 표현이다 ASCII/Unicode(65)이 저장 될 수있는 경우, -65도 저장할 수 있습니다. ASCII/Unicode음수 값에 대해 걱정할 필요 가 없으므로 음수 이진 값이 없습니다 .

#include <stdio.h>

int main()
{
    signed char char1 = 255;
    signed char char2 = -128;
    unsigned char char3 = 255;
    unsigned char char4 = -128;

    printf("Signed char(255) : %d\n",char1);
    printf("Unsigned char(255) : %d\n",char3);

    printf("\nSigned char(-128) : %d\n",char2);
    printf("Unsigned char(-128) : %d\n",char4);

    return 0;
}

출력-:

Signed char(255) : -1
Unsigned char(255) : 255

Signed char(-128) : -128
Unsigned char(-128) : 128
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.