C ++ 'for'루프에 두 개의 증분 문을 어떻게 교체합니까?
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 (int i = 0; i != 5; ++i, ++j)
do_something(i, j);
FOR 루프의 증분 절에 두 번째 인덱스를 코딩하는 방법을 상기하기 위해 여기에 왔습니다. 주로 C ++로 작성된 다른 프로젝트에 통합 한 샘플에서이를 관찰함으로써 수행 할 수 있다는 것을 알고있었습니다.
오늘 저는 C #으로 작업하고 있지만 FOR 문이 모든 프로그래밍에서 가장 오래된 제어 구조 중 하나이기 때문에 이와 관련하여 동일한 규칙을 따를 것이라고 확신했습니다. 고맙게도 저는 최근에 이전 C 프로그램 중 하나에서 FOR 루프의 동작을 정확하게 문서화하는 데 며칠을 보냈으며 그 연구에서 오늘날의 C # 문제, 특히 두 번째 인덱스 변수의 동작에 적용되는 교훈이 있다는 것을 금방 깨달았습니다. .
다음은 내 관찰에 대한 요약입니다. 오늘 내가 본 모든 일은 Locals 창에서 변수를주의 깊게 관찰함으로써 C # FOR 문이 C 또는 C ++ FOR 문과 똑같이 작동한다는 내 기대를 확인했습니다.
- FOR 루프가 처음 실행되면 증가 절 (3 개 중 3 번째 절)을 건너 뜁니다. Visual C 및 C ++에서 증분은 루프를 구현하는 블록 중간에 3 개의 기계 명령어로 생성되므로 초기 단계에서 초기화 코드를 한 번만 실행 한 다음 증분 블록을 건너 뛰어 종료 테스트를 실행합니다. 이는 인덱스 및 제한 변수의 상태에 따라 FOR 루프가 0 회 이상 실행되는 기능을 구현합니다.
- 루프의 본문이 실행되는 경우 마지막 문은 첫 번째 반복에서 건너 뛴 세 개의 증가 명령 중 첫 번째로의 점프입니다. 이러한 실행 후 제어는 자연스럽게 middle 절을 구현하는 제한 테스트 코드로 떨어집니다. 해당 테스트의 결과는 FOR 루프의 본문이 실행되는지 또는 제어가 해당 범위의 맨 아래에있는 점프를지나 다음 명령어로 전송되는지 여부를 결정합니다.
- 제어는 FOR 루프 블록의 맨 아래에서 증가 블록으로 전송되기 때문에 테스트가 실행되기 전에 인덱스 변수가 증가합니다. 이 동작은 학습 한 방식으로 제한 절을 코딩해야하는 이유를 설명 할뿐만 아니라 쉼표 연산자를 통해 추가하는 보조 증분에 영향을줍니다. 이는 세 번째 절의 일부가되기 때문입니다. 따라서 첫 번째 반복에서 변경되지 않고 본문을 실행하지 않는 마지막 반복에서 변경됩니다.
루프가 끝날 때 인덱스 변수 중 하나가 범위에 남아 있으면 해당 값은 실제 인덱스 변수의 경우 루프를 중지하는 임계 값보다 하나 더 높습니다. 마찬가지로, 예를 들어 두 번째 변수가 루프에 들어가기 전에 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);
특히 값으로 함수에 전달하는 경우 원하는 것을 정확히 수행하는 무언가를 얻어야합니다.
참고 URL : https://stackoverflow.com/questions/1232176/how-do-i-put-two-increment-statements-in-ac-for-loop
'ProgramingTip' 카테고리의 다른 글
프록시 뒤에서 sbt를 사용하는 방법은 무엇입니까? (0) | 2020.10.04 |
---|---|
"Microsoft .NET Core 1.0.0 RC2-VS 2015 Tooling Preview 1"을 제거해야합니까? (0) | 2020.10.04 |
롤백으로 만 트랜잭션 : 원인을 어떻게 찾습니까? (0) | 2020.10.04 |
활동이 시작될 때 스낵바를 표시하는 방법은 무엇입니까? (0) | 2020.10.04 |
ASP.NET Core 2.0으로 업그레이드 한 후 마이그레이션을 만들 수 없습니다. (0) | 2020.10.04 |