2009-07-21 4 views
2

big and little-endianness을 공부하고 있습니다.엔디안에 관한 C 코드를 이해하려면

1. 다음 코드에서 | \의 목적은 무엇입니까?

... 

#elif defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN) 

    #define htons(A) ((((uint16_t)(A) & 0xff00) >> 8) | \ 
        (((uint16_t)(A) & 0x00ff) << 8)) 
... 

2. 코드 (A)의 목적은 무엇인가?

+0

답장을 보내 주셔서 감사합니다. –

+1

마스크 & 0xff00 또는 & 0x00ff가 필요하지 않습니다. 첫 번째 경우에는 맨 아래 8 비트가 맨 아래로 이동하기 때문에 마스크됩니다. 두 번째 경우에는 비트가 오버플로되고 손실됩니다. (uint16_t) ((uint16_t) (A) >> 8)) ((uint16_t) (A) << 8)))은 동일한 결과를 나타냅니다. –

+0

@Tom Leys는 두 번째 경우에 대해 동의하지 않습니다. '(((uint16_t) (A)) << 8))'. 'A'는 16 비트의 LS 비트를 유지하는'uint16_t'에 캐스트됩니다. 그런 다음 일반적인 정수 프로모션을 생각해 봅니다. 예를 들어 32 비트 'int'가 될 수 있습니다. 그런 다음 그 값이 바뀝니다 8. ​​OP가 원하는 것 같지는 않습니다. – chux

답변

16

'|' 비트 OR 연산자입니다. 기본적으로 값을 결합합니다. 'A'는 #define htons의 매개 변수입니다. 표현식이 프로그래머 또는 컴파일러를 혼동하지 않도록 괄호로 묶습니다. '\'는 다음 줄로 매크로를 계속합니다. 매크로는 일반적으로 줄 끝에서 끝납니다.

이 매크로는 A에서 16 비트 값을 가져와 상위 8 비트를 마스크합니다. 그런 다음 그 값을 취하여 오른쪽으로 8 비트 이동합니다. 이는 상위 8 비트가 이제 16 비트 값의 맨 아래에 있음을 의미합니다. 그런 다음 A에서 원래 값의 상위 8 비트를 마스크하여 왼쪽 8 비트를 이동합니다. 즉, 하단 8 비트가 상단에 있음을 의미합니다. 마지막으로 두 값을 하나의 값으로 다시 결합합니다.

결과적으로 상단 및 하단 바이트의 위치가 바뀌 었습니다.

3

| 두 개의 정수에 bitwise "OR"를 수행합니다. \은 #define이 다음 줄로 넘어갈 수있는 이스케이프 문자입니다.

+0

내가 너무 늦었 어. : P – Victor

4

이 코드는 표준 C- 전 처리기 매크로에 지나지 않습니다.

|은 비트 OR 연산자입니다. \은 줄 바꿈을 이스케이프하여 #define은 다음 줄로 계속 진행할 수 있습니다. (A)은 매크로의 매개 변수입니다.

2

매크로이기 때문에 사용하면 확장됩니다.

그것은 함수에서 변수와는 달리하지 그입니다

uint16_t i = ((((uint16_t)(0x1234) & 0xff00) >> 8) |(((uint16_t)(0x1234) & 0x00ff) << 8)); 

, 예를 들면 :에 그것은 확장됩니다

uint16_t i = htons(0x1234); 

같이 매크로 ("전화")를 사용

uint16_t htons(uint16_t A) 
{ 
    return (A & 0xff00) >> 8) | (A & 0x00ff) << 8); 
} 
+0

좋은 예! –

+1

'8)'의 마지막 코드에'''가 두 개 더 많이 있습니까? –

+2

C/C++ 프로그래머에게 가장 중요한 계시 중 하나는 'uint16_t i = 0x1233; uint16_t j = htons (i ++);'결과. –