このコードは醜いハックであり、現在、そして将来このコードを見るために戻ってきたときに混乱を招くだけです. ポインター演算の背後にある考え方は、配列へのアクセスを難しくするのではなく、簡単にすることです。変えたら
float *p;
に
float **p;
ポインターは二重ポインターになりました。つまり、間接演算子 (*) を 1 回使用すると、別のポインターが得られます。作成した配列は次のようになります。
[0,0][0,1][0,2][0,3][0,4]
[1,0][1,1][1,2][1,3][1,4]
[2,0][2,1][2,2][2,3][2,4]
[3,0][3,1][3,2][3,3][3,4]
[4,0][4,1][4,2][4,3][4,4]
[5,0][5,1][5,2][5,3][5,4]
[6,0][6,1][6,2][6,3][6,4]
[7,0][7,1][7,2][7,3][7,4]
[8,0][8,1][8,2][8,3][8,4]
[9,0][9,1][9,2][9,3][9,4]
2 レベルの間接参照があるため、最初のポインターは行を指し、2 番目のポインターは列を指します。インダイレクションは逆方向に行われるため、ポインター表記では最も内側の要素が配列表記で最も左にある要素になります。
arr[ROW][COL] === *(*(p + ROW) + COL)
要素にアクセスしたい場合は、配列表記arr [ROW][COL] を使用するか、ポインター演算を使用してアクセスできます。二重ポインターでは、2 つのレベルの間接参照があります。だからあなたが使用しなければならなかったのに対し
p = (float *) balance;
*(p + 16)
必要な場所を取得するには、実際には(私の意見では)単純に書く方がはるかに簡単です
p = balance;
*(*(p + 3) + 1)
これは、ポインター演算を配列のインデックス付けと同様に使用しているため、ポイントしたい要素を一目で簡単に判断できるからです。
二重ポインターを単一のポインターにキャストする限り、最初に二重ポインターを処理する方が本当に簡単です。それが配列の名前のすべてです。
int arr[ROW][COL] = {0};
int **p_arr = arr; /* Valid operation. arr without array notation is a double pointer */