스터디/C방장

문자형/character type 이야기 [C언어 파헤치기 2]

SW PLAN B 2020. 12. 27. 13:23
728x90

제가 알고 있는 C에 관한 지식을 나눕니다.

카카오톡 오픈 채팅방에서 질문도 받습니다.

C언어 질문 무료 오픈채팅방
C방장 오픈채팅방 QR코드

C방장한테 질문하러 가기


먼저 읽으면 좋은 글

2020/12/27 - [스터디/C방장] - 정수형 type 이야기 [C언어 파헤치기 1]


char, signed char, unsigned char는 어떤 차이가 있을까? C언어 파헤치기2

■ QUIZ 1

int main(void)
{
	char c = 0xff;
	unsigned char uc = 0xff;
	signed char sc = 0xff;

	if (c == uc)
	{
		printf("1\n");
	}
	if (c == sc)
	{
		printf("2\n");
	}
	if (uc == sc)
	{
		printf("3\n");
	}
}

위 퀴즈의 답은 어떻게 될까요?

char, signed char, unsigned char 차이1
char, signed char, unsigned char 차이2

"답은 1일 수도 2일 수도 있다"입니다. 그리고 3일 수는 없습니다. 왜 이런 결과가 나오는지 알아보겠습니다.

■ 문자형 (character type)

표준C의 정수형 분류
표준C의 정수형 분류

표준 C(C99)에서 정수형의 분류는 위 그림처럼 분류됩니다. 그리고 이 중에서 unsigned char, signed char 그리고 char 타입은 다시 문자형(character types) 으로 분류 됩니다.

unsigned char, signed char는 부호가 명시적으로 정해져 있는 문자형인 것을 직관적으로 알 수 있습니다. 그렇다면 char 타입의 부호는 어떻게 결정될까요?

6.2.5 Types (C99, ISO/IEC 9899:1999 (E))
p3
An object declared as type char is large enough to store any member of the basic execution character set.
...
p15
  The three types char, signed char, and unsigned char are collectively called the character types. The implementation shall define char to have the same range, representation, and behavior as either signed char or unsigned char.

6.3.1.1 Boolean, characters, and integers (C99, ISO/IEC 9899:1999 (E))
p1
...
- The rank of char shall equal the rank of signed char and unsigned char
...
p3
  The integer promotions preserve value including sign. As discussed earlier, whether a "plain" char is treated as signed is implementation-defined.

해석하면 다음과 같습니다.

char는 문자 집합을 담기에 충분한 공간이어야 한다.

char, signed char 그리고 unsigned char를 문자형이라고 부른다. char의 사이즈, 표현, 행동에 대한 구현은 signed char 또는 unsigned char와 같도록 한다.

charsigned charunsigned char와 같은 rank를 갖느다.

정수 승격은 부호를 보존한다. "plain" char의 부호는 구현에 따른다.

결국, char의 부호는 시스템, 컴파일러에 따라 다르다는 것입니다.

다시 퀴즈의 코드로 돌아가 보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int main(void)
{
    char c = 0xff;
    unsigned char uc = 0xff;
    signed char sc = 0xff;
 
    if (c == uc)
    {
        printf("1\n");
    }
    if (c == sc)
    {
        printf("2\n");
    }
    if (uc == sc)
    {
        printf("3\n");
    }
}
cs

□ c == uc (line 7)

첫 번째 조건문의 연산은 다음 순서로 이루어집니다.

1. c의 정수 승격

여기서 문제가 발생합니다. 앞서 봤듯이 char c의 부호는 시스템에 따라 달라집니다.

따라서 두 가지 경우가 존재합니다.

char를 signed char로 보는 시스템에서 c는 정수 승격이 일어나서 0xffffffff가 비교 연산에 사용됩니다. (편의를 위해 Case 1이라고 하겠습니다.)

charunsigned char로 보는 시스템에서 c는 정수 승격이 일어나서 0x000000ff가 비교 연산에 사용됩니다. (편의를 위해 Case 2라고 하겠습니다.)

(※ 정수 승격(integer promotion)과 데이터 확장을 이해하기 위해 이전 글을 참고 부탁드립니다.)

2020/12/27 - [스터디/C방장] - 정수형 type 이야기 [C언어 파헤치기 1]

2. uc의 정수 승격

uc의 정수 승격 결과 0x000000ff가 비교 연산에 사용됩니다.

3. 비교

Case 1 비교 결과 false

Case 2 비교 결과 true, 1 출력

□ c == sc (line 11)

Case 1 비교 결과 true 2 출력

Case 2 비교 결과 false

□ uc == sc (line 13)

Case 1 비교 결과 false

Case 2 비교 결과 false

■ visual studio (2019)에서 char

char 형식
char 형식은 표현할 수 있는 문자 집합 멤버의 정수 값을 저장하는 데 사용됩니다. 해당 정수 값은 지정된 문자에 대응하는 ASCII코드입니다.

Micorsoft 전용
unsigned char 형식의 문자 값 범위는 0에서 0xFF까지의 16 진수입니다. signed char의 범위는 0x80에서 0x7F까지입니다. 이 범위는 0에서 255까지의 10진수 및 -128에서 +127까지의 10진수로 각각 변환됩니다. /J컴파일러 옵션은 기본값을 signed에서 unsigned로 변경합니다.
Micorsoft 전용

출처: https://docs.microsoft.com/ko-kr/cpp/c-language/type-char?view=msvc-160

위 내용을 보면 visual studio에서 기본 문자 집합은 ASCII코드를 사용하고 default 설정으로 plain charsigned char인 것을 알 수 있습니다.

■ visual studio (2019)에서 char의 기본 설정 unsigned char로 바꾸는 방법

visual studio에서 char 기본설정 unsigned로 바꾸기 1

프로젝트(P) - (프로젝트 이름) 속성(P)을 클릭합니다.

visual studio에서 char 기본설정 unsigned로 바꾸기 2

구성 속성 - C/C++ - 명령줄의 추가 옵션(D)에 "/J"를 입력합니다. (큰 따옴표는 입력하지 않고 j는 대문자로 입력합니다.)

출처: https://docs.microsoft.com/ko-kr/cpp/build/reference/j-default-char-type-is-unsigned?view=msvc-160

적용, 확인을 누르면 char의 기본 설정이 unsigned char로 설정되고 Quiz의 실행 결과가 1이 출력되는 것을 확인할 수 있습니다.

 

읽어주셔서 감사합니다.


C언어 글 목록 보기

 

'스터디/C방장' 카테고리의 글 목록

일상의 모든것

sw-daily.tistory.com



#태그를 이용하시면 제 블로그에 있는 비슷한 주제의 글들을 보실 수 있습니다.

반응형