숙제 : unsigned char랑 char의 차이점. 꼭 구분해서 써야하는 예를 알려주세요.

위의 숙제를 받고 혼자 생각해본 바는...

 
이미 알고 있던 사전지식으로는 자료형은 맨 앞에 부호 비트가 있다. 이것이 signed 자료형이고 unsigned로 선언이 되면 부호비트를 일반 데이터비트로 사용하게 되어 데이터를 저장하게 된다.
대부분의 인터넷 검색 자료에서는 이로 인해 데이터 표현범위가 2배로 늘어나게 된다고 하는데...
실상 생각해보면 같은게 아닐까 한다. 양의 정수쪽으로는 표현범위가 2배 늘어나겠지만 음의 정수로 표현하는 범위를 상실했으니 표현 범위의 넓이는 결과적으로 같은게 아닐까?
signed char는 8비트이다. 첫 1비트를 부호비트로 쓰기 때문에 표현 범위는 -2^7~+2^7-1이 될 것이다. 고로 -128~+127이 되니 256개의 표현이 된다.
unsigned char 또한 8비트이지만 첫 1비트 또한 데이터비트이기 때문에 표현 범위는 2^8-1이 될 것이다. 고로 0~255가 된다.

이걸 구분해야 하는 이유가 있을 때는 어떤 때일까?
몇몇 블로그를 방문해 내요을 본 결과 대부분의 사람들은 1bit씩 나누어 통신을 하거나 무언가 비트 단위 작업을 할때 문제를 야기할 수 있다고 한다.
1bit씩 나누어 통신을 하는 경우에 발생하는 오류는 일반 환경에서는 발생하지 않지만 임베디드 환경에서는 발생 할 수 있다고 하는데 컴파일러 문제인지 잘 모르겠다;

 
char buf; 를 선언하고 RS-232 등의 통신을 위해 한 바이트식 전송을 하려고 할때 buf에 들어가는 값이 0xA0 부터 즉, sign bit 가 1이 되는 시점부터 그 값을 잘못 읽어 sizeof(char) = 1 임에도 불구하고 0xFFFFFFA0 가 되어 실제로 전송되는 값은 FF가 되는 문제가 발생을 할 수 도 있다.

또, 비트단위 작업의 경우 비트단위 연산자를 쓰면 오류가 발생한다는데 예제를 찾지 못했다. 대충 예상을 해보면 10진수로 표현했을 때 정수값이 같더라도 비트값은 틀리다는 것을 말하는 걸까 싶다.

뒤늦게 찾은 예제?

1.

void main()
{
             unsigned char c=0x80;
             printf("%u\n",c);
             printf("%d\n",c);
}

실행 결과
128
128

unsigned char1바이트로 0~255를 표현이 가능합니다.
%u는 인자를 unsigned int 값으로 표현하는 포멧입니다.
인자 cunsigned char이고 출력 포멧은 unsinged int여서 묵시적 형변환이 진행됩니다.
둘 다 부호가 없는 표현이므로 묵시적 형변환이 진행될 때 늘어나는 메모리의 값은 0으로 채워집니다.
따라서 0000 0000 0000 0000 0000 0000 1000 0000 로 형변환됩니다.
여전히 10진수로 128이므로 실행 결과는 128이 출력됩니다.

%d는 인자를 int 값으로 표현하는 포멧입니다.
unsigned char는 부호를 표현하지 않으므로 묵시적 형변환이 진행될 때 늘어나는 메모리의 값으 0으로 채워집니다. 마찬가지로 0000 0000 0000 0000 0000 0000 1000 0000 로 형변환됩니다.
여전히 10진수로 128이므로 실행 결과는 128이 출력됩니다.

 

2.

void main()
{
             char c=0x80;
             printf("%u\n",c);
             printf("%d\n",c);
}

실행 결과
4294967168
-128

char1바이트로 -128~127 을 표현이 가능합니다. 물론, ASCII 코드가 0~127까지 약속되어 있어서 문자를 표현할 때 많이 사용되어 형식 명을 char라 부르게 된 것이죠.
%u는 인자를 unsigned int 값으로 표현하는 포멧입니다.
인자 cchar이고 출력 포멧은 unsinged int여서 묵시적 형변환이 진행됩니다.
char는 부호가 있는 표현인데 최상위 비트가 1이면 음수입니다. 0x801000 0000 으로 음수입니다. 묵시적 형변환이 진행될 때 늘어나는 메모리의 값은 부호비트로 채워집니다.
따라서 1111 1111 1111 1111 1111 1111 1000 0000 로 형변환됩니다.
부호없는 10진수로 4294967168 이므로 실행 결과는 4294967168를 출력합니다.

%d는 인자를 int 값으로 표현하는 포멧입니다.
인자 cchar이고 출력 포멧은 int여서 묵시적 형변환이 진행됩니다.
char는 부호가 있는 표현인데 최상위 비트가 1이면 음수입니다. 0x801000 0000 으로 음수입니다. 묵시적 형변환이 진행될 때 늘어나는 메모리의 값은 부호비트로 채워집니다.
따라서 1111 1111 1111 1111 1111 1111 1000 0000 로 형변환됩니다.
부호있는 10진수로 -128 이므로 실행 결과는 -128을 출력합니다.

찾아본 마지막으로 오류 처리를 위한 결과 값을 if 문에 사용할 때이다.
보통 아래와 같이 작성을 하는데...이 때 unsigned char의 경우 조건문을 의도한대로 탈 수 없다는 것입니다.
if([함수 이름이나 함수 리턴값이 담긴 변수 이름] < 0) bla~ bla~
머...이건 별로 유념하지 않아도 될 것 같긴 합니다만...