문제

a에서 두 가지 변수를 증가시키고 싶습니다 for-하나 대신 루프 조건.

그래서 :

for (int i = 0; i != 5; ++i and ++j) 
    do_something(i, j);

이것의 구문은 무엇입니까?

도움이 되었습니까?

해결책

일반적인 관용구는 사용하는 것입니다 쉼표 운영자 두 피연산자를 모두 평가하고 두 번째 피연산자를 반환합니다. 따라서:

for(int i = 0; i != 5; ++i,++j) 
    do_something(i,j);

그러나 그것은 정말로 쉼표 운영자입니까?

이제 댓글 작성자는 실제로 쉼표 운영자가 아니라 실제로 성명서에서 특별한 구문 설탕이라고 제안했습니다. GCC에서 다음과 같이 확인했습니다.

int i=0;
int a=5;
int x=0;

for(i; i<5; x=i++,a++){
    printf("i=%d a=%d x=%d\n",i,a,x);
}

X가 A의 원래 값을 선택할 것으로 기대하고 있었으므로 x에 대해 5,6,7 ..을 표시해야했습니다. 내가 얻은 것은 이것이었습니다

i=0 a=5 x=0
i=1 a=6 x=0
i=2 a=7 x=1
i=3 a=8 x=2
i=4 a=9 x=3

그러나 파서가 실제로 쉼표 연산자를 볼 수 있도록 표현을 괄호로 묶었다면 나는 이것을 얻는다.

int main(){
    int i=0;
    int a=5;
    int x=0;

    for(i=0; i<5; x=(i++,a++)){
        printf("i=%d a=%d x=%d\n",i,a,x);
    }
}

i=0 a=5 x=0
i=1 a=6 x=5
i=2 a=7 x=6
i=3 a=8 x=7
i=4 a=9 x=8

처음에 나는 이것이 쉼표 연산자로서 행동하지 않았다는 것을 보여 주었다고 생각했지만, 결과적으로 이것은 단순히 우선 순위 문제입니다. 가능한 가장 낮은 우선 순위, 표현식 x = i ++, a ++는 효과적으로 (x = i ++), a ++로 구문 분석됩니다.

모든 의견에 감사드립니다. 흥미로운 학습 경험이었으며 수년 동안 C를 사용해 왔습니다!

다른 팁

이 시도

for(int i = 0; i != 5; ++i, ++j)
    do_something(i,j);

그렇게하지 마십시오!

에서 http://www.research.att.com/~bs/jsf-av-rules.pdf:

AV 규칙 199
for 루프의 증분 표현식은 단일 루프 매개 변수를 루프의 다음 값으로 변경하는 것 외에 다른 조치를 수행하지 않습니다.

이론적 근거 : 가독성.

for (int i = 0; i != 5; ++i, ++j) 
    do_something(i, j);

나는 두 번째 색인을 For Loop의 증분 조항으로 코딩하는 방법을 상기시키기 위해 여기에 왔으며, C ++로 작성된 다른 프로젝트에 통합 한 샘플에서 주로 관찰함으로써 수행 할 수 있다는 것을 알았습니다.

오늘 저는 C#에서 일하고 있지만, 이와 관련하여 동일한 규칙을 준수 할 것이라고 확신했습니다. for 문은 모든 프로그래밍에서 가장 오래된 제어 구조 중 하나이기 때문입니다. 고맙게도, 나는 최근에 나이가 많은 C 프로그램 중 하나에서 루프의 행동을 정확하게 기록하는 데 며칠을 보냈으며, 그 연구가 오늘날의 C# 문제에 적용되는 수업, 특히 두 번째 색인 변수의 동작에 적용되는 교훈을 신속하게 깨달았습니다. .

부적절한 것은 다음이 내 관찰에 대한 요약입니다. 현지인 창에서 변수를주의 깊게 관찰함으로써 오늘 일어나는 모든 일은 문의 C#이 문의 C 또는 C ++와 똑같이 동작한다는 기대를 확인했습니다.

  1. Loop의 첫 번째 A가 실행되면 증분 절 (3 중 3)이 건너 뜁니다. Visual C 및 C ++에서, 증분은 루프를 구현하는 블록의 중간에 3 개의 기계 지침으로 생성되므로 초기 패스가 초기화 코드를 한 번만 실행 한 다음 증분 블록을 뛰어 넘어 종단 테스트를 실행합니다. 이는 인덱스 상태 및 제한 변수에 따라 A가 루프의 A가 0 이상을 실행한다는 기능을 구현합니다.
  2. 루프의 본문이 실행되면 마지막 진술은 첫 번째 반복에 의해 건너 뜁니다. 이러한 실행 후 Control은 자연스럽게 중간 절을 구현하는 한계 테스트 코드로 떨어집니다. 해당 테스트의 결과는 FOR 루프 본문이 실행되는지 또는 컨트롤이 범위의 맨 아래에서 점프를지나 다음 명령으로 전송되는지 여부를 결정합니다.
  3. FER 루프 블록의 하단에서 증분 블록으로의 제어 전송이 있으므로 테스트가 실행되기 전에 인덱스 변수가 증가합니다. 이 동작은 왜 당신이 배운 방식으로 한계 조항을 코딩 해야하는지 설명 할뿐만 아니라 쉼표 연산자를 통해 추가하는 보조 증분에 영향을 미칩니다. 왜냐하면 그것이 세 번째 조항의 일부가되기 때문입니다. 따라서 첫 번째 반복에서는 변경되지 않지만 마지막 반복에 있으며 신체를 실행하지 않습니다.

루프가 종료 될 때 인덱스 변수 중 하나가 범위에 남아있는 경우, 실제 색인 변수의 경우 루프를 중지하는 임계 값보다 값이 높습니다. 마찬가지로, 예를 들어, 루프가 입력되기 전에 두 번째 변수가 0으로 초기화되면, 끝의 값은 반복 카운트가 될 것입니다. 루프의 본문은 그 값을 바꿉니다.

나는 squelart에 동의합니다. 두 가지 변수를 증가시키는 것은 버그가 발생합니다. 특히 그 중 하나만 테스트하는 경우.

이것은 읽을 수있는 방법입니다.

for(int i = 0; i < 5; ++i) {
    ++j;
    do_something(i, j);
}

For 루프는 루프가 하나의 증가/감소 변수에서 실행되는 경우입니다. 다른 변수의 경우 루프에서 변경하십시오.

필요한 경우 j 묶여 있습니다 i, 원래 변수를 그대로두고 추가하지 않는 이유는 무엇입니까? i?

for(int i = 0; i < 5; ++i) {
    do_something(i,a+i);
}

논리가 더 복잡한 경우 (예 : 실제로 둘 이상의 변수를 모니터링해야 함) while 고리.

int main(){
    int i=0;
    int a=0;
    for(i;i<5;i++,a++){
        printf("%d %d\n",a,i);
    } 
}

수학을 사용하십시오. 두 작업이 루프 반복에 수학적으로 의존하는 경우 수학을 수행하지 않겠습니까?

int i, j;//That have some meaningful values in them?
for( int counter = 0; counter < count_max; ++counter )
    do_something (counter+i, counter+j);

또는보다 구체적으로 OP의 예를 언급합니다.

for(int i = 0; i != 5; ++i)
    do_something(i, j+i);

특히 값으로 기능을 전달하는 경우 원하는 것을 정확하게 수행하는 무언가를 얻어야합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top