(1) 바이트 순서는 C에서 char의 희귀를 의미합니까? UTF-16은 바이트 시퀀스입니까, 아니면 무엇입니까? (2) 바이트 시퀀스가 가변 길이와 관련이없는 이유는 무엇입니까?
엔디안 문제가 무엇인지 오해하는 것 같습니다. 다음은 간단한 요약입니다.
32 비트 정수는 4 바이트를 차지합니다. 이제이 바이트들의 논리적 순서를 알았습니다. 32 비트 정수가있는 경우 다음 코드를 사용하여 상위 바이트를 얻을 수 있습니다.
uint32_t value = 0x8100FF32;
uint8_t highByte = (uint8_t)((value >> 24) & 0xFF); //Now contains 0x81
그게 다 잘 됐어 문제가 시작되는 곳은 다양한 하드웨어가 메모리에서 정수를 저장하고 검색하는 방법입니다.
Big Endian 순서로, 32 비트 정수로 읽는 4 바이트 메모리는 첫 바이트가 높은 바이트 인 상태에서 읽습니다.
[0][1][2][3]
리틀 엔디안 (Little Endian) 순서로, 32 비트 정수로 읽는 4 바이트 메모리는 첫 바이트가 낮은 바이트 로 읽 힙니다 .
[3][2][1][0]
32 비트 값에 대한 포인터가있는 경우 다음을 수행 할 수 있습니다.
uint32_t value = 0x8100FF32;
uint32_t *pValue = &value;
uint8_t *pHighByte = (uint8_t*)pValue;
uint8_t highByte = pHighByte[0]; //Now contains... ?
C / C ++에 따르면이 결과는 정의되어 있지 않습니다. 0x81 일 수 있습니다. 또는 0x32 일 수 있습니다. 기술적으로는 모든 것을 반환 할 수 있지만 실제 시스템의 경우 하나 또는 다른 것을 반환합니다.
메모리 주소에 대한 포인터가 있으면 해당 주소를 32 비트 값, 16 비트 값 또는 8 비트 값으로 읽을 수 있습니다. 빅 엔디안 머신에서 포인터는 높은 바이트를 가리 킵니다. 리틀 엔디안 머신에서 포인터는 하위 바이트를 가리 킵니다.
이것은 메모리에서 읽고 쓰는 것에 관한 것입니다. 내부 C / C ++ 코드와 는 아무런 관련 이 없습니다 . C / C ++에서 정의되지 않은 것으로 선언하지 않은 코드의 첫 번째 버전은 항상 높은 바이트를 얻기 위해 작동합니다.
바이트 스트림 읽기를 시작할 때 문제가 발생합니다. 파일에서와 같은.
16 비트 값은 32 비트와 같은 문제가 있습니다. 그것들은 단지 4 대신에 2 바이트를 갖는다. 따라서, 파일은 빅 엔디안 또는 리틀 엔디안 순서로 저장된 16 비트 값을 포함 할 수있다.
UTF-16은 일련의 16 비트 값으로 정의됩니다 . 효과적으로, 그것은입니다 uint16_t[]
. 각 개별 코드 단위는 16 비트 값입니다. 따라서 UTF-16을 올바르게로드하려면 데이터의 엔디안이 무엇인지 알아야합니다.
UTF-8은 일련의 8 비트 값으로 정의됩니다 . 입니다 uint8_t[]
. 각 개별 코드 단위의 크기는 8 비트이며 단일 바이트입니다.
이제 UTF-16과 UTF-8은 여러 코드 단위 (16 비트 또는 8 비트 값)를 함께 결합하여 유니 코드 코드 포인트 ( "문자")를 구성 할 수있게하지만 올바른 용어는 아닙니다 . 단순화입니다. ). 코드 포인트를 구성하는 이러한 코드 단위 의 순서 는 UTF-16 및 UTF-8 인코딩에 의해 결정됩니다.
UTF-16을 처리 할 때 16 비트 값을 읽고 필요한 엔디안 변환을 수행합니다. 그런 다음 대리 쌍인지 감지합니다. 그렇다면 다른 16 비트 값을 읽고 두 값을 결합하면 유니 코드 코드 포인트 값을 얻게됩니다.
UTF-8을 처리 할 때 8 비트 값을 읽습니다. 1 바이트 만 있기 때문에 엔디안 변환이 불가능합니다. 첫 번째 바이트가 멀티 바이트 시퀀스를 나타내는 경우 멀티 바이트 시퀀스에 의해 지시 된대로 일부 바이트 수를 읽습니다. 각 개별 바이트는 바이트이므로 엔디안 변환이 없습니다. 위해 이들은 UTF-16 게이트 쌍의 순서는, UTF-8에 의해 정의되는 것처럼 시퀀스 바이트.
따라서 UTF-8에는 엔디안 문제가 없습니다.