2016-11-17 4 views
0

配列の添え字演算子が識別子に結びついているのはなぜですか?配列 - なぜ添字演算子は識別子に結びついていますか?

Cuzの私たちが書く:

int a[5]; 

これは以下を利用するために禁止

タイプで実際にある "[5] INT":

typedef int[3][3] matrix_t; 
.... 
void foo(matrix_t my_matrix){ 
    .... 
} 

利点は何実際の実装の?

本当にこの機能を使いたいのですが、何か迷ってしまいましたか?

+1

'typedef int matrix_t [3] [3]' – Brian

+3

または 'matrix_t = int [3] [3]' – Brian

+1

を使用しています。 –

答えて

1

これはC言語開発の初期の時代からの単なる歴史的遺産である。当時、エンティティの宣言は将来の使用法を模倣することが決定されました。したがって、配列の宣言は、配列が式で使用される方法と似ています。関数宣言、ポインタ宣言などにも同じことが言えます(ポインタ宣言の*も ​​"識別子に結びつけられています")。

最新のC++では、実際には新しい構文を使用できます。これは、(古典のtypedef宣言に類似)型名エイリアスの使用-宣言

using array_type = int[3]; 
// Same as 
// typedef int array_type[3]; 

または

auto foo() -> int (*)[3] 
{ 
    ... 

// Same as 
// int (*foo())[3] 
+0

すべての言語に文法があります。あなたは "遺産"とは何を意味するのか分かりません。それはちょうどCが設立された方法です。その声明は他のすべての言語にも適用できる。 – Olaf

+0

@Olaf:私は、文法がなぜ最初に設定された日に戻ってセットアップされたのかについてコメントしています。私たちは宇宙からの石の錠剤についてCの文法を受けていませんでした。文法は人々によって作成されました。それで、彼らはその特定の方法でそれを作成したのです(または、少なくとも「なぜ」の問題に関して何らかの情報源が述べています)。 – AnT

+0

私の主張は、**すべての**プログラミング言語のための "legacy"比較的新しいGo、RustまたはSwiftです。いくつかの文法が選択され、それ以降のバージョンでそれを使用しなければなりません(言語には少なくとも十分なユーザーベースがあれば)。 – Olaf

2

はCでは、あなたがしたい方法で変数を入力する関数の戻り値の型宣言のようなコンテキストに適用されますそれらを使用してください。

「冷凍式」のようなものです。

ので

int x[5][2]; 

あなたは[]2までの値であり、何がその値がintであるために割り当て、その後、[]5までの最初の値を渡してxを使用すると思います意味します。

ある意味では、これは表現解析エンジンを使用して物事を入力します。

typedefは、変数が何でもその型のエイリアスになることを除いて、変数の宣言と同じように機能します。だからではなく、

typedef int[3][3] matrix_t; 

のそれは、このタイプの別名を定義するための変数宣言の構文解析/文法を再利用し、再び

typedef int matrix_t[3][3]; 

です。 C++ 11では

、我々はより多くのあなたが望むかもしれないように動作します usingを持っている:

using matrix_t = int[3][3]; 

あなたの問題の最後の部分はCで行列をコピーまたは値によって渡すことができないということです。関数パラメータとしてint[3][3]の型はint[3]*型になります - int[3]へのポインタです。また、int[3][3]型の期間を返すことはできません。 C++で

、これはstd::arrayを介して固定されている:

std::array< std::array< int, 3 >, 3 > 

は、(少なくとも、実際に)レイアウトint[3][3]と互換性のあるタイプであるが、それでもに/関数の値と同様の周りに渡すことができます。 Cでは、あなたは何だろう:上記std::arrayとしてメモリ内の同じレイアウトを持ち、その値のような関数に/から渡すことができる

struct matrix { 
    int data[3][3]; 
}; 

を。

関連する問題