-2

質問を閲覧していて、この回答を見つけました。

答えの最後にあるこのプログラムを理解できませんでした。具体的には、プットオフ関数の最初の 3 行

 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>

 #define NUM_ELEM(ar) (sizeof(ar) / sizeof((ar)[0]))

int * put_off(const int newrow[2])
{
static int mymatrix[3][2];
static int (*rowp)[2] = mymatrix;
int (* const border)[] = mymatrix + NUM_ELEM(mymatrix);

memcpy(rowp, newrow, sizeof(*rowp));
rowp += 1;
if (rowp == border) {
    rowp = mymatrix;
}

return *rowp;
 }

int main(int argc, char *argv[])
{
int i = 0;
int row[2] = {0, 1};
int *rout;

for (i = 0; i < 6; i++) {
    row[0] = i;
    row[1] += i;
    rout = put_off(row);
    printf("%d (%p): [%d, %d]\n", i, (void *) rout, rout[0], rout[1]);
}

return 0;
  }

プログラム内の関数の最初の 3 行について助けが必要です。

4

1 に答える 1

1

以下は、理解を深めるための説明です。

static int mymatrix[3][2];

mymatrix3 行 2 列の int の 2D 配列です。C は行優先順を使用します。つまり、行はメモリに次々に格納されます。static キーワードは、その値を関数呼び出し間で永続化します (スコープはまだローカルです)。

static int (*rowp)[2] = mymatrix;

これは、2 つの整数の配列 (つまり、この場合は mymatrix の行) へのポインターを宣言します。mymatrix に初期化することは、最初の行に初期化することと同じです。もちろん、 static キーワードは上記と同じ意味です。

int (* const border)[] = mymatrix + NUM_ELEM(mymatrix);

borderint の配列への定数ポインター (つまり、ポインターは変更できません) です。mymatrix を超えるメモリアドレスに初期化されます (これは少し珍しいかもしれません)。具体的には、mymatrixもう 1 行ある場合に存在する次の行を指しているため、行ポインターが正確にその場所を指している場合、関数は行ポインターをラップして、行列全体を埋めた最初の行に戻します。

ポインター、配列の括弧などの集合については、いつでもcdeclを試して、変換できるかどうかを確認できます。

于 2013-01-27T05:56:14.337 に答える