2

C のポインターと配列の宣言の基本について混乱しています。次の 2 つのステートメントの違いを知りたいのですが、2 番目のステートメントで配列へのベース アドレスが ptr に割り当てられる点が異なります。

int a[2][3]= { (1,2,3),(4,5,6)};
int (*ptr)[3] = &a[0];

明確にするために例を引用してください。2行目のR側の[3]はどのような効果がありますか?

4

3 に答える 3

5

1. 二次元配列:

int a[2][3]= { {1,2,3},{4,5,6}};

このステートメントをメモリ内に置くと、2x3 の整数がすべてメモリ内で隣接しています。それらにアクセスする方法を知っていると思いますが、そうでない場合は明確にします。

a[0][0] : 1
a[0][1] : 2
a[0][2] : 3
a[1][0] : 4
a[1][1] : 5
a[1][2] : 6

2. 配列へのポインタ:

int (*ptr)[3] = &a[0];

ptr はメモリの int[3] ブロックを指します。したがって、int[3] タイプにのみ割り当てることができます。

ptr= &a[0];
ptr= &a[1];

違いは、このポインターには独自のメモリがなく、int[3] 変数に割り当てるか、割り当てる必要があることです。

ptr= malloc (2*sizeof(int[3]);

このようにして、ptr を次のように初期化すると、ptr が指すメモリを使用できます。

for(int j=0; j<2; j++)
    for(int i=0; i<3;i++)
        ptr[j][i]=i+j*3+1;

この場合、int a[2][3] と同じメモリ表現になりますが、このメモリはスタックではなくヒープにあります。いつでもメモリの再割り当て/解放を選択でき、このメモリは削除されません。関数が終了したら。

于 2012-11-14T17:14:25.067 に答える
1

Cの演算子の優先順位の規則を知っておく必要があります:http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B#Operator_precedencehttp://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B#Operator_precedence

int (*ptr)[3]とは対照的にint * ptr [3]

int (*(ptr [3]))1つ目はサイズ3のintの配列へのポインター(*は変数名に近いことに注意)です。2つ目はintポインターのサイズ3の配列に等しいです。

式の解釈方法に疑問がある場合は、次のサイト(http://cdecl.org/ )を使用することもできます。

于 2012-11-14T17:21:15.257 に答える
-1

a は、行サイズ 2、列サイズ 3 の 2 次元配列です。

一方、サイズが 3ptrの配列へのポインターint

しかし、あなたの配列のa初期化は正しい方法ではありません

soを使用()したので、コンマ演算子が有効になり、3andで初期化され6、配列の他の要素が実際の初期化の使用を行うaことになります0{}

&a[0] は、配列の最初の要素のアドレスです (a に対しても同じ値を出力することを意味します)。

ただし、これ&a[0]は、ポインター算術演算を実行すると有効になりますptr

配列の場合、次の 3 つの点に注意してください。

--->int *ptr=&a[0][0];最初の要素のアドレスから次の要素ptr++が得られますa[0][1]

---> &a[0] = 最初の要素のアドレスですがint (*ptr)[3]=&a[0] 、そうすると、ptr++ポインターは行全体のサイズだけ増加し、ptr は次の行を直接指すようになり、ptr が指すようになります&a[1]

---> &a = 配列全体のアドレスであり、それを保持して実行するint (*ptr)[2][3] =&aと、ptr++ポインターは配列全体のサイズだけ増加します。

于 2012-11-14T17:02:27.467 に答える