2010-11-26 31 views
1

私が構造を持っている:C++:関数の引数として構造体の配列

typedef struct 
{ 
    int nNum; 
    string str; 
}KeyPair; 

のは、私は私の構造体を初期化するとしましょう:

KeyPair keys[] = 
{ {0, "tester"}, 
    {2, "yadah"}, 
    {0, "tester"} 
}; 

私は、関数で初期化された値を使用します。 この配列構造体を関数パラメータとして渡すにはどうすればよいですか?

は私が持っている:

FetchKeys(KeyPair *pKeys) 
{ 
    //get the contents of keys[] here... 
} 
+0

もしあなたがC++を書いているのであれば、typedef構造体を書く必要はありません。struct KeyPair {...}を宣言するだけです。 –

答えて

3

ので キーと&キー[0]は同じであり、(任意の型の)配列のC/C++名で

// Definition 
void FetchKeys(KeyPair *pKeys, int nKeys) 
{ 
    //get the contents of keys[] here... 
} 
// Call 
FetchKeys(keys, sizeof(keys)/sizeof(keys[0])); 
+7

私は何度もこのことを言わなければいけないのですが、オブジェクトのサイズと配列のインデックスを表すのに 'int'の代わりに' size_t'を使用してください。 –

+2

#define countOf(a)(sizeof(a)/ sizeof(*(a))) – tato

+1

@tatoここで#defineを使う必要はありません。テンプレートを使ってそれを行うことができます:template size_t countOf(T(&arr)[N])はNを返します。誤って配列の代わりにポインタを渡すという副作用がありません。 – CashCow

1

あなただけFetchKeys「戻り値の型を宣言するFetchKeys(keys);

EDIT

有料注意を喚起する。

EDIT 2

あなたはまた、アイテムの数が必要な場合は、FetchKeys入力パラメータとしてサイズを追加します。

void FetchKeys(KeyPair*, size_t size); 

とBTW FetchKeys(keys, sizeof(keys)/sizeof(*keys));

を呼び出し、状態のすべてのあなたの質問によって、できるだけ最初の投稿を編集してください。

+0

配列にはいくつの要素があるのでしょうか? –

+1

あなたはそうではありません。そういうわけで、普通の配列よりもstd :: vectorの使用を推奨している人が常にいるでしょう。 –

+0

@Mad:Psst、rethorical question。 –

1

配列の最初の要素のアドレスを表してある必要があります。 KeyPair *のいずれかを渡すことができます。

+0

C/C++配列では、最初の要素へのポインタへの崩壊**がかなり簡単に行われます。これは配列の名前が最初の要素のアドレスを表すと主張するのと同じではありません* - 配列の名前は配列を表し、**は最初の要素へのポインタではありません。あなたの解釈が失敗する実際のユースケース(C++のみ)の@Chubsdad答えを見てください。 –

+0

Cテストの場合は、次のようにしてください: 'void foo(int(* array)[5]){} int main(){int array [5] = {0}; foo(&array); int array2 [2] = {0};/* foo(&array2)* /} '配列は5つの要素を持つため、コードは最初のケースでコンパイルされますが、要素の数が異なるので2番目の(コメントアウトされた)ケースで失敗します。このテストでは、配列が最初の要素へのポインタではなく、サイズ情報を持っていることが検証されます。この情報は、コンパイル時にのみ使用可能で、配列*がポインタに崩壊する前に使用できます。 –

4

上記の@MSaltersとして実行することもできますし、std::vector<KeyPair>を作成して関数に渡すこともできます。ここにサンプルコードがあります:

using namespace std; 

struct KeyPair 
{ 
    int nNum; 
    string str; 
}; 

void fetchKeys(const vector<KeyPair>& keys) 
{ 
    //Go through elements of the vector 
    vector<KeyPair>::const_iterator iter = keys.begin(); 
    for(; iter != keys.end(); ++iter) 
    { 
     const KeyPair& pair = *iter; 

    } 
} 



int main() 
{ 
    KeyPair keys[] = {{0, "tester"}, 
        {2, "yadah"}, 
        {0, "tester"} 
        }; 

    //Create a vector out of the array you are having 
    vector<KeyPair> v(keys, keys + sizeof(keys)/sizeof(keys[0])); 

    //Pass this vector to the function. This is safe as vector knows 
    //how many element it contains 
    fetchKeys(v); 
    return 0; 

} 
+0

それは私がそれをやる方法です。 –

+0

確かに。 (例えば、従来の関数インタフェースのために)強制されない限り、配列を使用しないでください。 – Gorpik

5

どのようにですか?

template<int N> void FetchKeys(KeyPair const (&r)[N]){} 

EDIT 2:

FetchKeys(&keys); 
として

、あるいはコールと

template<int N> void FetchKeys(KeyPair const (*p)[N]) 

+1

参照バージョンは+1です...可能であれば2番目の例の余分なポインタは避けています(値を追加せずにコードを読みにくくしています) –

0

はこの回答を参照してください。How can I pass an array by reference to a function in C++?

は素敵な、構造で包みそして...

#include <iostream> 

struct foo 
{ 
    int a; 
    int b; 
}; 

template <typename _T, size_t _size> 
struct array_of 
{ 
    static size_t size() { return _size; } 
    _T data[_size]; 
}; 

template <typename _at> 
void test(_at & array) 
{ 
    cout << "size: " << _at::size() << std::endl; 
} 

int main(void) 
{ 
    array_of<foo, 3> a = {{ {1,2}, {2,2}, {3,2} }}; 

    test(a); 

} 

EDIT簡単:URGH、私はコードを正しくフォーマットするツールバーを見ることができない、うまくいけば、タグの作品..

+0

簡単な質問です。 Cでは、アンダースコアで始まり大文字(すなわち '_T ')で始まる識別子は予約されており、それらを使用すると未定義の動作になります。テンプレートの場合でもC++に同じ制限があるかどうか知っていますか? – dreamlax

+0

@dreamlax:["C++識別子でアンダースコアを使用する際の規則は何ですか?"](http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore -in-ac-identifier)。アンダースコアと大文字で始まる識別子は、どのスコープでも予約されています。 –

+0

@dreamlax、ありがとう、奇妙なことが起こっていて、私はフォーマット/コメントできませんでした、今は大丈夫と思われる...あなたの質問に関して、私はちょうど怠け者でした... – Nim

1

あなたはあなたもブースト範囲を使用して、イテレータの組として機能するようにそれを渡すことができます何をしたいかに応じて:

void FetchKeys(KeyPair *begin, KeyPair *end) 
FetchKeys(boost::begin(keys), boost::end(keys)); 
0

私はVS 2008を使用し、これは私のために正常に動作します。

#include "stdafx.h" 

typedef struct 
{ 
    int nNum; 
    CString str; 
}KeyPair; 

void FetchKeys(KeyPair *pKeys); 
int _tmain(int argc, _TCHAR* argv[]) 
{ 

    KeyPair keys[] = 
{ {0, _T("tester")}, 
    {2, _T("yadah")}, 
    {0, _T("tester")} 
}; 

    FetchKeys(keys); //--> just pass the initialized variable. 
    return 0; 
} 

void FetchKeys(KeyPair *pKeys) 
{ 
    printf("%d, %s\n",pKeys[0].nNum, pKeys[0].str); 

} 

難易度は分かりません。私が間違っているなら、私を修正してください。簡単にするために、ベクトルやテンプレートなどを使うのを避けました。 edit:構造体のサイズを知るために、もう1つargを渡すことができます。

関連する問題