次のコードを検討してください。
_#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
_
私はこれについて混乱しています。この疑問を解決するための説明をお願いします。
*(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]
_を使用して読み取ることができます。
(*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番目の要素へのポインターです。
ポインタを使用して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");
}
}
入力を間違えない限り、_(*ptr + 1)
_は最初のブロックの2番目の要素へのポインターである*(ptr + 0) + 1
と同等です。