-2

変数を使用した後、後置演算子のインクリメント値を知っています。しかし、この場合、それは有効なステートメントですか? returnステートメントの後に変数を変更しているように見えるからです。

#include <iostream>

using namespace std;

int val = 0;

int foo()
{
        return val++;
}

int main()
{
        cout<<foo();
        cout<<endl<<val;
}

どんな詳細でも役に立ちます。

4

4 に答える 4

6

return val++最初に戻りval、次にインクリメントすると言うのは、まったく正しくありませ。式val++は の値をインクリメントしますがval、の古い値に評価さvalれます。

++接尾辞は、ヘルパー変数を使用して古い値を保持する関数と考えることができます。

int temp = val; // save old value to temp
++val;          // increment actual value
return temp;    // evaluate to old value
于 2015-03-25T01:47:55.963 に答える
2

はい、有効です。

val戻ってからインクリメントするとは考えないでください。

代わりに、操作の結果を返していますval++

于 2015-03-25T01:29:47.267 に答える
2

お気づきvalかもしれませんが、グローバル変数です。

を呼び出すとfoo()

int foo()
{
    return val++;
}

val最初に が返され0次にの値がインクリメントされるvalため、 になりval = 1ます。

ゼニスが引用したように、

val++は の値をインクリメントしますがval、インクリメントする前の の値に評価さvalれます。

ここで、coutvalvalは明らかに 1 であるため、出力は正当化されます。

于 2015-03-25T01:46:37.163 に答える
1

コードを表現するためにコンパイラが実行した正確な手順を確認するために、逆アセンブリを調べました。

行 00324C2E は、グローバル変数「val」の値を CPU の eax レジスタにコピーします。

行 00324C33 は、値を eax から「foo」関数のローカル スタック スペースにコピーします。

行 00324C39 は、グローバル変数「val」の値を CPU の ecx レジスタにコピーします。

行 00324C3F は、ecx レジスターの値に 1 を追加します。

行 00324C42 は、インクリメントされた値を ecx レジスタからグローバル変数「var」にコピーします。

行 00324C48 は、「foo」関数のローカル スタック スペース (上記の行 00324C33 を参照) に格納された値の影響を受けないコピーを CPU の eax レジスタにコピーします。これは、呼び出し元の関数 (この場合は "main") に返される値であるため、eax レジスタにコピーされます。

したがって、foo() からは 0 が返されますが、foo() が返された後、グローバル変数「val」には 1 が含まれます。


int foo()
{
  00324C10  push        ebp  
  00324C11  mov         ebp,esp  
  00324C13  sub         esp,0C4h  
  00324C19  push        ebx  
  00324C1A  push        esi  
  00324C1B  push        edi  
  00324C1C  lea         edi,[ebp-0C4h]  
  00324C22  mov         ecx,31h  
  00324C27  mov         eax,0CCCCCCCCh  
  00324C2C  rep stos    dword ptr es:[edi]  
      return val++;
  00324C2E  mov         eax,dword ptr ds:[0032F320h]  
  00324C33  mov         dword ptr [ebp-0C4h],eax  
  00324C39  mov         ecx,dword ptr ds:[32F320h]  
  00324C3F  add         ecx,1  
  00324C42  mov         dword ptr ds:[32F320h],ecx  
  00324C48  mov         eax,dword ptr [ebp-0C4h]  
}
于 2015-03-25T02:41:41.310 に答える