2009-12-29 3 views
7

좋아, 처음에는 직관적이지 않을 수도있는 이상한 관용구와 일반적인 관행에 관한 많은 글을 보았습니다. 아마도 몇 가지 예는 배열에서C 숙어와 거의 알려지지 않은 사실

요소는 순서대로 :

#define ELEMENTS(x) (sizeof (x)/sizeof (*(x))) 

Odd array indexing:

a[5] = 5[a] 

Single line if/else/while/for safe #defines

#define FOO(X) do { f(X); g(X); } while (0) 
#define FOO(X) if (1) { f(X); g(X); } else 

전문가에 내 질문이 밖으로 C 프로그래머 : 무엇 관용구, 연습, 코드 스 니핏 또는 거의 알려지지 않은 사실은 C 코드에서 많이 나타나지만 매우 직관적이지는 않지만 C 프로그래밍에 대한 좋은 통찰력을 제공 할 수 있습니까?

+6

은 커뮤니티 위키 여야합니다. –

+0

너무 좋지 않아 닫히지 않았습니다. 질문이 없습니다. –

답변

11

0으로 N-1에서 카운트 다운의 "화살표 연산자"

for (int i = n; i --> 0;) ... 

그것은 상당히 일반적인 아니지만, 흥미로운 그림의 그 어떤 방법으로 for의 초기화/테스트/업데이트 부품 루프가 규칙입니다. 그것은 일반적인 패턴이지만 여전히 임의의 표현식을 그 안에 넣을 수 있습니다.

또한 어휘 분석의 작동 방식에 대해 약간의 알림을줍니다.

+0

http://cplusplus.co.il/2009/12/28/the-omnototrol-operator/ – rmn

+0

있습니다. 이 강 대한 조작자에게서 단순히 도주하십시오. – GManNickG

+0

선형 검색에 좋습니다. 결국, 당신이보아야 할 첫 번째 장소는 당신이 무언가를 넣는 마지막 장소입니다. –

4

쉼표 연산자는 꽤 많은 알고리즘 코드에 나타나며 이전에는 발견되지 않은 많은 프로그래머에게 놀랄 수 있습니다 (K & R 등). 종종 일부 루프 구조를 단순화하기 위해 사용된다 : 중첩 루프를 회피하면서

#define kITERATIONS_MAX 10 
int i=0,j=0,array[kITERATIONS_MAX],outArray[kITERATIONS_MAX],temp=0; 

for (i=0,j=kITERATIONS_MAX-1; i < kITERATIONS_MAX; i++,j--) 
{ 
temp = array[i]*array[j]; 
outArray[i]=temp; 
} 

위의 코드를 통해 9 0 9 통해 어레이 요소는 0 곱한다.

쉼표 연산자를 사용할 때 첫 번째 표현식과 두 번째 표현식이 모두 평가됩니다. 첫 번째 표현식의 결과는 무시되고 두 번째 표현식의 결과가 리턴됩니다.

+0

'while (c = getc(), c! = EOF) ...'라는 두 가지 일을하는 while 조건에서 쉼표 연산자를 사용합니다. –

+0

@DavidRTribble'c = getc()'는'c'와 동일하다고 평가합니다. 즉, (아마도) (while = (c = getc())! = EOF) ...' –

+0

@ RobbieMckennie, 맞습니다.하지만 두 개의 연산 (할당 및 비교)을 제어 while 식에서 두 개의 별도 표현식으로 읽기가 더 쉽습니다. –

5

어쨌든 누구든지 언급 할 것이므로, 저도 그렇습니다 : Duff's Device. 라벨이 C에서 작동하는 방식을 보여주는 멋진 그림입니다. 처음으로 "aha experience"를 얻었습니다.

send(to, from, count) 
register short *to, *from; 
register count; 
{ 
    register 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); 
    } 
} 

오늘, 하나 register을 사용하고, 이전 스타일 함수 정의를 피할 것 : 이것은 그의 원래의 코드입니다.

+0

또한 필자가 알고 있듯이, 현대적인 최적화 컴파일러에서이 작업을 수행하고 싶지는 않습니다. – dubiousjim

관련 문제