2012-09-28 6 views
0

내 컴퓨터에서 다음 프로그램은 1234를 출력합니다.문자열 리터럴의 endianness 및 case 문에서 문자열 사용

const char str[] = "1234"; 
printf("%c%c%c%c\n", 
    (int) (0xff & (*(uint32_t*) str) >> 0), 
    (int) (0xff & (*(uint32_t*) str) >> 8), 
    (int) (0xff & (*(uint32_t*) str) >> 16), 
    (int) (0xff & (*(uint32_t*) str) >> 24)); 

str 내부적 0x34333231로 표현되는 것을 의미하고, 제 1 바이트 str[0] 최하위 8 개 비트를 나타낸다.

str은 리틀 엔디안으로 인코딩됩니까? 그리고이 프로그램의 출력은 플랫폼에 따라 다릅니 까?

또한 switch case 문에 1, 2, 4 및 8 자의 문자열 리터럴을 사용하는 편리한 방법이 있습니까? *(const uint32_t* const) "1234"은 상수 표현식이 아니며 0x34333231/0x31323334은 16 진수로 표기해야하며 플랫폼에 종속적 일 수 있으므로 문자열을 정수로 변환 할 수있는 방법이 없습니다.

편집 : 즉

str[0] 항상 동일한 0xff & *(uint32_t*) str입니까?

어, 결코 생각하지 말고 그냥 깨달았습니다. 이유도 있습니다.

답변

2

엔디 언은 더 큰 값의 바이트 순서를 나타냅니다. 문자열은 최소한 C 및 C++에서 바이트 배열이므로 엔디안이 적용되지 않습니다.

멀티 문자 리터럴을 사용하여 마지막 단락에서 언급 한 것을 실제로 수행 할 수 있습니다. 구현 방법은 정확히 정의되어 있으며 문자열은 sizeof(int) 이상이어야합니다.

C++ 표준, §2.14.3/1 - 문자 리터럴

이 (...) 하나 이상의 C-문자를 포함 리터럴 일반 문자가 위해 다중 문자입니다. 다중 문자 리터럴은 int 유형 및 구현 정의 값을가집니다.

예를 들어 'abcd'은 구현 정의 값이있는 int 유형의 값입니다. 이 값은 엔디안에 따라 다를 수 있습니다. 정수이기 때문에 스위치를 켤 수 있습니다.

+0

감사합니다. 그러나 8 문자 리터럴은 어떨까요? 그것은 내 컴퓨터의 워드 크기이지만 int의 크기보다 큽니다. – RPFeltz

+0

@RPFeltz 컴파일러에 확장 기능이있는 경우에만. 표준에 따라 문자 리터럴은 항상 int입니다. –

4

정수의 엔디안을 사용하여 문자열의 엔디 언 (ASCII 문자열에 관한 한 오래 존재하지 않음)을 혼동하는 경우가 있습니다. 시스템의 정수는 리틀 엔디안입니다.

두 번째 질문에 대답하려면 아무 것도 입력 할 수 없습니다. 속도 향상이 절실히 필요하다면 리틀 엔디 언 시스템과 빅 엔디 언 시스템을위한 시스템을 만들 수 있습니다.

0

바이트는 증가하는 메모리 주소에서 0x31, 0x32, 0x33, 0x34로 레이아웃됩니다.

32 비트 정수에서 리틀 엔디안은 0x34333231입니다. 큰 엔디안 0x31323334 인 경우

(일반적으로 정수는 짝수 또는 4 중 주소에 정렬됩니다.)