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


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 비트 부호없는 정수가됩니다 0에 255). 표준은 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 = 1234와 char *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_t및 uint8_t유형을 사용하는 것입니다.


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

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

@chqrlie 따라서 메모리를 절약하려면 작은 정수를 나타내는 가장 안전한 방법은 signed char및 unsigned char? 를 유지하는 것입니다 . 아니면 그 특정한 경우에 더 나은 "safer"대안을 추천 하시겠습니까? "진짜"정수 타입과 스틱 예를 들어 signed int및 unsigned 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.