2

次のコードのように、名前の前にポインターとダブルポインターを追加して、配列がその名前でどのように参照されるかを誰かが説明してください:

#include<stdio.h>

main()
{  
    int a[3][2];
    a[0][0]=15;
    a[0][1]=150;
    a[1][0]=115;
    a[1][1]=165;
    a[2][0]=135;
    a[2][1]=139;
    printf( "%u\n", a);
    printf( "%u\n", *a);
    printf( "%u\n", **a);
}
4

5 に答える 5

5

最初の1つ

printf("%u\n",a);

のアドレスを出力しますa。これは、最初の要素のアドレスと同じです。

2つ目

printf("%u\n",*a);

aの最初の「行」のアドレスを逆参照して提供しますa

そして3つ目

printf("%u\n",**a);

の最初の「行」へのポインターを逆参照しa、この 2 次元配列の最初の要素の値を返します。

警告を有効にして例をコンパイルすると、コンパイラはすでにエラーを出しており、使用している型のいくつかについて教えてくれます。への引数としてポインタを与えるときprintfは、フォーマット指定子を使用する必要があります%p

printf("%p\n",a);
printf("%p\n",*a);

フォーマット指定子%uは 用unsigned intです。 がある場合はint、指定子を使用することをお勧めします%d

printf("%d\n",**a);
于 2012-12-02T14:32:44.470 に答える
3

aとは両方とも*aポインタであるため、フォーマット指定子としてprintf()使用する場合と同様に、これをフォーマットされた出力に出力し%pます。

そうしないと、コンパイラから次のような警告メッセージが表示されます。

warning: format ‘%x’ expects type ‘unsigned int’, but argument 2 has type ‘int (*)[2]’ warning: format ‘%x’ expects type ‘unsigned int’, but argument 2 has type ‘int *’

だからこれを試してみてください:

printf("%p\n",a);
printf("%p\n",*a);

3番目のケース**aはタイプintなので、%dまたはを使用することをお勧めします%i

printf("%d\n",**a);

C規格によると、

ISO c99 standard : 7.19.6 Formatted input/output functions

9   If a conversion specification is invalid, the behavior is undefined.

    If any argument is not the correct type for the corresponding conversion 

    specification, the behavior is undefined.
于 2012-12-02T14:38:24.913 に答える
0

タイプの調査は有益です。

aタイプがint [3][2]あります。つまり、2つのintの3つの配列の配列です。ただし、配列タイプをCで割り当てたり、渡したりすることはできません。に渡すaと、最初の引数へのポインタ、つまり、型を持つ、つまり2intの配列へのポインタprintf分解されます。それはあなたが見るアドレスです。&a[0]int (*)[2]

(もちろん、配列の最初の引数のアドレスも配列自体のアドレスと同じであるため、そうするとprintf("%u", &a);、同じアドレス値が表示されます(ただし、タイプは異なります-タイプがあり&aますint (*)[3][2]) 。)

次に、*a。ポインターを逆参照することしかできないため、a最初にポインター()に分解され、&a[0]次に逆参照(*&a[0])されます。結果はa[0]、の最初の要素ですaa[0]タイプint [2]、つまり2intの配列があります。繰り返しますが、上記のように、配列を渡すことはできません。したがって、配列をに渡すとprintf、これは最初の引数へのポインタに分解されます。つまり&a[0][0]、型int *はintへのポインタです。それが2番目に表示されるアドレスです。a[0]この場合も、のアドレスは最初の要素のアドレスと同じであるため、上記と同じアドレスになりますa[0][0](ただし、タイプは異なります)。

最後に、があります**a。上で説明したように、*aa劣化し、次に逆参照されます。*a上記の型int [2]、配列型があることを覚えておいてください。と同様にa、それを逆参照すると、逆参照する前に暗黙的にポインターに分解されます。、劣化、逆参照、劣化、および再び逆参照されます**aa何が起こっているかについてのより明確な説明はです*&(*&a[0])[0]。最終結果はa[0][0]、タイプがint。です。

于 2012-12-02T21:06:20.393 に答える
0

a がアドレスより *a が a の値である場合のようです

ここに画像の説明を入力

于 2012-12-02T14:41:55.733 に答える
0

sizeof_Alignof、または単項演算子のオペランドである場合、または&宣言で別の配列を初期化するために使用される文字列リテラルである場合を除いて、型 "N 要素配列 " のTは変換 ("decay") されます。型「へのポインタ」の式Tであり、式の値は配列の最初の要素のアドレスになります。

最初のprintf呼び出しでは、式のa型は「2 要素配列の 3 要素配列int」です。上記の規則により、式はint「( int (*)[2]) の 2 要素配列へのポインタ」型に変換され、その値は と同じになり&a[0]ます。

2 番目のprintf呼び出しでは、式の*a型は「2 要素配列int」です。上記の規則により、式は「ポインタint」 ( int *) 型に変換され、その値は&a[0][0](と同じです&a[0]- 配列の最初の要素のアドレスは、配列の最初の要素のアドレスと同じです)配列自体)。

3 番目のprintf呼び出しでは、式**aは typeintを持ち、その値は格納されているものa[0][0](この場合は 15) です。

于 2012-12-02T16:16:28.873 に答える