2011-05-04 4 views
1

문자열을 뒤집어서 화면에 출력하는 작은 프로그램을 작성했습니다 :이 프로그램은 크고 작은 엔디안 시스템과 호환됩니까?

void ReverseString(char *String) 
{ 
    char *Begin = String; 
    char *End = String + strlen(String) - 1; 
    char TempChar = '\0'; 

    while (Begin < End) 
    { 
     TempChar = *Begin; 
     *Begin = *End; 
     *End = TempChar; 
     Begin++; 
     End--; 
    } 
    printf("%s",String); 
} 

Windows (리틀 엔디안)의 Dev C++에서 완벽하게 작동합니다. 그러나 나는 그 효율성에 대해 갑작스러운 의심을 품고있다. 이 줄을 보면 :

while (Begin < End) 

나는 시작과 끝 주소를 비교하고있다. 이것이 올바른 방법입니까? 이 코드는 Mac OS X와 ​​같은 빅 엔디안 OS에서 작동합니까? 또는 잘못된 생각을하고 있습니까?

위에서 언급 한 몇 가지 의문점이 있습니다. 누구든지 명확히 할 수 있습니까?

+0

사소한 nit-pick으로, 루프 밖에서 TempChar를 가질 필요가없고 초기화시에도 아무런 포인트가 없습니다. 루프 내부로 이동하여 const로 만듭니다. const TempChar = * Begin ;. – unwind

+0

또 다른 사소한 단언 - Mac OS X은 빅 엔디안이 아니며 x86 (리틀 엔디안), PowerPC (빅 엔디안) 및 기타 아키텍처에서 실행될 때 크거나 작은 엔디안이 될 수 있습니다. –

+1

문제를 찾고있는 경우이 코드는 배열 시작 부분에있는 빈 문자열을 전달할 때 정의되지 않은 동작을합니다. "시작 전에 하나"포인터를 가져 오는 것은 유효하지 않습니다. 실제로 플랫 메모리 모델을 사용하면 어디서든 작동 할 것이며, 대부분의 경우에는없는 것입니다. –

답변

6

코드에 엔디안 관련 문제가 없습니다. 두 포인터를 비교하는 방법에도 아무런 문제가 없습니다. 간단히 말해서, 당신의 코드는 괜찮습니다.

+0

당신은 내가 왜 그게 옳은가? – Vijay

+3

@ Zombie : 코드에는 포인터와 문자 (바이트) 만 있습니다. 바이트는 정의에 따라 endian-neutral입니다. 그리고 포인터로 수행하는 작업은 모두 endian-neutral 연산 인 read, assign, increment 및 decrement입니다. 엔디안 중립적 인 바이트를 역 참조합니다. 그럼 다 괜찮아. – DarkDust

1

전체 type T 개체 (type Tchar 인 작업)를 조작하면 엔디안 문제가 생길 수 없습니다.

예를 들어 더 큰 유형 (예 : int) 내에서 별도의 바이트를 조작하려고 시도했지만 그와 같은 작업을 수행하지 않을 수도 있습니다. 이러한 이유로 엔디안 문제는 코드에서 불가능합니다.

3

endianness는 다중 바이트 기본 유형의 바이트의 중요도 순서로 정의됩니다. 따라서 int이 빅 엔디안 인 경우 메모리에있는 int의 첫 번째 바이트 (즉, 가장 낮은 주소를 가진 바이트)가 int의 최상위 비트를 포함하며 나머지는 최하위/최하위 비트까지 포함한다는 의미입니다. 그것은 모두을 의미합니다. 우리가 시스템이 빅 엔디 언이라고 말하면, 일반적으로 포인터와 산술 타입 모두가 빅 엔디 언 (big-endian)이라는 것을 의미합니다. 엔디안은 포인터 연산 또는 비교 또는 문자열이 메모리에 저장되는 순서에 영향을주지 않습니다.

코드에서 멀티 바이트 기본 유형 [*]을 사용하지 않으므로 endian-ness는 부적합합니다. 일반적으로 endian-ness는 어쨌든 (예를 들어 unsigned char*에 포인터를 던지거나 파일이나 네트워크에 메모리를 쓰는 등으로) 그러한 객체의 개별 바이트에 액세스하는 경우에만 관련이 있습니다.

int x = 0x00010203; // assuming sizeof(int) == 4 and CHAR_BIT == 8 
ReverseString((char *)&x); 

그런 다음 자신의 코드 엔디안에 의존하는 것 : 발신자를 가정 할

는 다음과 같이했다. 빅 엔디안 시스템에서는 첫 번째 바이트가 0이 될 것이므로 빈 문자열을 전달하므로 코드에서 x은 변경되지 않습니다.처음 세 바이트 0x03, 0x02, 0x01 네 번째 바이트 0이 될 것이기 때문에 코드가 x을 변경 할 수 있도록 리틀 엔디안 시스템에서 그들은 당신에게 3 바이트 문자열을 전달 할 0x00030201

[*] 잘 , 포인터는 OSX와 거의 모든 C 구현에서 멀티 바이트입니다. 그러나 스토리지 표현을 검사하지 않고 값으로 만 사용하므로 엔디안에 따라 동작이 다를 수 없습니다.

관련 문제