이것이 실행될 때 (커튼 뒤) 어떻게됩니까?
int x = 7;
x = x++;
즉, 변수가 포스트 증분되어 하나의 명령문으로 자체에 할당되는 경우입니다. 나는 이것을 컴파일하고 실행했다. 전체 진술 후에도x
여전히 7 입니다. 내 책에는 그것이 증가 한다고 말합니다 !x
답변
x
증가합니다. 그러나 당신은 이전의 가치를 x
다시 부여하고 있습니다.
x = x++;
x++
증가x
하고 이전 값을 반환합니다.x =
이전 값을 다시 자신에게 할당합니다.
결국, x
초기 값으로 다시 할당됩니다.
답변
x = x++;
에 해당
int tmp = x;
x++;
x = tmp;
답변
진술 :
x = x++;
다음과 같습니다.
tmp = x; // ... this is capturing the value of "x++"
x = x + 1; // ... this is the effect of the increment operation in "x++" which
// happens after the value is captured.
x = tmp; // ... this is the effect of assignment operation which is
// (unfortunately) clobbering the incremented value.
요컨대, 그 진술은 효력이 없다.
요점 :
-
Postfix 증가 / 감소 표현식의 값은 증가 / 감소가 발생 하기 전의 피연산자 값입니다 . (접두사 양식의 경우 값은 연산 후 피연산자의 값입니다. )
-
값이 LHS에 할당 되기 전에 할당 표현식의 RHS가 완전히 평가됩니다 (증가, 감소 및 / 또는 기타 부작용 포함) .
C 및 C ++와 달리 Java의 표현식 평가 순서는 완전히 지정되며 플랫폼 별 변형의 여지가 없습니다. 컴파일러는 현재 스레드의 관점에서 코드 실행 결과를 변경하지 않는 경우에만 작업 순서를 다시 지정할 수 있습니다. 이 경우 컴파일러는 명령문이 작동하지 않음을 증명할 수 있으므로 전체 명령문을 최적화 할 수 있습니다.
아직 명확하지 않은 경우 :
- “x = x ++;” 거의 모든 프로그램에서 실수입니다.
- OP (원래 질문에 대한)는 아마도 “x ++;”를 의미했을 것입니다. “x = x ++;”대신.
- 같은 변수에 대한 자동 증가 / 감소와 할당을 결합한 문장은 이해하기 어렵 기 때문에 정확성에 관계없이 피해야 합니다 . 그런 코드를 작성할 필요는 없습니다.
다행히 FindBugs 및 PMD와 같은 코드 검사기는 이와 같은 코드를 의심스러운 것으로 플래그 지정합니다.
답변
int x = 7;
x = x++;
C에서는 동작이 정의되어 있지 않으며 Java의 경우이 답변을 참조하십시오 . 컴파일러에 따라 달라집니다.
답변
다음과 같은 구조 x = x++;
는 ++
운영자가 수행 하는 작업을 오해하고 있음을 나타냅니다 .
// original code
int x = 7;
x = x++;
++
연산자 를 제거하여 동일한 작업을 수행하도록 이것을 다시 작성해 보겠습니다 .
// behaves the same as the original code
int x = 7;
int tmp = x; // value of tmp here is 7
x = x + 1; // x temporarily equals 8 (this is the evaluation of ++)
x = tmp; // oops! we overwrote y with 7
자, 당신이 원했던대로 (내 생각에) 다시 작성해 봅시다.
// original code
int x = 7;
x++;
여기서 미묘한 점은 ++
연산자 는x
x + x
int 값으로 평가되지만 변수 x
자체는 변경되지 않은 상태 와 같은 식과 달리 변수를 수정한다는 것 입니다. 훌륭한 for
루프 와 같은 구성을 고려하십시오 .
for(int i = 0; i < 10; i++)
{
System.out.println(i);
}
i++
거기에 주목 ? 같은 연산자입니다. 이 for
루프를 다음과 같이 다시 작성할 수 있으며 동일한 동작을합니다.
for(int i = 0; i < 10; i = i + 1)
{
System.out.println(i);
}
또한 ++
대부분의 경우 연산자를 더 큰 식으로 사용하지 않는 것이 좋습니다 . 사전 및 사후 증분 ( 및) 에서 원래 변수를 수정할 때 의 미묘함 때문에 추적하기 어려운 미묘한 버그를 쉽게 도입 할 수 있습니다.++x
x++
답변
클래스 파일에서 얻은 바이트 코드에 따르면
두 할당 모두 x를 증가 시키지만 차이는 when the value is pushed onto the stack
에서 Case1
, 증가 이전에 푸시가 발생했다가 나중에 할당됩니다.
Case2
에서 증가가 먼저 발생 하여 (8) 스택에 푸시 된 다음 x에 할당됩니다.
사례 1 :
int x=7;
x=x++;
바이트 코드 :
0 bipush 7 //Push 7 onto stack
2 istore_1 [x] //Pop 7 and store in x
3 iload_1 [x] //Push 7 onto stack
4 iinc 1 1 [x] //Increment x by 1 (x=8)
7 istore_1 [x] //Pop 7 and store in x
8 return //x now has 7
사례 2 :
int x=7;
x=++x;
바이트 코드
0 bipush 7 //Push 7 onto stack
2 istore_1 [x] //Pop 7 and store in x
3 iinc 1 1 [x] //Increment x by 1 (x=8)
6 iload_1 [x] //Push x onto stack
7 istore_1 [x] //Pop 8 and store in x
8 return //x now has 8
- 여기서 스택은 피연산자 스택, 로컬 : x 인덱스 : 1 유형 : int를 나타냅니다.
답변
” x = x++;
” 다음에 증가 합니다. ” x = ++x;
“를 수행 하면 8이됩니다 .