これが事です。ポインタから配列へのポインタなどで作成される多次元配列(しばらく2Dを考えてみましょう)の概念を完全に理解できます...
次のようにします。
// we can use dynamically defined size n and m
int n = 3, m = 5 ;
int **T = new int *[n];
for (int i = 0 ; i < n ; ++i)
T[i] = new int[m];
私たちが得たものは:(私がここにいるかどうかを確認してください)
- メモリ内のどこかに配置された、5 int の 3 ブロックのメモリ
- ints のブロック数 (行数) と同じサイズのメモリの 1 つの追加ブロック。このブロックは、これらの int 行へのポインターの配列です (通常、int のようなポインターの場合は 4 バイト)。
- 私たちが最も関心を持っているのは、(**T) 型の T であり、ポインターへのポインターです。これはまさにポインターの配列へのポインターです。C++ では、配列は実際にはメモリのブロックを指すポインターであるため、t[] または t[0] は *t を意味し、t[x] は *(t+バツ)。
問題は、次のように sth を実行する場合です。
int n = 3, m = 5 ;
int T[n][m] ;
私たちが持っているのは、私が前に示したことを行うことができたものではありません. 奇妙になります。Tとは何ですか?T を printfing すると、T[0] と同じ値が得られます。行へのポインターの配列を追加せずに、サイズが n*m の int のブロックを予約したようです。
私の質問は次のとおりです。コンパイラは配列の次元と行と列の数を覚えていますか? T[i][j] を要求すると、実際には *(T+i*n+j) が要求されるため、この n はどこかに保存されますか? 問題は、このこと (T) を関数に渡そうとするときです。理由はわかりませんが、n と m が定数の場合、T をこの配列へのポインターとして渡して、このプログラムのように機能させることができます。
#include <stdio.h>
const int n = 3, m = 4 ; // this is constant!
void add_5(int K[][m])
{
for (int i = 0 ; i < n ; ++i)
for (int j = 0 ; j < m ; j++)
K[i][j] += 5 ;
}
int main()
{
// n x m array the most straight forward method
int T[n][m] ;
for (int i = 0 ; i < n ; ++i)
for (int j = 0 ; j < m ; ++j)
T[i][j] = i*m + j ;
for (int i = 0 ; i < n ; ++i)
{
for (int j = 0 ; j < m ; j++)
printf("%d ",T[i][j]) ;
printf("\n") ;
}
printf("\n") ;
// adding 5 to all cells
add_5(T) ;
printf("it worked!!\n") ;
for (int i = 0 ; i < n ; ++i)
{
for (int j = 0 ; j < m ; j++)
printf("%d ",T[i][j]) ;
printf("\n") ;
}
int ss ;
scanf("%d",&ss) ;
}
しかし、n と m が一定でない場合はできません。したがって、動的に作成された多次元配列のポインターを、手動でメモリを割り当てずに関数に渡す必要があります。これを行う方法?