0
for (i = 0; i < t; i++)
{
  values.clear();

  scanf("%d %d %d", &values[0], &values[1], &values[2]);
  printf("%d %d %d\n", values[0], values[1], values[2]);
  sort(values.begin(), values.end());
  printf("%d %d %d\n", values[0], values[1], values[2]);

  printf("Case %d: %d\n", i + 1, values[1]);
}

私はその小さなスニペットを持っています。「120015001800」と入力すると、中間値である1500が表示されるはずです。ただし、最小値である1200が出力されます。

私がやっていることは、STLのsort()を使用してベクトルをソートしてから、中間値であるvalues[1]を出力することです。

ただし、sort()はまったく機能していないようです。前後に出力されるベクトルは、同じものです。

私は自分のベクトルを次のように宣言します:

vector<int> values (3);

私はそれをで宣言しようとしましたvector<int> values;そしてそれからpush_back(0)3回そしてそれをしました。

しかし、なぜそれが最初の方法で機能しないのか疑問に思います。

4

5 に答える 5

6

プログラムの動作は未定義です。

これを修正するには、次の行を削除します。

values.clear();

上記の行は、実際には、ベクトルからすべての要素を消去することです。次に、この行:

scanf("%d %d %d", &values[0], &values[1], &values[2]);
                   ^^^^^^^^^   ^^^^^^^^^   ^^^^^^^^^

存在しない要素にアクセスしようとします。operator []連想コンテナの場合とは異なり、operator []ベクトルの場合は新しい要素を作成しません。したがって、式、、、values[0]およびvalues[1]values[2]すべて、存在しない要素にアクセスしようとします。

C ++ 11規格の表101によると:

a[n]

戻りタイプ:参照; const_reference定数の場合a

操作的意味論*(a.begin() + n)

これは、これを行うことによって:

values[0]

あなたは実際にこれをやっています:

*(values.begin() + 0)

ここを呼び出すとvalues.begin()、配列の最初の要素にイテレータが返されます。ベクトル(§23.2.1/ 6)には要素がないため、への呼び出しは:values.begin()への呼び出しと同等です。values.end()

begin()コンテナの最初の要素を参照するイテレータを返します。end()コンテナの終了後の値であるイテレータを返します。コンテナが空の場合、begin() == end();

したがって、values[0]あなたの場合、実際にはこれと同等です:

*(values.end() + 0)

これは、これと同等です。

*(values.end())

つまり、コンテナ内の最後の要素を超えた位置を指すイテレータを間接参照しています。これは未定義動作であり、もちろん同じことがとにも当てはまりvalues[1]ますvalues[2]

于 2013-03-24T14:15:00.647 に答える
5
values.clear();

これによりクリアvaluesされ、要素が含まれなくなります。要素にアクセスしようとすると、未定義の動作が発生しstd::sort、空の数列が単純にソートされます。

シーケンスコンテナがa.clear()どこにあるかの定義は次のとおりです。a

内のすべての要素を破棄しますa。の要素を参照するすべての参照、ポインター、およびイテレーターをa無効にし、過去のイテレーターを無効にする場合があります。
posta.empty()trueを返します

于 2013-03-24T14:14:28.920 に答える
1

<アルゴリズム>ヘッダーの__median関数の方が簡単だと思います 。

med = __median(a, b, c);
于 2013-03-24T14:22:04.930 に答える
0

クリアするvectorと、サイズを0に設定します。通常、読み取り値が格納されるストレージが事前に割り当てられているため、通常scanf、行はクラッシュしません。vectorその結果、を呼び出すと、sortが等しくなります。begin()end()

値を一時的に読み取るか、値をresize(3)読み取る前に呼び出すことを試すことができます。

于 2013-03-24T14:19:42.053 に答える
0

で実際の既存の要素をクリアしようとする試みは、実際にvalues.clear();はそれらをベクトルから完全に削除することです。これには、作成begin()end()等化の効果があり、ソートは効果がありません(そして、さまざまな要素のアドレスを取得する入力は、未定義の動作をします)。

あなたが本当にやりたかったのは、ベクトルに要素が多すぎないことを確認することだったと思います。そのため、使用する代わりに、余分clearな要素を削除するか、ベクトルのサイズを現在小さい場合は3に増やす効果があります。 。resizevalues.resize(3)

于 2013-03-24T14:21:21.730 に答える