[java] “x = x ++”다음에 x는 무엇입니까?

이것이 실행될 때 (커튼 뒤) 어떻게됩니까?

int x = 7;
x = x++;

즉, 변수가 포스트 증분되어 하나의 명령문으로 자체에 할당되는 경우입니다. 나는 이것을 컴파일하고 실행했다. 전체 진술 후에도x 여전히 7 입니다. 내 책에는 그것이 증가 한다고 말합니다 !x



답변

x증가합니다. 그러나 당신은 이전의 가치를 x다시 부여하고 있습니다.


x = x++;
  1. x++증가 x하고 이전 값을 반환합니다.
  2. 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++;

여기서 미묘한 점은 ++연산자 xx + 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);
}

또한 ++대부분의 경우 연산자를 더 큰 식으로 사용하지 않는 것이 좋습니다 . 사전 및 사후 증분 ( 및) 에서 원래 변수를 수정할 의 미묘함 때문에 추적하기 어려운 미묘한 버그를 쉽게 도입 할 수 있습니다.++xx++


답변

클래스 파일에서 얻은 바이트 코드에 따르면

두 할당 모두 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이됩니다 .