'for' 루프 내에서의 포스트 인크리먼트와 프리 인크리먼트에서도 동일한 출력이 생성됩니다.
하나는 포스트 인크리먼트, 다른 하나는 프리 인크리먼트를 사용해도 루프의 결과는 동일합니다.
코드는 다음과 같습니다.
for(i=0; i<5; i++) {
printf("%d", i);
}
for(i=0; i<5; ++i) {
printf("%d", i);
}
양쪽 'for' 루프에 대해 동일한 출력을 얻을 수 있습니다.내가 뭘 빼놓았나요?
후i++
★★★★★★★★★★★★★★★★★」++i
의 " " " "i
두 경우 모두 동일합니다.사전 및 사후 증가 간의 차이는 표현식 자체를 평가한 결과입니다.
++i
increi
새로운 가치로 평가합니다.i
.
i++
로 평가하다i
및, " " "i
.
for 루프에서는 이것이 문제가 되지 않는 이유는 컨트롤 플로우가 대략 다음과 같이 동작하기 때문입니다.
- 상태를 시험하다
- 거짓일 경우 종료합니다.
- 그것이 사실이라면, 본문을 처형하라.
- 증가 단계를 실행하다
(1)과 (4)는 분리되므로 사전 또는 사후 증가를 사용할 수 있습니다.
간단해요.의 「 」for
'루프'와 동등합니다.
int i = 0;
while(i < 5) {
printf("%d", i);
i++;
}
그리고.
int i = 0;
while(i < 5) {
printf("%d", i);
++i;
}
은 「」으로 되어 있는 것에 해 주세요.i++;
★★★★★★★★★★★★★★★★★」++i;
에서 동일한 . 다 .i
(1개씩 변환)하기 때문에 이들 루프의 동작에 동일한 영향을 미칩니다.
루프가 다음과 같이 고쳐지면 차이가 있음을 주의해 주십시오.
int i = 0;
int j = i;
while(j < 5) {
printf("%d", i);
j = ++i;
}
int i = 0;
int j = i;
while(j < 5) {
printf("%d", i);
j = i++;
}
는 코드 첫 코드 '''가j
를 i
후는)))i
번째, 즉 및 "Code"의 두 에서는 "Code "Code "는 "Code"의 두 번째 블록에서 합니다.j
를 i
이치노
코드 결과는 동일합니다.그 이유는 2개의 증분 연산이 2개의 서로 다른 함수 호출로 간주될 수 있기 때문입니다.두 함수에 따라 변수가 증가하며 반환값만 다릅니다.이 경우 반환값은 그냥 버려집니다.즉, 출력에 구별 가능한 차이는 없습니다.
하지만 후드 아래에는 차이가 있습니다.포스트 인크리먼트i++
원래 값을 저장하는 임시 변수를 생성해야 합니다.i
그러면 인크리먼트가 실행되고 일시 변수가 반환됩니다. 인크리먼트 「」++i
임시 변수는 생성되지 않습니다.물론,, 적절한 할 수 .int
단, 반복기처럼 복잡한 클래스에서는 ++-private가 과부하된다는 점에 유의하십시오.과부하된 두 메서드는 서로 다른 연산(예를 들어 stdout에 "Hey, I'm pre-increment!"를 출력하고 싶을 수 있음)을 가지고 있기 때문에 컴파일러는 반환값을 사용하지 않을 때 메서드가 동일한지 여부를 판단할 수 없습니다(기본적으로 이러한 컴파일러는 해결할 수 없는 정지 문제를 해결하기 때문에).따라서 더 비싼 메서드를 사용해야 합니다.포스트 인크리먼트버전(기입하는 경우)myiterator++
.
사전 증가를 해야 하는 세 가지 이유는 다음과 같습니다.
- 변수/개체에 오버로드된 사후 증분 메서드(템플릿 함수 등)가 있는지 여부를 고려하여 다르게 취급할 필요가 없습니다(또는 다른 취급을 잊어버릴 수도 있습니다).
- 일관된 코드가 더 보기 좋습니다.
- "왜 미리 증가시키느냐"는 질문을 받으면 컴파일러 최적화의 중단 문제와 이론적 한계에 대해 설명할 기회가 주어집니다.:)
이것은 제가 가장 좋아하는 인터뷰 질문 중 하나입니다.정답을 먼저 설명하고 제가 왜 이 질문을 좋아하는지 말씀드리겠습니다.
솔루션:
정답은 두 스니펫 모두 0부터 4까지의 숫자를 인쇄하는 것입니다.은, 「」가for()
으로는 루는는 loop loop loop a a a에 해당합니다.while()
디세이블로그:
for (INITIALIZER; CONDITION; OPERATION) {
do_stuff();
}
기입 가능:
INITIALIZER;
while(CONDITION) {
do_stuff();
OPERATION;
}
OPERATION은 항상 루프의 맨 아래에서 수행됨을 알 수 있습니다.이 형식에서는, 다음과 같은 것을 명확히 할 필요가 있습니다.i++
★★★★★★★★★★★★★★★★★」++i
같은 효과가 있을 것이다: 둘 다 증가하게 될 것이다.i
결과를 무시합니다.「」의 값.i
는 다음 반복이 시작될 때까지 루프 상부에서 테스트되지 않습니다.
편집: Jason이 지적해 주셔서 감사합니다.for()
로로 합니다.while()
루프가 제어문을 포함하는 경우 등가성은 유지되지 않습니다(예:continue
을하는 것입니다.OPERATION
을 while()
루우프OPERATION
항상 다음 반복 직전에 실행됩니다.for()
loopsyslog.syslog..syslog.
왜 좋은 인터뷰 질문인가
우선, 후보자가 바로 정답을 말하면 1, 2분이면 되기 때문에 바로 다음 문제로 넘어갈 수 있습니다.
그런데 의외로 많은 후보자가 인크리먼트 후의 루프는 0부터4까지의 숫자를 인쇄하고, 인크리먼트 전의 루프는 0부터5까지 또는 1~5까지 인쇄한다고 합니다. 증가 를 정확하게하지만, 증가 전과 증가 후의 알고 .for()
loopsyslog.syslog..syslog.
때는 '다'를 사용해서.while()
그리고 이것은 정말 그들의 사고 과정을 잘 알 수 있게 해준다.하는지, 내가 돌아가는지 을 제기할 때 알고 싶다.나는 그들이 어떤 문제에 어떻게 접근하는지, 그리고 내가 그들의 세상이 어떻게 돌아가는지에 대해 의문을 제기했을 때 그들이 어떻게 대처하는지 알고 싶다.
이 시점에서 대부분의 응시자들은 자신의 오류를 깨닫고 정답을 찾는다. 그의 하다가 번역 for()
while()
흥미로운 인터뷰가 되었지만, 우리는 제안을 하지 않았다!
도움이 됐으면 좋겠네요!
i++, ++i 모두 printf(%d, i) 실행 후 매번 실행되므로 차이가 없다.
어느 경우든 루프의 본문 뒤에 증가하기 때문에 루프의 계산에는 영향을 주지 않습니다.컴파일러가 우둔한 경우에는 (보통 나중에 사용하기 위해 pre 값의 복사본을 보관해야 하기 때문에) post-increment를 사용하는 것이 조금 덜 효율적일 수 있지만, 이 경우 어떤 차이도 최적화되지 않을까 생각합니다.
기본적으로 할당, 테스트 및 브랜치명령어 세트로 변환되는 for 루프의 실장 방법을 생각하면 편리할 수 있습니다.의사 코드의 프리 인크리먼트는 다음과 같습니다.
set i = 0
test: if i >= 5 goto done
call printf,"%d",i
set i = i + 1
goto test
done: nop
포스트 인크리먼트에는 적어도 다른 단계가 있습니다만, 최적화로 해소하는 것은 매우 간단합니다.
set i = 0
test: if i >= 5 goto done
call printf,"%d",i
set j = i // store value of i for later increment
set i = j + 1 // oops, we're incrementing right-away
goto test
done: nop
다음과 같은 경우에는 차이가 있습니다.
int main()
{
for(int i(0); i<2; printf("i = post increment in loop %d\n", i++))
{
cout << "inside post incement = " << i << endl;
}
for(int i(0); i<2; printf("i = pre increment in loop %d\n",++i))
{
cout << "inside pre incement = " << i << endl;
}
return 0;
}
그 결과:
내부 포스트 인스톨 =
i = 루프 0의 사후 증가
내부 포스트 인스톨 = 1
i = 루프 1의 사후 증가
두 번째 루프:
내부 프리 인스톨 = 0
i = 루프 1의 사전 증가
내부 프리 인스톨 = 1
i = 루프 2의 사전 증가
이렇게 쓰면 문제가 됩니다.
for(i=0; i<5; i=j++) {
printf("%d",i);
}
다음과 같이 쓴 경우보다 한 번 더 반복합니까?
for(i=0; i<5; i=++j) {
printf("%d",i);
}
컴파일러 번역
for (a; b; c)
{
...
}
로.
a;
while(b)
{
...
end:
c;
}
따라서 고객님의 경우(사후/사전 증가)는 문제가 되지 않습니다.
편집: 속행은 단순히 다음으로 대체됩니다.goto end;
구글의 답변은 이쪽에서 보실 수 있습니다.http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Preincrement_and_Predecrement
요점은 단순한 오브젝트에는 차이가 없지만 반복기 및 기타 템플릿오브젝트에는 프리 인크리먼트를 사용해야 한다는 것입니다.
편집:
단순한 유형을 사용하기 때문에 차이가 없습니다.따라서 부작용이 없고 루프 본문 후에 사후 또는 사전 증분이 실행되므로 루프 본문의 값에 영향을 주지 않습니다.
이러한 루프에서 확인할 수 있습니다.
for (int i = 0; i < 5; cout << "we still not incremented here: " << i << endl, i++)
{
cout << "inside loop body: " << i << endl;
}
네, 두 가지 출력 모두 정확하게 동일합니다.왜 그들이 당신에게 다른 결과를 제공해야 한다고 생각합니까?
다음과 같은 경우 증가 후 또는 증가 전 문제가 발생합니다.
int j = ++i;
int k = i++;
f(i++);
g(++i);
여기서 인수를 할당하거나 전달하여 값을 지정합니다. 다 안요.for
루프만 증가합니다.★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★!
for construct의 세 번째 문은 실행되었을 뿐 평가된 값은 폐기되고 처리되지 않습니다.
평가된 값이 폐기되면 사전 및 사후 증분이 동일합니다.
하다
언급URL : https://stackoverflow.com/questions/4706199/post-increment-and-pre-increment-within-a-for-loop-produce-same-output
'programing' 카테고리의 다른 글
.toArray(새로운 MyClass[0]) 또는 .toArray(새로운 MyClass[myList.size()])? (0) | 2022.08.09 |
---|---|
vue-router를 체크인합니다.각자가 루트에 대한 접근을 제한하지 않습니다. (0) | 2022.08.09 |
클래스가 최신 버전의 Java Environment로 컴파일되었습니다. (0) | 2022.08.09 |
pthread_cond_wait(&cond_t, &mutex);는 뮤텍스를 잠금 해제하고 잠글 수 있습니까? (0) | 2022.08.09 |
Java SE 8에는 페어 또는 튜플이 있습니까? (0) | 2022.08.09 |