{{ label!='' ? 'Label : ' : (q!='' ? '검색 : ' : '전체 게시글') }} {{ label }} {{ q }} {{ ('('+(pubs|date:'yyyy-MM')+')') }}

[C++] The C++ Programming Language: 6. Types and Declarations (2) - Character Types

 6.2.3 Character Types

  세상에는 다양한 문자들과, 다양한 인코딩 방식이 있습니다. C++는 이를 위해 다양한 문자 자료형을 지원하죠:

  • char: 프로그램 텍스트를 위한 기본 문자 자료형입니다. A char is used for the implementation's character set. 보통 8비트입니다.
  • signed char: char와 비슷하지만 부호를 붙일 수 있습니다. 양수와 음수 값을 가질 수 있습니다.
  • unsigned char: char와 비슷하지만 양수임이 보증됩니다.
  • wchar_t: 유니코드와 같이 큰 문자 집합을 표현할 수 있습니다. wchar_t의 크기는 implementation-defined이며, 아무리 큰 문자 집합이여도 충분할 정도로 큰 크기를 지니고 있습니다.
  • char16_t: UTF-16과 같은 16-비트 문자 집합을 표현합니다.
  • char32_t: UTF-32와 같은 32-비트 문자 집합을 표현합니다.

  이러한 6개의 자료형이 존재합니다. 구현상 char형은 signed char, unsigned char와 동일하지만 여전히 그들은 분리된 자료형임에 유의하세요.

(생략)

  십진수와 26개의 알파벳 문자, 몇몇 구두점 문자들을 포함한 문자 집합을 구현한다는 것은 확실합니다. 하지만 다음을 보장한다고 생각하지는 마세요:

  • 8-비트 문자 집합에는 127개 이하의 문자만 있습니다. (어떤 집합은 때로 255개의 문자를 지원하기도 합니다)
  • 영어에서 쓰이는 알파벳 문자 말고는 존재하지 않습니다. (대부분의 유럽 언어에서는 다른 문자들도 지원하는 경우가 있습니다)
  • 알파벳 문자들의 값은 연속으로 26개에 대응합니다. (EBCDIC는 i와 j 사이에 값의 간격이 있습니다)
  • C++에서 쓰이는 문자는 전부 사용 가능합니다. (어떤 국제 문자 집합에서는 {, }, [, ], |, \를 지원하지 않습니다)
  • char는 1 byte입니다. (char를 4 byte로 처리하는 프로세서들도 존재합니다. 이 경우 16-비트 유니코드 인코딩을 char로 하는 것도 가능하겠죠)

  가능하다면, 우리는 객체의 표현에 대한 추론을 하지 않아야 합니다. 이러한 통념은 문자 자료형에도 예외는 아닙니다.

  각 문자는 그에 대응하는 정수 값이 존재합니다. 예를 들어, ASCII의 경우 'b'는 98입니다. 다음은 여러분이 입력한 문자에 대해 정수 값을 출력해주는 프로그램입니다:

1
2
3
4
5
void intval()
{
    for (char c; cin >> c; )
        cout << "the value of '" << c << "' is " << int{c} << '\n';
}
cs

  int{c}는 문자 c의 정수 값을 표현합니다. c로부터 int형 값이 생성되는 것이죠. 이러한 정수 값 변환은 우리에게 질문을 던지죠: char는 부호가 있나요? 8-비트의 값은 256개의 값을 표현합니다. 0부터 255, -127부터 127. -128부터 127까지라고 예상할 수도 있었을 텐데요. 그렇지는 않습니다. C++는 1의 보수를 사용하는 가능성을 염두에 두기 때문에 하나의 값을 제외합니다. 결국, -128의 값은 사용할 수 없죠. 안타깝게도, char의 값에서 부호를 고려할 것인지 말 것인지의 구현에서 결정되는 문제입니다. 이는 signed char와 unsigned char 사이에서 문제가 발생할 수 있겠지만, 대부분의 문자 집합에서는 0부터 127 사이의 범위를 사용하니, 안심하세요.

(생략)


6.2.3.1 Signed and Unsigned Characters

  char가 부호가 있는지 없는지의 문제는 구현부에 달린 문제입니다. 이는 가끔 끔찍한 문제를 불러일으키게 되죠. 다음을 참고하세요:

1
2
char c = 255; // 255 is "all ones." hexadecimal 0xFF
int i = c;
cs

  i의 값은 무엇일까요? 안타깝게도, 정답은 "모른다."입니다. 8-bit 바이트를 사용하는 구현의 경우, i의 값은 char의 비트 패턴이 정수형으로 확장되었을 때 어떻게 생겼느냐에 달려있습니다. char를 부호 없는 수로 구현하고 있다면, i의 값은 255가 됩니다. char를 부호 있는 수로 구현하고 있다면, i의 값은 -1이 됩니다. 이 경우, 컴파일러는 255의 리터럴이 -1로 변환될 것임을 경고합니다. 하지만, C++는 이러한 문제를 탐지할 일반적인 메커니즘을 제공하지 않습니다. 하나의 해결책은 순수 char형을 쓰는 것 대신 특수한 char 자료형만 사용하는 것이죠. 안타까운 사실은, 몇몇 표준 라이브러리 함수의 경우 순수한 char만을 요구한다는 것입니다. 가령 strcmp()가 그렇습니다.

  char는 signed char 혹은 unsigned char와 동일하게 행위해야 합니다. 하지만 세 char 자료형은 다르며, 포인터 역시 섞어서 사용할 수 없습니다:

1
2
3
4
5
6
7
void f(char c, signed char sc, unsigned char uc)
{
    char∗ pc = &uc; // error : no pointer conversion
    signed char∗ psc = pc; // error : no pointer conversion
    unsigned char∗ puc = pc; // error : no pointer conversion
    psc = puc; // error : no pointer conversion
}
cs

  각각 세 char 자료형은 서로가 자유롭게 할당될 수 있습니다. 하지만 너무 큰 수가 부호 있는 char에 할당되는 것은 정의되어 있지 않습니다:

1
2
3
4
5
6
7
8
9
10
void g(char c, signed char sc, unsigned char uc)
{
    c = 255; // implementation-defined if plain chars are signed and have 8 bit
    c = sc; // OK
    c = uc; // implementation-defined if plain chars are signed and if uc’s value is too large
    sc = uc; // implementation defined if uc’s value is too large
    uc = sc; // OK: conversion to unsigned
    sc = c; // implementation-defined if plain chars are unsigned and if c’s value is too large
    uc = c; // OK: conversion to unsigned
}
cs

  구체적으로, char는 8 비트라 가정해보죠:

1
2
3
4
5
6
7
signed char sc = −160;
unsigned char uc = sc; // uc == 116 (because 256-160==116)
cout << uc; // print 't'

char count[256]; // assume 8-bit chars
++count[sc]; // likely disaster: out-of-range access
++count[uc]; 
cs

  모든 문자를 일반적인 char 값을 사용하고, 음수 값을 피한다면, 이러한 문제는 발생하지 않을 것입니다.


6.2.3.2 Character Literals

  문자 리터럴은 작은 따옴표로 둘러쌓인 하나의 문자입니다. 'a', '0'과 같은 것이죠. 문자 리터럴의 자료형은 char입니다. 문자 리터럴은 묵시적으로 정수 값으로 변환될 수 있습니다. ASCII 문자 집합을 사용한다면, '0'은 48로 변환되죠. 정수 표현 대신 문자 리터럴을 사용하는 것은 프로그램을 좀 더 호환성 있게 만듭니다.

  몇몇 문자는 백슬래시를 이용한 표준 이름이 있습니다:


(생략)

댓글

이 블로그의 인기 게시물

[코딩의탑] 4층: 툰 쉐이딩

[코딩의탑] 3층: 바다 렌더링

[코딩의탑] 5층: 포탈(Portal), 더 나아가기