이것이 실행될 때 (커튼 뒤) 어떻게됩니까?
int x = 7;
x = x++;
즉, 변수가 포스트 증분되어 하나의 명령문으로 자체에 할당되는 경우입니다. 나는 이것을 컴파일하고 실행했다. 전체 진술 후에도x
여전히 7 입니다. 내 책에는 그것이 증가 한다고 말합니다 !x
x += 1
루프를 제외하고는 을 사용하고 싶습니다 . for(int x=0; x<7; x++)
이것이 실행될 때 (커튼 뒤) 어떻게됩니까?
int x = 7;
x = x++;
즉, 변수가 포스트 증분되어 하나의 명령문으로 자체에 할당되는 경우입니다. 나는 이것을 컴파일하고 실행했다. 전체 진술 후에도x
여전히 7 입니다. 내 책에는 그것이 증가 한다고 말합니다 !x
x += 1
루프를 제외하고는 을 사용하고 싶습니다 . for(int x=0; x<7; x++)
답변:
x
증가합니다. 그러나 당신은 이전의 가치를 x
다시 부여하고 있습니다.
x = x++;
x++
증가 x
하고 이전 값을 반환합니다.x =
이전 값을 다시 자신에게 할당합니다.결국, x
초기 값으로 다시 할당됩니다.
x = x++;
에 해당
int tmp = x;
x++;
x = tmp;
x=x+1
대신 해야했을 것 입니다x++
x = x++
포스트 증가가 아니라 전체 문장을 의미했습니다 x++
.
x = ++x;
것은 사실이 int tmp = x; ++x; x = tmp;
아니므로 어떤 논리에 의해 귀하의 답변이 정확하다고 판단 할 수 있습니까?
x=x++
=MOV x,tmp; INC x; MOV tmp,x
진술 :
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의 표현식 평가 순서는 완전히 지정되며 플랫폼 별 변형의 여지가 없습니다. 컴파일러는 현재 스레드의 관점에서 코드 실행 결과를 변경하지 않는 경우에만 작업 순서를 다시 지정할 수 있습니다. 이 경우 컴파일러는 명령문이 작동하지 않음을 증명할 수 있으므로 전체 명령문을 최적화 할 수 있습니다.
아직 명확하지 않은 경우 :
다행히 FindBugs 및 PMD와 같은 코드 검사기는 이와 같은 코드를 의심스러운 것으로 플래그 지정합니다.
x++
대신 대신 말하는 것을 의미합니다 x = x++
.
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
사후 증가 연산자는 다음과 같이 작동합니다.
그래서 진술
int x = 7;
x = x++;
다음과 같이 평가됩니다.
따라서 x는 실제로 증가하지만 x ++는 결과를 x에 다시 할당하므로 x의 값은 이전 값으로 재정의됩니다.
x ++는 변수에 값을 할당 한 후 값을 증가시키기 때문입니다. 그래서이 줄을 실행하는 동안 :
x++;
varialbe x는 여전히 원래 값 (7)을 가지지 만 다른 행에서 x를 다시 사용합니다 (예 :
System.out.println(x + "");
당신에게 줄 것이다 8.
과제 명세서에 증분 된 x 값을 사용하려면
++x;
이것은 x를 1 씩 증가시키고, 그 값을 변수 x에 할당합니다.
x = x ++ 대신 [편집], 그것은 단지 x ++입니다; 전자는 x의 원래 값을 자신에게 할당하므로 실제로 해당 줄에 아무것도 수행하지 않습니다.
언제 발생 int x = 7; x = x++;
합니까?
ans-> x++
는 먼저 표현식에 x 값을 사용한 다음 1 씩 증가시키는 것을 의미합니다.
이것은 귀하의 경우에 발생합니다. RHS의 x 값은 LHS의 변수 x에 복사 된 다음 x
1의 값 이 증가합니다.
마찬가지로 x의 값을 먼저 증가시킨 다음 expression에 사용하는 ++x
것을 의미 ->
합니다.
따라서 귀하의 경우 x = ++x ; // where x = 7
에는 8의 가치를 얻습니다.
더 명확하게 보려면 다음 코드를 실행할 printf 문 수를 찾으십시오.
while(i++ <5)
printf("%d" , ++i); // This might clear your concept upto great extend
x
8이되지만 7과
++x
사전 증분 ->
x는 사용 전에 증분 되고
x++
사후 증분 ->
x는 사용 후 증분 됩니다
int x = 7; -> x get 7 value <br>
x = x++; -> x get x value AND only then x is incremented
따라서 이것은 다음
x++
과 같습니다.x = x+1
때문에:
int x = 7; x = x++;
x is 7
int x = 7; x = x = x+1;
x is 8
이제는 조금 이상해 보입니다.
int x = 7; x = x+=1;
x is 8
매우 컴파일러에 의존합니다!
(x = x + 1, x-1)
쉼표로 구분 된 표현이 허용되는 C 와 같습니다 .
이 논쟁은 코드에 들어 가지 않고 그냥 생각하지 않고도 해결할 수 있다고 생각합니다.
Func1 & Func2와 같이 i ++ & ++ i를 함수로 생각하십시오.
이제 i = 7;
Func1 (i ++)은 7을 반환하고 Func2 (++ i)는 8을 반환합니다 (모두 알고 있음). 내부적으로 두 함수 모두 i ~ 8을 증가 시키지만 다른 값을 반환합니다.
따라서 i = i ++는 Func1 함수를 호출합니다. 함수 내에서 i는 8로 증가하지만 완료되면 함수는 7을 반환합니다.
따라서 궁극적으로 7은 i에 할당됩니다. (결국 i = 7)
int x = 7; x = ++x;
물론 여전히 끔찍한 코드이므로 다시 할당 할 필요가 없습니다.int x = 7; x++;
충분하다.