2012-01-10 15 views
2

私はまだプログラミング/ C++ではなく、ポインタの周りを頭で囲み、参照やすべてを渡すことを試みています。今私が理解しようとしているプログラムは、構造体の配列を別の関数に渡す必要があります。私はそこに直接配列を渡すだけで動作しています。それはうまくいくようです。しかし、私が心配しているのは、値渡しであると信じているからです。構造体を参照渡しする方が良いことを理解していますので、毎回構造体のコピーを作成しているわけではありません。構造体の配列をC++での参照渡し

私が理解から

struct GoldenHelmet { 
    int foo; 
    string bar; 
    }; 

void pass (GoldenHelmet ofMambrino[], int size); 

int main() { 
    GoldenHelmet ofMambrino[10]; 
    int size = sizeof(ofMambrino)/sizeof(ofMambrino[0]); 
    ofMambrino[1].foo = 1; 
    pass(ofMambrino, size); 
    cout << ofMambrino[2].foo << endl; 
    return 0; 
} 

void pass (GoldenHelmet ofMambrino[], int size) { 
    ofMambrino[2].foo = 100; 
    ofMambrino[2].bar = "Blargh"; 
} 

、配列がすでにポインタであるため、それが右、動作します:

とにかく、ここで私がやっているの基本的な例ですか?しかし、私はそれが設定されている方法は、私はまだ構造体のコピーを通過するすべてのパス()関数に?私は参考にしてそれを渡そうとしましたが、私が試した方法では動作したくないようです。

+4

配列はポインタではありません。あなたが気絶するまでこのことを繰り返してください。その後、このサイトに戻って、それまでに投稿された回答を読んでください。 –

+3

@NiklasBaumstarkいいえ、答えはC++になります:) – dasblinkenlight

+0

@Kerrek SBご清聴ありがとうございます。私は[この投稿](http://forums.devshed.com/c-programming-42/how-to-passing-arrays-of-structures-61159.html)を読んでいたので、配列がポインタであることを暗示していたようでした。私はそれを調べ続ける必要があると思う。とにかく、皆さんの助けをいただきありがとうございます。 – Nate

答えて

5

この構文:

void pass (GoldenHelmet ofMambrino[], int size) 

は実際には非常に混乱しています。配列を渡さないので、ポインタを渡しています。彼らは同じことではありませんが、混乱しないでください。この奇妙は、関数のパラメータにのみ適用されます。上記本と全く同じである。

void pass (GoldenHelmet * ofMambrino, int size) 

それが別のオブジェクトのサブオブジェクトでない限り、値によって配列を渡すために、実際には不可能です。あなたはかかわらず、サイズを含める必要があり、参照することによってそれらを渡すことができますが、テンプレートを使用していることを行うことができます。

template<int N> 
void pass (GoldenHelmet (&ofMambrino)[N]) 
+1

なぜテンプレートが必要なのですか? 'void pass(GoldenHelmet(&h)[10])の何が間違っていますか? –

+0

@Kerrek:テンプレートが必要だとは言いませんでした。私は "あなたはサイズを含める必要がありますが、あなたはテンプレートを使ってそれを行うことができます"と言いました。あなたはそれについて明示することを選んだ[サイズ]、私はテンプレートを使用することを選んだ。 –

+1

@Benjaminありがとう、もう少し理解し始めています。したがって、配列全体ではなくポインタを渡している場合は、参照渡しを心配する必要がありますか?私が、単に構造体を渡すだけであれば、参照渡しの利点が分かります。しかし、もし私がポインタを渡しているのであれば、実際には参照渡しのメリットはありますか? – Nate

1

配列はポインタとして表現されて渡されるため、ここでは何もコピーされません。対照的に、という単一のstructを渡した場合、値渡しされます。以下

この最後の点を説明するためのコードの断片である:

void passByVal (GoldenHelmet ofMambrino) { 
    ofMambrino.foo = 100; 
    ofMambrino.bar = "Blargh"; 
} 

void passByRef (GoldenHelmet& ofMambrino) { 
    ofMambrino.foo = 100; 
    ofMambrino.bar = "Blargh"; 
} 

int main() { 
    GoldenHelmet h; 
    passByVal(h); // h does not change 
    passByRef(h); // fields of h get assigned in the call 
} 
6

C++方法:

#include <array> 

typedef std::array<GoldenHelmet, 10> Helmets; 

void pass(Helmets &); 

int main() 
{ 
    Helmets h; 
    h[1].foo = 1; 
    pass(h); 
    //... 
} 

void pass(Helmets & h) 
{ 
    h[2].foo = 100; 
    // ... 
} 

実際、我々は参照によって配列を渡します。

4

これらがすべて可能ですが、それらのどれも値渡しません。 ofMambrinoを配列の先頭アドレスと考えると、それはあなたが渡しているものです。

void pass (GoldenHelmet ofMambrino[], int size) 
void pass (GoldenHelmet ofMambrino[10], int size) 
void pass (GoldenHelmet *ofMambrino, int size) 
void pass (GoldenHelmet (&ofMambrino)[10], int size) 
+0

パーフェクト、それは多くをクリアします。なぜ私はサイズを渡す必要があるのか​​、配列の先頭のアドレスを指しているだけなので、配列の長さを把握する必要があるからです。 – Nate

+0

@ネイト:まあ、最初に学習を始めたとき、私はいつも誰も私に "ちょうどその住所"と言った理由を疑問に思った。 –

0

まず第一に、配列はポインタではありません。

int x[ ] 

xは、実際には配列の先頭を指すconstポインタです。これを引数リストのポインタと呼びます。これを関数に渡すと、配列の先頭にあるメモリのアドレスを送信します。それで、あなたがあなたの関数を変更したときに、あなたは実際に呼び出し元セクションの変数のアドレスを変更します。これは実際には参照による呼び出しではなく参照によるシミュレートされた呼び出しです。しかし、メモリロケーションで作業しているので、参照による呼び出しと同じ効果があります。この理由から、あなたがあなたの構造体の配列を送るときには、実際に構造体の配列のアドレスを渡します。それで、これで値を変更すると、実際に構造体が変更されます。

参照によってコールを使用するには、行うには、あなたがしなければならない一つのことは

void f(int &param) 

のように、あなたの関数のプロトタイプを定義することで、関数を呼び出すとき、それは他の人と同じです。要約する

int main() 
{ 
    int x; 

    // simulated call by reference that use adress of variable, 
    // lets say adress of x is 19ff 
    f(&x);  // actually you send 19ff 

    f(x);  // call by reference that use reference of variable 

} 

// simulated call by reference 
void f(const int *y) 
{ 
    // when you use like *y=10, you are writing on memory area 19ff, you actually 
    // change memory area that is belong to x in the main 

} 

// call by reference 
void f(const int &y) 
{ 
} 
関連する問題