1

C の基礎を勉強していますが、文字列と配列について混乱しています。

    #include<stdio.h>
    int main()
    {
      char arr[2][4] = {1,2,3,4,5,6,7,8};
      printf("%u %u\n",arr,arr+1);
      printf("%d",*(*(arr+1)+2) );
      return 0;
    }

ここでarrarr+1は隣接する場所ですが、2 番目printf arr+1は 2 番目の配列のゼロ インデックス要素に直行します。これはどのように合法ですか?2番目の配列に移動するには、&arr+1.


私が学んだことは --> 一次元配列の場合:

  arr[7]={1,2,3,4,5,6,7};

ここで arr と &arr は同じと見なされるべきではありません (ただし、同じ値が出力されますが、この情報の意味は完全に異なります)。そのため、 arr+1 と &arr+1 も同じではありません。&arr は、7 つの整数のコンテナーであるデータ型のアドレスを提供するため、 &arr+1 は、7 つの整数のコンテナーでもある後続の配列型に移動します。それで

arr = 5796 , &arr = 5796    (both are base address but arr is the address of    
                   1st element while &arr is the address of the whole array)
arr+1 = 5800 ,&arr+1 = (5796+(7X4))=5797+28 = 5825(this is address of some 
new array)

2 次元配列の場合、概念は同じです。

arr[2][4]={1,2,3,4,5,6,7,8};

arrここにあるのは、配列の個々の要素を指すポインターでもある soarrarr+1は、その連続する要素のアドレスです (そして、それらの要素は{1,2,3,4}andです{5,6,7,8})_ and 同様に、2x4=8 要素を持つ 2 つの配列のベースアドレスを与えます&arr&arr+1to&arr&arr+1は、相似サイズの 2 つの配列のアドレスです。そう

 arr = 5796 , arr+1 = 5796+(4*3)=5796+12 = 5808 
 &arr = 5796 , &arr+1 = 5796+(4*7)=5796+ 28= 5824

これで、2 次元配列で、個々の要素に到達するために 2 つのアドレスが関連付けられていることがわかります。

1)arr(配列内の2つの要素から選択する要素を与える)
2)*arr(その特定の要素(配列)のどの要素を与えるか

そのため、データにアクセスしたい場合は、2 回逆参照する必要があります。

arr=5796(first array), *arr=5796(first element address), **arr = 1 (1st element)
arr+1=5812(second array), *(arr+1) = 5812(first element address), *(*(arr+1))=5(first element)
arr=5796,*arr=5796, *arr+1=5796+1(second element), *(*arr+1)=2 (second element)

配列の構文は次のとおりです。

   *arr = arr[0]
   **arr = arr[0][0]
   *arr+1 = arr[0]+1
   **arr+1 = arr[0][0]+1
   *(*arr+1) = *(arr[0]+1) = arr[0][1]
   *(*(arr+1)+1) = *(arr[1]+1) = arr[1][1]

配列を書き込む他の方法がいくつかあります

      3[arr[1]] = arr[1][3]
      -3[arr[1]] = -arr[1][3]
      *(1[arr]+2) = *(arr[1]+2) = arr[1][2]

この概念は 3 次元配列にも拡張できますが、これはすべての初心者が理解する必要がある最低限のものです。概念的または構文的に間違っている場合は修正してください。

4

6 に答える 6

2

arrは二次元配列だからです。

*(*(arr+1)+2))と同等arr[1][2]です。

于 2013-10-03T11:12:13.433 に答える
1

宣言

char arr[2][4] = {1,2,3,4,5,6,7,8};  

意味

char arr[2][4] = { 
                     {1,2,3,4},   // row 0
                     {5,6,7,8}    // row 1
                  };  

arr配列名を に渡すことは、配列の最初の要素 (行)printfへのポインターに減衰し、型(2D 配列は、それぞれ 4 要素の配列である 2 要素の 1D 配列と考えられます) であることを意味します。 0arr[2]int (*)[4]

2 番目の配列に移動するには、&arr+1 にする必要があると考えました。

arr + 11配列の 2 番目の要素 (行) を指します (arr[2]配列行の 2 番目の要素ではありません1arr[2][4])。を実行すると、(減衰後に)ポインターarr + 1だけに追加されるのではなく、要素を行に格納するために必要な合計バイト数が追加されます。 簡単な例でこれを理解しましょう: isのアドレスとサイズへの参照を考えてみましょう。それからあなたのすることを意味します。 したがって、逆参照すると行全体が返されますが、逆参照すると行の 3 番目の要素、つまり 7が 返されます。アドレス (ポインター値) を出力するには、次を使用します。1arr
arr100int4arr + 1100 + (4-1)*4 = 112
(arr + 1)1(*(arr+1)+2)1
%uunsigned integer%pprintf最初のステートメント の指定子。

于 2013-10-03T11:33:40.700 に答える
0

arr+1&arr+1このコンテキストでは、 はまったく同じものです。これはarr、配列が暗黙的にポインターに分解されるか、そのアドレスが明示的に取得されるため、同じことになります。

ご存じのとおり、配列に 1 を追加すると、2 番目の要素に移動します。Andarrは配列の配列であるため、その 2 番目の要素は 2 番目のサブ配列です。

最初のサブ配列の 2 番目の要素が必要な場合は、 を試してくださいarr[0]+1。これは と同等&arr[0][1]です。

于 2013-10-03T11:13:35.290 に答える
0

使用する配列はcharacter、各フィールドが 1 バイトかかるようにするためです。arr隣接する場所にはありarr+1ません。

arr と arr+1 の出力を確認すると、差が 4 であるため、整数を念頭に置いて、隣接する場所にあることを伝えていると思います。

&arr[0]= 1 行目の 1 番目の要素のアドレス

&arr[1]= 2 行目の 1 番目の要素のアドレス

データ型をからcharに変更すると、intより理解が深まります。

以下のプログラムの出力を確認してください。

#include<stdio.h>
int main()
{
 char arr[2][4] = { 1,2,3,4,
                    5,6,7,8 };

 printf("%u\n", &arr[0][0]);
 printf("%u\n", &arr[0][4]);

 printf("%u\n", &arr[1][0]);
 printf("%u\n", &arr[1][4]);

 printf("%d\n",*(*(arr+1)+2) ); // equal to arr[1][2]
 printf("%d\n", *(arr[1] + 2) );
 printf("%d\n", arr[1][2]);

 return 0;
}

出力:

3214594184
3214594188
3214594188
3214594192
7
7
7

上記のプログラムは警告を表示します。%u を %p に置き換えてください。

于 2013-10-03T11:32:38.100 に答える
0

にアクセスする場合char arr[ROW_COUNT][COLUMN_COUNT]arr[row][col]は と同等address_of_arr[col + (row * ROW_COUNT)]です。頭を包み込むと、すべてがより理にかなっています。

arr隣接してarr+1はならず、4 バイトの差があるはずです。正確にどのような結果が表示されていますか?

于 2013-10-03T11:31:25.597 に答える