2013-12-16 2 views
4

제드 쇼의 에서 하드 코트를 배우십시오, 23 번 연습에서 그는 더프의 장치에 대해 이야기합니다. .더프의 장치 용 매크로 작성하기

int duffs_device(char *from, char *to, int count) 
{ 
    { 
     int n = (count + 7)/8; 

     switch(count % 8) { 
      case 0: do { *to++ = *from++; 
         case 7: *to++ = *from++; 
         case 6: *to++ = *from++; 
         case 5: *to++ = *from++; 
         case 4: *to++ = *from++; 
         case 3: *to++ = *from++; 
         case 2: *to++ = *from++; 
         case 1: *to++ = *from++; 
        } while(--n > 0); 
     } 
    } 

    return count; 
} 

그는 독자 요청 : 예를 들어

는 "이 같은 길이의 장치를 만들 수 있습니다 매크로 세트를 만들기를, 당신이 원한다면 여기에서 참조 더프의 장치입니다 총 32 건의 사례 발표문을 갖고 있으며, 모두 작성하고 싶지는 않습니까? 한 번에 8 개를 작성하는 매크로를 만들 수 있습니까? "

이것은 정말로 저를 곤란하게했고, 나는 올바른 방향으로 조금 움직여야한다고 느낍니다. 어떤 도움이라도 대단히 감사하겠습니다! 이 같은

+0

Duff 's Device는 선택 코딩이 멋지지만 유용한 범용 C 관용구가 아닙니다. 당신은 그것을 사용하여 몇 가지 명성을 찾을 수 있지만 부정적인 푸시 백을 위해 준비하십시오. – chux

+0

@ chux- 나는 그가 단지 배우려고하고 있다고 생각한다. 그래서 그것을 요구하는 것이다. – vidit

+2

나는 그것이 오늘날의 프로세서에서 일반적으로 쓸모없는 것이 아니라는 것을 이해한다. 매크로를 작성하는 방법을 알아내는 데 관심이 있습니다. 나는 오늘 밤 잠을 자지 않고서도 그것을 이해할 수 없을 것입니다. – Fumbster

답변

6

뭔가 :

#define LAYDUFF(x, y) \ 
    case ((0 ## x ## y) + 1) : *to++ = *from++ 

#define SEVEN_AT_ONCE(x) \ 
    LAYDUFF(x,6); \ 
    LAYDUFF(x,5); \ 
    LAYDUFF(x,4); \ 
    LAYDUFF(x,3); \ 
    LAYDUFF(x,2); \ 
    LAYDUFF(x,1); \ 
    LAYDUFF(x,0) 

#define EIGHT_AT_ONCE(x) \ 
    LAYDUFF(x,7);   \ 
    SEVEN_AT_ONCE(x) 

int duffs_device(char *from, char *to, int count) 
{ 
    { 
     int n = (count + 31)/32; 

     switch(count % 32) { 
      case 0: do { *to++ = *from++; 
         SEVEN_AT_ONCE(3);     
         EIGHT_AT_ONCE(2); 
         EIGHT_AT_ONCE(1); 
         EIGHT_AT_ONCE(0); 
        } while(--n > 0); 
     } 
    } 

    return count; 
} 

 case ((036) + 1) : *to++ = *from++; // = 31 

        ... 

     case ((000) + 1) : *to++ = *from++; // = 1 

업데이트로 확장됩니다 :

또는, 당신은 첫 번째 매크로 다시 작성할 수 있습니다 :

 #define LAYDUFF(x, y) \ 
case (8 * x + y + 1) : *to++ = *from++ 

기본적으로 8 진수를 사용하지 않는다는 점을 제외하면 기본적으로 동일합니다.

+1

'case ((x) * 8 + (y) + 1) :'는 잘 작동했을 것이며, 틀림없이 이해하기 쉽습니다. – rici