web-dev-qa-db-ja.com

memsetは整数の配列を-1で初期化する方法は?

manpagememsetについて述べています:

_#include <string.h>
void *memset(void *s, int c, size_t n)
_

memset()関数は、nが指すメモリ領域の最初のsbytesを埋めます。定数バイトcを使用します。

以下に示すように、memsetを使用してint配列を初期化できないことは明らかです。

_int a[10];
memset(a, 1, sizeof(a));  
_

これは、intが4バイト(たとえば)で表され、配列aの整数に必要な値を取得できないためです。
しかし、プログラマはmemsetを使用してint配列要素を_0_または_-1_に設定することがよくあります。

_int a[10];
int b[10];
memset(a, 0, sizeof(a));  
memset(b, -1, sizeof(b));  
_

私の理解では、整数_0_で初期化することは問題ありません。なぜなら_0_は1バイトで表現できるからです(このコンテキストでは間違っているかもしれません)。しかし、bを_-1_(4バイトの値)で初期化する方法はありますか?

61
haccks

奇妙なことに、これが-1で動作する理由は、これがゼロで動作する理由とまったく同じです。in 2の補数バイナリ表現-11sすべてのビットは、整数のサイズに関係なく、すべての1sで埋められたバイトで領域を埋めると、-1符号付きints、longsの領域が生成されます。 、および2の補数のハードウェア上のshorts。

2の補数とは異なるハードウェアでは、結果は異なります。 -1整数定数は、すべてが1のunsigned charに変換されます。これは、標準が変換の実行方法に固有であるためです。ただし、すべてのビットが1に設定されているバイトの領域は、プラットフォームの規則に従って整数値として解釈されます。たとえば、符号と大きさのハードウェアでは、配列のすべての要素に、対応する型の最小の負の値が含まれます。

69
dasblinkenlight

数値のすべてのビットが_0_の場合、その値もです。ただし、すべてのビットが_1_の場合、値は-1です。


_int a[2]_を書き込むと、 4x2 バイトのメモリが割り当てられます。

_00110000 00100101 11100011 11110010    11110101 10001001 00111000 00010001
_


次に、memset(a, 0, sizeof(a))と記述します。現在、memset()intcharを区別しません。 バイト単位で動作します。 の1バイト表現は_00000000_です。それで、

_00000000 00000000 00000000 00000000    00000000 00000000 00000000 00000000
_

したがって、_a[0]_と_a[1]_は両方ともで初期化されます。


今、memset(a, -1, sizeof(a))を見てみましょう:-1の1バイトは_11111111_です。そして、私たちは-

_11111111 11111111 11111111 11111111    11111111 11111111 11111111 11111111
_

ここでは、_a[0]_と_a[1]_の両方の値は-1になります。


ただし、memset(a, 1, sizeof(a))の場合:1バイトの1は_00000001_-

_00000001 00000001 00000001 00000001    00000001 00000001 00000001 00000001
_

したがって、値は-16843009になります。

3
Minhas Kamal