int *a[3]
とはどう違いint (*a)[3]
ますか?
6 に答える
int a[3]
との間に違いはありません。どちらも3の配列としてint (a)[3]
宣言されます。との間には違いがあります。前者はへの3つのポインタの配列を宣言し、後者は3の配列へのポインタを宣言します。ここでは、Cブラケットの優先順位が*よりも高いため、括弧が違いを生みます。a
int
int *a[3]
int (*a)[3]
int
int
cdecl
または、変数宣言の意味を英語で出力するを使用できます。
cdecl> explain int*a[3]
a を int へのポインタの配列 3 として宣言する
cdecl> explain int (*a) [3]
a を int の配列 3 へのポインタとして宣言する
疑問がある場合は、このg++トリックを使用すると便利なことがよくあります。
#include <iostream>
template < class T > void describe(T& )
{
// With msvc, use __FUNCSIG__ instead
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
int main(int argc, char* argv[])
{
int *a[3];
describe(a);
int (*b)[3];
describe(b);
return EXIT_SUCCESS;
}
g ++でコンパイルして実行すると、次のようになります。
void describe(T&) [with T = int*[3]]
void describe(T&) [with T = int (*)[3]]
だから、彼らは間違いなく同じではありません!あなたが持っているものは:
- intへの3つのポインターの配列。
- 3intの配列へのポインタ。
フォーマットでアスタリスクが失われているようです...
int *a[3]
3の配列を宣言しint*
ます。
int (*a)[3]
intのベクトルへのポインタとしてaを宣言します。これは実際には他のポインタと大差ありません。少し複雑な型を指しているだけです。
int foo[3];
int bar[3];
int (*vp)[3];
vp = &foo;
(*vp)[0] = 0;
このURLには、C型宣言の読み取りに関する優れた記事があります。著者のEliBenderskyは、宣言を読み取るための簡単な方法を示しています。変数の名前から始めて、歩きながら遭遇したことを発音する線に沿って移動します。基本的な方法は、変数名から始めて右に進むことです。簡単な概要を説明しますが、記事を読むことを強くお勧めします。
- 変数名から始めて、右に進みます。
)
右のパレンまたはセミコロンをヒットした場合は、右;
に移動し始めた場所に戻ってから左に移動します。(
右に進んでいるときに左括弧に遭遇した場合は、関数宣言に遭遇しています。次に続くのは、コンマで区切られた引数のリストです。注:引数リストの最後に正しいパレンがあります。上記の規則は、この右の親には適用されません。- 左角かっこが表示された場合は、「配列」と読み替えてください。
- 左に行った後、左のパレンに当たっ
(
たら、最後に右に行った右のパレンに戻ります。その右のパレンを飛び越えて、それから繰り返し続けてください。 - [繰り返す]
したがって、このルールを特定の問題に適用する場合は...
宣言では、" int * a[3];
"a
は変数名です。だから、それは読まれます:
a
整数()へのポインタ()[
の3つの要素( )の配列( )です[3]
*
int
宣言中の「int (* a)[3];
」a
は変数名です。だから、それは読まれます:
a
整数()の3つの要素()の配列*
()へのポインタ( )です[
[3]
int