2011-10-21 5 views
4

友人からCの関数を書いて、配列の100番目の要素を返すように求められました。私はCに慣れていないので、どのような型の配列でもこれを行うことができる汎用関数を作る方法がわからないので、浮気し、整数の配列であり、この関数を書いたと仮定します:これは関数のようには見えません。これは何ですか?

int GetHundredthElement(int *array) { 
    return array[100 - 1]; 
} 

(配列がゼロインデックス付きであるため、- 1がある)

私はどのように配列のいずれかのタイプのために働くだろう機能を作るために彼に尋ねました。彼はそれを行うための簡単な方法があった私に言った:

int GetHundredthElement = 100 - 1; 

と、この「機能」は、このように呼ばれることができること:

GetHundredthElement[array]; 

私はそれを試みたが、それが働いたのではなく、これは関数呼び出しがCでどのように書かれているかではないブラケット記法を使用しているので私の関数のように見えます。私はこのコードが何をしているのか、それがどういうものなのかを本当に分かりません。何が起きてる?

+0

@ K-balloには正しい答えがあります。しかし、将来的に、任意の精度型(int、float、doubleなど)を取るより複雑な関数を作成したい場合や、C++へのアクセス権がある場合(具体的にはC言語の質問があることがわかります)、lookテンプレートに変換する。彼らはC++に驚くほどの追加機能です。 – Amit

答えて

9

GetHundredthElementは関数ではないということは正しいことです。これは期待どおりの整数です。

しかし、これはC言語で驚くべき能力を示しています。ここでは、配列アクセスの順序を逆にすることができます。

assert(a[5] == 5[a]); 

配列アクセスがポインタ演算で実現することができるからである。

assert(a[5] == *(a+5)); 
assert(*(a+5) == *(5+a)); 
assert(*(5+a) == 5[a]); 
5

ポインタを使用する場合、pointer[ index ]index[ pointer ]は実際には同じです。これは関数ではなく、通常の演算子です。 array[ GetHundredthElement ]またはarray[ 100 - 1 ]と同じです。

11

これは機能ではなく、単に配列インデックスを入れ替えることができます。すべてのx[y]表記は、y配列のx番目のオフセットにアクセスしていることを意味します。しかし、あなたも同じように簡単にy[x]と書くことができます。

99[array]およびarray[99]は同じものを意味します。 GetHundredthElementを99と宣言すると、あなたの友人は素敵なトリックを演奏しました:)

C++テンプレート(Cではない)を使用して、配列の100番目の要素をかなり簡単に得る汎用関数を書くことはできます。

+6

これは、x [y]が*(x + y)と等価であるためです。加算は可換であるため、これは*(y + x)であり、y [x]となります。 –

2

これは、アレイにアクセスできる特別なファンキーな方法です。

配列はポインタのように扱うことができ、算術演算を使用できることを思い出してください。例えば

xは、いくつかの任意の配列であるとする。

int x[4]; 

*(x+4)あるx年代にアクセスする第5要素を意味しています。メモリレイアウトの

ひどい例は:

x -> [0][1][2][3][4] 

さて、あなたはCの配列で行うことができます奇妙なことは/ブロックへのポインタは、ブラケット表記の数と変数を反転です。それらが分解するので

x[4] is equal to 4[x] 

は:Cで

+0

ちょうど好奇心のために、 'x [4] [4]'をどのように後方に表現しますか?それは '(4 * 4)[x]'でしょうか? – Amit

+2

@Amit - 私は多次元配列で奇妙なやり方をする方法を知らないと告白する必要があります。 '(4 * 4)[x]'は 'x [16]'と言っているのでコンパイルできません。配列名は一度しか表示されないので、このようなトリックは実際には '4 [x] [4]'のようにしかできません。しかし、それを行う算術的な方法は '*(*(x + 4)+4);'です。はい、私もファンキーに見えます。 – birryree

+0

非常に真実。ありがとうございます:) – Amit

2
*(x+4) and *(4+x) 

、ブラケット表記は、ポインタ演算のための短い手です。 x[i]のような通常の使用法は、*(x + i)と構文的に同等です(配列はポインタであることに注意してください)。代わりにi[x]を使用した場合は、*(i + x)と同じで、同じ出力が生成されます。他の回答でも指摘されているように、このアプローチは機能ではなく、興味深いテクニックです。

関連する問題