0

配列の内容をシフトするには、できるだけ効率的な手段が必要です。配列の各位置の内容を 1 つ右にシフトし、最初の位置を無視して、そこに新しい値を書き込めるようにする必要があります。

ここに私が持っているものがあります:

#define LENGTH 5

int myArray[LENGTH] = {1, 2, 3, 4, 5};

int *pa = myArray + (LENGTH - 1);

for (ushort i = 5; i > 0; i--) {
    *pa = *(pa - 1);
    pa--;
}

私がやりたいのは、forループの 2 行を 1 つの操作に結合することです。何かのようなもの:

*pa = *(pa--);

ただし、この結果は未定義です。すでに使用しているものにこだわっていますか?

編集:これは私が使用している実際のコードではないことを明確にする必要がありました。私が求めていた構造を示す簡単な例です。

4

5 に答える 5

6

あなたが本当にこれをする必要があるならば、memmoveおそらくあなたの最良の選択になるでしょう。

ただし、可能であれば、完全に回避することをお勧めします。現在のコンテンツをシフトして新しいアイテム用のスペースを確保する代わりに、配列内の「最も古い」場所へのポインターを保持します。新しいアイテムを追加する必要がある場合は、のような操作を行います*new_pos++ = new_item;

データを読み取る必要がある場合はnew_pos+1、次の5つの項目から始めて読み通しますが、インクリメントするたびに行う% LENGTHので、配列の最後に到達すると、最初に「ラップアラウンド」します。 。

于 2011-01-29T17:12:57.093 に答える
5

効率は行数では測定されないため、この方法でコードを「圧縮」しようとしても何も得られません。

最後の要素を削除する場合、このシフトがまったく必要ないように、配列の代わりに循環バッファーを使用することをお勧めします。要素へのアクセスのコストはわずかに増加しますが、LENGTH が 2 の累乗に等しい場合、そのコストは非常に小さくなります。

于 2011-01-29T17:11:03.137 に答える
0

memmove(3)

于 2011-01-29T17:12:43.157 に答える
0
*pa = *(pa--);

ただし、この結果は未定義です。私はすでに使用しているものに固執していますか?

はい。また、これを気にしないでください。あなたのコンパイラは賢いです。これが1行か2行にあるかどうかに関係なく、これを行う効率的な方法がわかります。

おそらくもっと最適化された何かをしたい場合は、ループの代わりにmemmoveを使用してください

memmove(&myArray[1],&myArray[0],(sizeof myArray - 1)*sizeof *myArray);
于 2011-01-29T17:12:45.747 に答える
0

おそらく、整数の配列内の要素をシフトすることは、優れたオプティマイザーが処理できるものです。しかし、本当にアセンブラーの命令について心配する必要があるのでしょうか? プロファイルを作成し、問題があることを発見しましたか?

それがボトルネックである場合、アルゴリズムで変更できるものがある可能性があります...たとえば、なぜそのシフトを行う必要があるのですか? バッファが固定サイズの場合、それを循環バッファとして使用しないのはなぜですか?

于 2011-01-29T17:21:12.597 に答える