1

私はC ++が初めてで、これに出くわしました:

    for (int i=0 ; i<500 ; i++) {
        //to do
    }

    int i;
    std::cin >> i;

更新: Visual Studio 2010 (およびそれが使用するコンパイラ) を使用すると、for ループの外側の i の値は、cin >> i; の呼び出し後に 500 になります。Visual Studio デバッガー << を使用して値を見ています (これが問題です - Greg に感謝します)

今私は期待した

a) int i; for ループと int i=0; の外側。異なる変数、つまり for ループ i は中かっこが閉じると範囲外になります

b) それが範囲外に出ていないことに気づいたら、なぜ cin によって上書きされないのか疑問に思いました。

b) は意図的なものだと思います (ただし、Bjarne Stroustrup の C++ に関する本でそのページを見つけるのに苦労しています) が、同じ本の中で、変数はそれらが囲まれた中括弧内にスコープを持つと述べていると確信しています。

他のほとんどの言語では、for コンストラクトで変数を宣言するときに、for ループの中括弧内にあると見なされることを知っていますが、C++ ではそうではないようです。

これは当てはまりますか、これはforループに固有のものですか、それともこれが発生する他のケースはありますか(他には考えられませんが、私は新しいです)

ありがとう

4

4 に答える 4

3

状況によっては、特にこの場合、同じ関数内に同じ名前の 2 つの異なる変数がある場合、デバッガーが正しい情報を提供することを常に信頼できるとは限りません。の値を要求している場合、デバッガーは、あなたが参照しているものをi正確に認識できない可能性があります。iあなたが説明したことから、コンパイラは の異なるインスタンスごとに 2 つの異なるメモリ位置を割り当てたようですi

私はよくこの原則を使います。を使用すると、出力を印刷する時点でスコープ内にあるの実際の値がstd::cout << i表示されるはずです。i

于 2012-12-28T11:32:29.600 に答える
2

うーん、たくさんの答えがあり、「解決策」として選択されたものさえあります。

とにかく、Visual C++ 10.0 (Visual Studio 2010 に同梱されているコンパイラ) の問題は、デフォルトはforループで宣言された変数のスコープが、ループが配置されたブロックの外に拡張される、標準化前の動作に構成できます。

このオプションが必要です:

/Zc:forScope,wchar_t

これにより、標準の C++forスコープと組み込みwchar_t型が有効になり、これが必要になります。

/GR

RTTI を有効にします (つまりdynamic_casttypeid)。

できる限り標準にするために、このリンカーオプションも必要です。

/entry:mainCRTStartup

GUI サブシステム プログラムの C++ 標準を有効にするにmainは、もちろん例外処理を有効にしたいのですが、(コマンド ライン コンパイラではなく) デフォルトで有効になっている Visual C++ プロジェクトを思い出してください。

/W4また、もちろん、標準への準拠とは何の関係もありませんが、 を介してできるだけ多くの警告を有効にしたいと考えています。

とにかく、まとめると、おかしなforスコープが表示される理由は、コンパイラや Visual Studio プロジェクトが原因である可能性が最も高いです。不履行古い標準化前のルールに設定されていて、そのためのオプションは/Zc:forScope.

于 2012-12-28T13:11:55.257 に答える
0

適合していると仮定すると(そして、その点でコンパイラが適合していないと、おそらくコンパイルエラーが発生するでしょう)、2つiは異なります。ただし、ライブ時間も異なるため、コンパイラが両方に同じメモリ位置を使用することを妨げるものはありません。したがって、i初期化されていないため、最初の値から2番目の値が開始されることが予想されます。

cin >> i新しい値を入力できないという事実は、それとは無関係です。そして、あなたは理由を推測する以上のことをするのに十分な情報を与えていません(私の推測では、ストリームはエラー状態にあります)。

于 2012-12-28T11:14:30.913 に答える
0

2番目のiが初期化されておらず、コンパイラが2番目のiに同じメモリブロックを使用するために発生すると思います。それらはまだ異なる2つの変数です。はい、最初の i はループにスクープされます。したがって、未定義であり、2 番目の i が 500 であるとは期待できません。

for (int i=0 ; i<500 ; i++) {
    //to do
}

int i=0;  //  initialize i
std::cin >> i;
于 2012-12-28T11:24:56.373 に答える