답변:
C ++에는 세 가지 고유 한 문자 유형이 있습니다.
char
signed char
unsigned char
text 문자 유형을 사용하는 경우 규정되지 않은 char
다음을 사용하십시오 .
'a'
이나 '0'
."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
.
sizeof
함수가 아니라 연산자이므로 공백을 두는 것이 일반적 입니다. 변수의 크기를 취할 때 괄호를 생략하는 것이 더 나은 스타일입니다. sizeof *p
또는 sizeof (int)
. 이것은 타입이나 변수에 적용되면 빠르게 명확 해집니다. 마찬가지로 뒤에 괄호를 붙여도 중복됩니다 return
. 기능이 아닙니다.
char
:이 같은 문자 리터럴의 유형 'a'
이나 '0'
." C ++에서는 true이지만 C는 아닙니다. C에서는 'a'
입니다 int
.
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
당신이 정말로 작은 정수를 표현하려면.
CHAR_BIT
표준에 따라 8 비트 이상이어야합니다.
나는 그것이 실제로 필요하다고 생각하기 때문에 C와 C ++의 규칙을 말하고 싶습니다 (이 점에서 동일합니다). 첫째, 부호없는 char 객체가 있으면 값을 결정하는 데 모든 비트 가 unsigned char
참여합니다. 둘째, unsigned char
서명되지 않은 것으로 명시 적으로 언급됩니다.
이제 -1
int 유형 의 값을로 변환 할 때 발생하는 일에 대해 누군가와 토론 했습니다 unsigned char
. 그는 unsigned char
부호 표현에 대해 걱정했기 때문에 결과 에 모든 비트가 1로 설정되어 있다는 아이디어를 거부했습니다 . 그러나 그는 필요하지 않습니다. 이 규칙에서 즉시 전환이 의도 한대로 수행됩니다.
새 유형에 부호가없는 경우 값이 새 유형의 범위에 올 때까지 새 유형에 표시 될 수있는 최대 값보다 하나 이상을 반복적으로 더하거나 빼서 값이 변환됩니다. (
6.3.1.3p2
C99 초안에서)
그것은 수학적 설명입니다. C ++은 모듈러스 미적분학으로 설명하며 동일한 규칙을 산출합니다. 어쨌든, 보장 되지 않는 것은 정수의 모든 비트 -1
가 변환 전에 하나라는 것입니다. 결과적 unsigned char
으로 모든 CHAR_BIT
비트가 1로 바뀌 었다고 주장 할 수 있습니까?
UCHAR_MAX+1
하는 -1
즉, 범위의 값을 얻을 것입니다UCHAR_MAX
실제로 충분합니다! 따라서 unsigned char
모든 비트 를 갖기를 원할 때마다
unsigned char c = (unsigned char)-1;
또한 변환은 단순히 고차 비트를 절단 하는 것이 아닙니다 . 2의 보수에 대한 운이 좋은 사건 은 그것이 단지 잘림이라는 것이지만 다른 부호 표현에 대해서도 반드시 같은 것은 아닙니다.
UCHAR_MAX
않습니까?
(unsigned type)-1
어떤 종류의 관용구 이기 때문 입니다. ~0
그렇지 않습니다.
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
. 정수 혼란에 약간의 문자가 뭔가를하고 있다고 생각하지만 모르겠습니다.
예를 들어 unsigned char의 사용법 :
unsigned char
컴퓨터 그래픽에 자주 사용되며, 각 색상 구성 요소에 단일 바이트를 할당하는 경우가 종종 있습니다. RGB (또는 RGBA) 색상이 각각 24 비트 (또는 32 비트)로 표시되는 것이 일반적 unsigned char
입니다. 이후 unsigned char
값 범위는 [0,255]으로 하강 값은 일반적으로 해석된다 :
따라서 RGB 빨강은 (255,0,0)-> (100 % 빨강, 0 % 초록, 0 % 파랑)로 끝납니다.
왜 사용하지 signed char
않습니까? 산술 및 비트 이동이 문제가됩니다. 이미 설명했듯이 signed char
의 범위는 기본적으로 -128만큼 이동합니다. RGB를 그레이 스케일로 변환하는 매우 단순하고 순진한 (대부분 사용하지 않는) 방법은 세 가지 색상 구성 요소를 모두 평균화하는 것이지만 색상 구성 요소의 값이 음수이면 문제가 발생합니다. unsigned char
산술을 사용할 때 빨강 (255, 0, 0)의 평균은 (85, 85, 85) 입니다. 그러나 값이 signed char
s (127, -128, -128) 인 경우 unsigned char
공간 에서 (29, 29, 29) 인 (-99, -99, -99)로 끝나게됩니다. .
문자를 작은 정수로 사용하려면 가장 안전한 방법은 int8_t
및 uint8_t
유형을 사용하는 것입니다.
int8_t
와 uint8_t
바이트 크기가 정확히 8 비트없는 경우에는 옵션 및 아키텍처에 정의되지 않습니다. 반대로, signed char
그리고 unsigned char
항상 적어도 8 비트 가능한 길게 보장됩니다. 일반적인 방법 일 수도 있지만 가장 안전한 방법은 아닙니다 .
signed char
및 unsigned char
? 를 유지하는 것입니다 . 아니면 그 특정한 경우에 더 나은 "safer"대안을 추천 하시겠습니까? "진짜"정수 타입과 스틱 예를 들어 signed int
및 unsigned int
대신 어떤 이유로?
signed char
하고 unsigned char
이식 가능하며 저장 공간을 절약하지만 코드 크기가 약간 증가 할 수 있습니다. 어떤 경우에는 작은 값을 비트 필드 또는 일반 정수 유형의 단일 비트에 저장하여 더 많은 저장 공간을 절약 할 수 있습니다. 이 질문에 대한 절대적인 대답은 없으며,이 접근 방식의 적절성은 현재 상황에 따라 다릅니다. 그리고이 답변은 어쨌든 문제를 다루지 않습니다.
char
그리고 unsigned char
모든 8 비트 유형을 보장하지 않는 플랫폼 - 그들은 8 비트 이상을 보장한다. 일부 플랫폼에는 9 비트, 32 비트 또는 64 비트 바이트가 있습니다. 그러나 오늘날 가장 일반적인 플랫폼 (Windows, Mac, Linux x86 등)에는 8 비트 바이트가 있습니다.
직접 값과 관련하여 값이 사이에 CHAR_MIN
있고 CHAR_MAX
부호없는 문자가 양수 범위의 두 배 범위를 제공 하는 경우 일반 문자가 사용됩니다 . 예를 들어, CHAR_BIT
8 인 경우 일반 범위는 char
[0, 127]이며 (서명 또는 부호 unsigned char
가 없을 수 있음) [0, 255]이고 signed char
[-127, 127]입니다.
용도에 따라 표준은 POD (일반 오래된 데이터)의 객체를 부호없는 문자 배열로 직접 변환 할 수 있도록합니다. 이를 통해 객체의 표현 및 비트 패턴을 검사 할 수 있습니다. char 또는 signed char에 대해 동일한 안전한 유형 제거 보장이 없습니다.
unsigned char
아니라, 어레이 즉, 모든 "변환"오직 공식적으로 정의 된 복사 실제의 물체로부터 선언 어레이 의 unsigned char
및 그 후자를 검사한다. OR이 그러한 배열로 직접 재 해석 될 수 있는지, 포인터 산술에 대한 허용치, 즉 ==
이 사용법에서 "순서" "배열" 인지 여부는 명확하지 않습니다 . 이를 명확히하기 위해 핵심 이슈 # 1701이 열렸습니다. 고맙게도,이 모호성은 최근에 실제로 나를 괴롭 히고 있습니다.
unsigned char
++ptr
memcpy
unsigned char
모든 속임수의 핵심입니다. 모든 플랫폼을위한 거의 모든 컴파일러에서 unsigned char
a는 단순히 작은 정수 또는 비트 팩으로 취급 될 수있는 (보통) 8 비트 의 바이트 및 부호없는 정수입니다.
중독에서 다른 사람이 말했듯이 표준은 문자의 부호를 정의하지 않습니다. 그래서 당신은 3 개 별개의이 char
유형 : char
, signed char
, unsigned char
.
부호없는 문자는 일반 문자의 부호를 위해 예약 된 비트를 다른 숫자로 사용합니다. [-128-127]과 반대로 범위를 [0-255]로 변경합니다.
일반적으로 부호없는 문자는 부호를 원하지 않을 때 사용됩니다. 이것은 문자를 숫자로 사용하지 않고 바이트로 처리 할 때 비트 이동 (시프트가 부호 확장)과 같은 작업을 수행 할 때 차이를 만듭니다.
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