intの配列があり、関数が呼び出されるたびに配列内のすべての値を「x」に設定したいと思います。
memsetを見てきましたが、それは私が思うバイトの配列に対してのみ機能します。
明らかなforループを実行することはできますが、これをより適切に実行する標準のlib関数があると思います。誰か知ってる?
intの配列があり、関数が呼び出されるたびに配列内のすべての値を「x」に設定したいと思います。
memsetを見てきましたが、それは私が思うバイトの配列に対してのみ機能します。
明らかなforループを実行することはできますが、これをより適切に実行する標準のlib関数があると思います。誰か知ってる?
ループするだけです。またはmemset
、値がゼロであることがわかっている場合は0に設定します(ビット表現の知識がある他の値の場合も同様です)。標準ライブラリは特定のユーザータイプを認識できないため、標準ライブラリソリューションはありません。
x86システムを使用している場合は、このためにいくつかのアセンブリを使用できます。たとえば、gccでは次のようになります。
__asm__(
"rep stosb"
: "=a"('x'), "=c"(count), "=D"(array)
);
トリックを行う必要があります。
rep stosb
の値を受け取り、AL
それを。が指す連続するメモリ位置に割り当てますES:EDI
。場所の数はで指定されECX
ます。
余談ですが、最近のプロセッサでは、 Intelはとのパフォーマンスを改善するために多くの努力を払ってきたMOVSB
STOSB
ので、これはそれを実行するための良い方法です。
memset
ループ(両方ともO(n)
時間)に加えて、実際にはで実行できますがO(1)
、メモリ量が3倍になり、後でルックアップするコストが高くなります。
この記事では、その方法について説明します。
アイデアは、追加のスタック(論理的には、配列+先頭へのポインターとして実装)と配列を維持することです。追加の配列は、最初に初期化された日時(0からnまでの数値)を示し、スタックは、どの要素が既に変更されたかを示します。
アクセスするとき、配列の値が。のarray[i]
場合。それ以外の場合は、「初期化された」値です。stack[additionalArray[i]] == i && i < top
array[i]
を実行するときarray[i] = x
に、まだ初期化されていない場合(前に見たように)、を設定additionalArray[i] = stack[top]
して増やす必要がありますtop
。
これによりO(1)
初期化が行われますが、前述のように、追加のメモリが必要であり、各アクセスはより拡張性があります。
以下のロジックが役立ちます。
...
int a[100] = {0};
int b = 5;
memset_ex(a, 100, &b, sizeof(int));
...
memset_ex(void *buf, int buf_size, void *value, int size_of_type)
{
int i = 0;
for(i = 0; i <= (buf_size - size_of_type); i +=size_of_type)
{
memcpy((buf + i), value, size_of_type);
}
}