8

次のコードを検討してください。

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

#define NUM_ARRAYS     4
#define NUM_ELEMENTS   4
#define INVALID_VAL   -1

int main()
{
   int index            = INVALID_VAL;
   int array_index      = INVALID_VAL;
   int **ptr            = NULL;

   ptr = malloc(sizeof(int*)*NUM_ARRAYS);

   if (!ptr)
   {
      printf ("\nMemory Allocation Failure !\n\n");
      exit (EXIT_FAILURE);
   }

   for (index=0; index<NUM_ARRAYS; index++)
   {
      *(ptr+index) = malloc(sizeof(int)*NUM_ELEMENTS); 

      if (!*(ptr+index))
      {
         printf ("\nMemory Allocation Failure !\n");
         exit (EXIT_FAILURE);
      }
   }

   /* Fill Elements Into This 2-D Array */
   for (index=0; index<NUM_ARRAYS; index++)
   {
      for (array_index = 0; array_index<NUM_ELEMENTS; array_index++)
      {
         *(*(ptr+index)+array_index) = (array_index+1)*(index+1);
      }
   }

   /* Print Array Elements */
   for (index = 0; index<NUM_ARRAYS; index++)
   {
      printf ("\nArray %d Elements:\n", index);
      for (array_index = 0; array_index<NUM_ELEMENTS; array_index++)
      {
         printf (" %d ", *(*(ptr+index)+array_index));
      }
      printf ("\n\n");
   }

   return 0;
}

私のコードに問題はありません。それは正常に動作します。

Output:

Array 0 Elements:
 1  2  3  4 


Array 1 Elements:
 2  4  6  8 


Array 2 Elements:
 3  6  9  12 


Array 3 Elements:
 4  8  12  16 

ポインター演算について質問があります。

*(ptr+0)= COMPLETE BLOCK (最初の配列)
*(ptr+1)へのポインター = COMPLETE BLOCK (2 番目の配列) へのポインター。

しかし、何ですか: (*ptr+1)?

GDB 出力:

(gdb) p *(*ptr+1)
$1 = 2
(gdb) p *(*ptr+2)
$2 = 3
(gdb) p *(*ptr+3)
$3 = 4
(gdb) p *(*ptr+4)
$4 = 0

私はこれについて混乱しています。この疑問を解決するための説明をお願いします。

4

5 に答える 5

28
                                 (*ptr)      (*ptr+1)     (*ptr+2)
                                   |            |            |
             __________      ______v____________v____________v____________
  ptr------>|   *ptr   |--->|  *(*ptr)   |  *(*ptr+1)  |*(*ptr+2) |       |
            |__________|    |____________|_____________|__________|_______|
 (ptr+1)--->| *(ptr+1) |     ____________ _____________ __________________
            |__________|--->|*(*(ptr+1)) |*(*(ptr+1)+1)|          |       |
            |          |    |____________|_____________|__________|_______|
            |__________|          ^             ^
                                  |             |
                              *(ptr+1)     *(ptr+1)+1

ダブルポインターを持つ2D配列。これは、メイン配列があり、メイン配列の要素がサブ配列へのポインター(またはアドレス)であることを意味します。上図に示すように

したがって、この2D配列のポインターとしてダブルポインターを定義した場合は、int **ptr

サブ配列へptrのポインタを含むメイン配列にポンティングします。ptrはメインアレイにポンティングしています。つまり、メインアレイptrの最初の要素をptr + 1指しているので、メインアレイの2番目の要素を指しているということです。

*ptrこれは、ptrが指している最初の要素の内容を意味します。そして、それはサブ配列へのポインターです。最初のサブ配列へのポインタも*ptr同様です(サブ配列はの配列ですint)。*ptrつまり、最初のサブ配列の最初の要素を指しています。*ptr + 1最初のサブ配列の2番目の要素へのポインタもそうです

于 2012-12-20T14:45:51.163 に答える
9

*(ptr+i)は に等しくptr[i]*(ptr+1)ptr[1]です。

2 次元配列を配列の配列と考えることができます。

  • ptrは完全な 2 次元配列をptr+1指すため、次の 2 次元配列を指します。

下の図 ptrは 2 次元で、列数は3

Kerrek SB氏作のオリジナルフィギュア、こちらも要チェック!

+===============================+==============================+====
|+---------+----------+--------+|+----------+---------+--------+|
||ptr[0,0] | ptr[0,1] | ptr[0,2]|||ptr[1,0] |ptr[1,1] | ptr[1,2]|| ...
|+---------+----------+--------+++----------+---------+--------++ ...
|            ptr[0]             |           ptr[1]              |
+===============================+===============================+====
   ptr

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

以下を理解してください。

ptr2-D を完了するためのポイント。

*ptr = *(ptr + 0) = ptr[0]それが最初の行です。

*ptr + 1 = ptr[1]2行目を意味します

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

Array 0 Elements:
1  2  3  4 

そしてGDB出力:

(gdb) p *(*ptr+1)
$1 = 2  

そうです、2これは を使用して読み取ることができますptr[0][1]

于 2012-12-20T14:18:35.050 に答える
2

タイプを間違えない限り、which は最初のブロックの 2 番目の要素へのポインターと(*ptr + 1)同等です。*(ptr + 0) + 1

于 2012-12-20T14:15:06.553 に答える