27

Why is the output of the following program 84215045?

int grid[110];
int main()
{
    memset(grid, 5, 100 * sizeof(int));
    printf("%d", grid[0]);
    return 0;
}
4

9 に答える 9

6

memset を使用しないでください。

メモリの各バイト[]を値 5 に設定します。各 int は 4 バイトの長さ[5][5][5][5]で、コンパイラはこれを 5*256*256*256 + 5*256*256 + 5*256 + 5 = 84215045 として正しく解釈します。代わりに、 sizeof() も必要としない for ループを使用します。一般に、 sizeof() は、何か難しいことをしていることを意味します。

for(int i=0; i<110; ++i)
    grid[i] = 5;
于 2011-08-17T23:02:27.743 に答える
2

プログラムで何をしたいのかを実際に言っていません。

の最初の 100 個の要素のそれぞれを 5 に設定したいと仮定すると(対の不一致gridは無視して)、次のようにします。100110

for (int i = 0; i < 100; i ++) {
    grid[i] = 5;
}

あなたが速度を気にしているのは理解していますが、あなたの懸念はおそらく見当違いです. 一方でmemset()は、最適化される可能性が高いため、単純なループよりも高速です。一方、最適化は、一度に複数のバイトを書き込むことで構成される可能性が高く、これがこのループが行うことです。一方、memset()とにかくループです。ループを関数呼び出しに埋め込むのではなく、明示的に記述しても、それは変わりません。一方、ループが遅くても問題になることはほとんどありません。明確なコードを書くことに専念し、実際の測定でパフォーマンスに重大な問題があることが示された場合は、コードを最適化することを検討してください。

あなたのコンピュータがgrid.

最後に、手がなくなる前に (手遅れです!)、どんなに速くmemset()ても、必要な結果が得られなければ意味がありません。(何も設定gridしない方が早い!)

于 2011-08-17T23:31:42.450 に答える
1

man memsetシェルで入力すると、次のように表示されます

void * memset(void *b, int c, size_t len)

これを平易な英語で説明すると、b長さのバイト文字列にlen各バイトを値で埋めますc

あなたの場合、

memset(grid, 5, 100 * sizeof(int));

sizeof(int)==4したがって、上記のコード部分は次のようになります。

for (int i=0; i<100; i++)
    grid[i]=0x05050505;

また

char *grid2 = (char*)grid;
for (int i=0; i<100*sizeof(int); i++)
    grid2[i]=0x05;

84215045が出力されます

しかし、ほとんどの C コードでは、メモリ ブロックの一部を値 0 に初期化する必要があります。

  • charタイプ -->\0またはNUL
  • intタイプ -->0
  • floatタイプ -->0.0f
  • doubleタイプ -->0.0
  • ポインタ型 -->nullptr

また、gccclangなどの最新のコンパイラは、これを自動的に処理してくれます。

// variadic length array (VLA) introduced in C99
int len = 20;
char carr[len];
int iarr[len];
float farr[len];
double darr[len];
memset(carr, 0, sizeof(char)*len);
memset(iarr, 0, sizeof(int)*len);
memset(farr, 0, sizeof(float)*len);
memset(darr, 0, sizeof(double)*len);
for (int i=0; i<len; i++)
{
    printf("%2d: %c\n", i, carr[i]);
    printf("%2d: %i\n", i, iarr[i]);
    printf("%2d: %f\n", i, farr[i]);
    printf("%2d: %lf\n", i, darr[i]);
}

ただし、C ISO 委員会はそのような定義を課していないことに注意してください。これはコンパイラ固有のものです。

于 2018-02-01T06:08:37.210 に答える
0

このコードはテスト済みです。これは、「整数」配列を0〜255の値にmemsetする方法です。

MinColCost=new unsigned char[(Len+1) * sizeof(int)];

memset(MinColCost,0x5,(Len+1)*sizeof(int));

memset(MinColCost,0xff,(Len+1)*sizeof(int));
于 2012-09-11T15:19:34.900 に答える
0

memset はバイトを書き込むため、通常は次のように int 配列をゼロに設定するために使用します。

int a[100];
memset(a,0,sizeof(a));

または、char は正確にバイトであるため、char 配列を設定するために使用できます。

char a[100];
memset(a,'*',sizeof(a));

さらに、int 配列は memset によって -1 に設定することもできます。

memset(a,-1,sizeof(a));

これは、-1 が int では 0xffffffff であり、char(バイト) では 0xff であるためです。

于 2011-08-18T02:16:18.467 に答える