web-dev-qa-db-ja.com

ダブルポインタを使用した2次元配列の実装

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

_#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
_

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

7
Sandeep Singh

*(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]

次のことを理解してください。

ptrは2-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]_を使用して読み取ることができます。

9
Grijesh Chauhan
                                 (*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番目の要素へのポインターです。

26
MOHAMED

ポインタを使用して2次元配列を作成し、値を割り当て、配列から要素にアクセスするための最も簡単な方法。

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

int main()
{
int i,j;
int row,col;
printf("Enter the values for row and col:\n");
scanf("%d%d",&row,&col);
int **arr=(int**)malloc(row*(sizeof(int*)));
for(i=0;i<row;i++)
{
    *(arr+i)=(int*)malloc(sizeof(int)*col);
            //You can use this also. Meaning of both is same.
            //arr[i]=(int*)malloc(sizeof(int)*col);
}
for(i=0;i<row;i++)
for(j=0;j<col;j++)
{
    arr[i][j]=0;
}
for(i=0;i<row;i++)
{
    for(j=0;j<col;j++)
    {
        printf("%d ",arr[i][j]);
    }
    printf("\n");
}
}
3
Tonmoy

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

2
MJZ