2015-01-01 2 views
0

최근에는 C, char/unsigned char/signed char의 세 가지 유형에 관한 문제를 읽었습니다. 필자가 지금 직면 한 문제는 지금까지 경험하지 못한 문제 (내 프로그램은 테스트 된 모든 컴퓨터에서 제대로 작동하고 리틀 엔디안 (Windows/Linux를 사용하는 기본적으로 모든 현대 데스크톱과 서버를 대상으로합니까?)을 대상으로합니다. array "string"(실제 문자열이 아닌)을 임시 변수로 유지하기 위해 정의했습니다. 예를 들어 스택에 다른 char을 추가하는 대신 array [0]과 같은 멤버 중 하나만 재사용합니다. 그러나이 전략을 나는 그것을 실제로 구현에 따라 오늘 읽을 때까지 문자가 항상 서명 될 수 있다는 사실. 내가 지금 문자를 가지고 있고 그것에 음의 값을 할당하면 무슨 일이 일어날 지?C 캐스트와 char 서명

char unknownsignedness = -1; 

내가 쓴 경우

unsigned char A = -1; 

C 스타일 캐스트는 비트를 다시 해석하고 A가 부호없는 유형으로 나타내는 값이 달라진다 고 생각합니다. 나는이 C 스타일의 캐스트가 단순히 비트의 재 해석이라고 맞습니까? 이제 서명 된 < -> 서명되지 않은 전환을 언급하고 있습니다.

구현에서 char가 서명되지 않은 경우 내 프로그램이 의도 한대로 작동하지 않습니까? 지금 내가 지금 서명 된 char 값에 서명 숯불을 비교하고

if (A == -1) 

을 할 경우, 마지막 변수를 가지고, 그래서 이것은 단순히 부호의에 대해 걱정하지 비트를 비교합니다 또는이 false를 반환합니다 분명 A는 할 수 없기 때문에 -1일까요? 나는이 경우에 어떤 일이 일어나는지 혼란 스럽다. 이것은 또한 자주 쓰는 숯을 사용하면서 가장 큰 관심사입니다. (: C++,하지만 내 추론에 대한 설명을 참조 경고) :

+2

무엇이 주조합니까? 어디에도 캐스팅이 없습니다. 그리고 바이너리 (문자가 아닌) 데이터를 저장하려면 더 나은 (IMO)'int8_t' 또는'uint8_t' 표준 유형을 사용하십시오. –

+0

내 구현은 C99을 지원하지 않습니다. int8_t가 해당 버전의 코드라고 생각했습니다. – user209347

+0

부호없는 값에 부호가있는 값을 할당하면 캐스팅이 없을까요? 또는 데이터 크기가 일치하지 않을 때만 형 변환이 발생합니까? – user209347

답변

4

에서 안전하다는 것을 확인하려면 어떤 컴파일러가 없습니다 :

코드 a = -1a에 구현 정의 값을 할당
#include <stdio.h> 

int 
main() 
{ 
    unsigned char a; 

    a = -1; 

    if(a == -1) 
     printf("Yes\n"); 
    else 
     printf("No\n"); 

    return 0; 
} 

; 대부분의 컴퓨터에서 255는 255가됩니다. a == -1 테스트는 unsigned charint과 비교하므로 일반적인 프로모션 규칙이 적용됩니다. 따라서,이 때문에 a

`(int)a == -1` 

로 해석 (int)a 여전히 255, 255이며, 시험 수율 거짓.

+0

"코드 a = -1"맞습니까? – user209347

+0

@ user209347 고침, 고마워. – jch

+0

"구현 정의 값"모든 준수 구현에서 UCHAR_MAX가됩니다. –

-1

나는이 질문에 가장 빠른 예를 응답 생각

char c = -1; 
unsigned char u = -1; 
signed char s = -1; 
if (c == u) 
     printf("c == u\n"); 
if (s == u) 
     printf("s == u\n"); 
if (s == c) 
     printf("s == c\n"); 
if (static_cast<unsigned char>(s) == u) 
     printf("(unsigned char)s == u\n"); 
if (c == static_cast<char>(u)) 
     printf("c == (char)u\n"); 

출력 :

s == c 
(unsigned char)s == u 
c == (char)u 

C가 치료되는 값을 있는 그대로 다르게 사용하면 캐스팅이 비트를 재 해석한다는 점에서 정확합니다. 여기에서 C++ static_cast을 대신 사용하여 컴파일러가이 캐스팅을하는 것으로 괜찮음을 보여줍니다. C에서는 괄호 안에 타입의 접두사를 붙이면됩니다. 캐스트는 다음 코드를 인쇄 No C.

+1

이것은 C 질문이었습니다. C와 C++은 다른 언어입니다. – jch

+0

@jch :이 예제에서 C++ 사용에 대한 설명을 보려면 첫 번째 줄을 읽으십시오. – greg

+0

그래서 "A == -1"질문에서 예제를 취하면 명시 적으로 "(부호있는 문자) A == -1"로 처리해야 작동하게됩니까? – user209347

3
unsigned char A = -1; 

255가됩니다. 할당 또는 초기화시 재 해석이 없습니다. -1은 2의 보수 표기법으로 된 1 비트의 무리이며 그 중 8 개는 그대로 복사됩니다.

-1 문자가 int 유형이므로 비교가 약간 다릅니다.

if (A == -1) 

승진 (암시 적 캐스트) 비교하기 전에 (int)A을 할 것입니다, 그래서 당신은 -1과 255을 비교 끝. 동등하지 않습니다.

네, 평야와 함께주의해야합니다 char.

+2

"의 결과는 255입니다. 만약 당신의'char '이 8 비트라면 그것입니다. 보장하지 않습니다. "8 비트 머신,'sizeof (int) == sizeof (char)'". 'int'는 적어도 16 비트입니다. –

+0

동의. 나는 char가 8 비트라고 가정했다. 누군가 다른 것을 본 적이 있습니까? 편집 됨. – SzG

+0

"다른 사람이 본 적이 있습니까?" 가능한 중복 : http://stackoverflow.com/questions/2098149/what-platforms-have-something-other-than-8-bit-char –

4
unsigned char a = -1; 

ISO/IEC 9899 : 1999 말한다 6.3.1.3/2에서 :

새로운 유형의 부호이면, 값 반복 가산 또는 최대 값보다 1를 감산하여 전환된다

그는 값이 새로운 유형의 범위가 될 때까지 우리는 한 번 (UCHAR_MAX+1)-1에 추가

새로운 유형의 표현, 그 결과는 분명하다, UCHAR_MAX입니다 수 있습니다 범위는 unsigned char입니다. 피연산자들 모두가 동일한 유형이 있다면

, 더 이상의 변환이 필요하지 않다 : (a == -1)

긴 통로 6.3.1.8/1에있어이 경우

.

두 피연산자가 모두 부호있는 정수 유형이거나 부호가없는 정수 유형 인 경우 더 낮은 정수 변환 순위 유형의 피연산자는 더 높은 순위의 피연산자 유형으로 변환 된 입니다. 부호없는 정수 형태를 가진 피연산자는 다른 피연산자의 타입의 랭크와 동일 랭크 크거나 있는 경우

그렇지 않으면, 다음 부호있는 정수 유형 오퍼랜드 부호와 피연산자의 형식으로 변환되고 정수 유형.

그렇지 부호있는 정수 타입 피연산자의 유형의 부호없는 정수 형태로 피연산자의 타입의 값을 모두 을 나타낼 수 있다면, 부호 정수 유형 오퍼랜드는 의 형식으로 변환되고 부호있는 정수 유형을 갖는 피연산자.

그렇지 않으면 두 피연산자 모두 부호있는 정수 유형의 피연산자 유형에 해당하는 부호없는 정수 유형 으로 변환됩니다.

unsigned char의 등급은 int보다 작습니다.

intunsigned char 경우는 (경우에 통상적 인) 수, 다음 두 피연산자 int 변환 된 모든 값을 나타낼 수 있고, 비교 false를 반환한다.intsizeof(int)==sizeof(char)으로 희귀 한 시스템에서 발생할 수있는 unsigned char 모든 값을 나타낼 수 없습니다

경우, 모두 -1UCHAR_MAX와 동일하게 발생 UINT_MAX로 변환됩니다, unsigned int로 변환되고, 비교 true를 반환합니다.