2016-11-08 9 views
6

ポインタとCの新機能で、プログラムのポインタに構造体の配列のポインタが必要で、このポインタを関数に渡すことができます。Cの構造体の配列へのポインタを宣言する方法

構造体配列型のポインタを宣言する正しい方法と、そのようなポインタをとることができる関数のパラメータは何ですか?

これは私の試みです:

#define HAND_SIZE 5 

struct Card { 
    char suit; 
    char face; 
}; 

void printHandResults(struct Card *hand[HAND_SIZE]); 

int main(void) 
{ 
    struct Card hand[HAND_SIZE]; 
    struct Card (*handPtr)[HAND_SIZE]; //Correct way to declare? 
    handPtr = &hand; 
    ... 
    printHandResults(handPtr); 

} 
void printHandResults(struct Card *hand[HAND_SIZE]) { 
... 
} 

そして、これは私が手に警告です:

warning: incompatible pointer types passing 'struct Card (*)[5]' to parameter of type 'struct Card **' [-Wincompatible-pointer-types] 

私はポインタが異なったタイプですが、私はそれを正しく設定する方法を見つけ出すように見えるカント理解。

私が誰かが正しい方向にポインタを向けることができれば感謝します。

+0

配列は関数に渡されるときに自動的にポインタになりますが、別の変数は必要ありません。 – Barmar

+1

'struct card * hand [HAND_SIZE]'は、配列へのポインタではなく、ポインタの配列です。 – Barmar

+0

あなたのやり方でhandPtrはポインタの配列です。なぜあなたはprintHandResultsに手を渡していませんか? –

答えて

5

たぶん、あなたは何をしたいこれを行うことです。

void printHandResults(struct Card (*hand)[]); 

と、この:あなたは何をしていた

void printHandResults(struct Card (*hand)[]) { 

} 

がメインで、構造体変数の配列へのポインタを渡していたが、、この関数は、構造変数へのポインタの配列を受け取るように設定され、の配列へのポインタはではありません。これで型の不一致が発生せず、警告も出されませんでした。

[]こと、(四角)括弧は、オペレータ*を逆参照(単項)よりも高い優先順位を持っているので、私たちは私たちがここで話しているかを確認するために配列名と*演算子を括弧()のセットが必要になります!

+0

ありがとうございます。私は私のプログラムでこれを実験します。 – user2300867

+0

@Angew:これは、オンラインIDEのC++で行います。問題は、Cの同じ機能についてです。 – skrtbhtngr

+0

@skrtbhtngr申し訳ありませんが、ファイルが '.cpp'で終わっているときに' g ++ 'から 'gcc'への変更が不十分であることは分かりませんでした。 – Angew

4

配列は、最初の配列要素への生ポインタに分解されます。あるいは、

#define HAND_SIZE 5 

struct Card { 
    char suit; 
    char face; 
}; 

void printHandResults(struct Card *hand, int numInHand); 

int main(void) 
{ 
    struct Card hand[HAND_SIZE]; 
    ... 
    printHandResults(hand, HAND_SIZE); 
} 

void printHandResults(struct Card *hand, int numInHand) 
{ 
    for (int i = 0; i < numInHand; ++i) 
    { 
     // print hand[i].suit and hand[i].face as needed... 
    } 
} 

カードアレイ用の新しいのtypedefを作成し、あなたはその型の変数とポインタを作成することができます:また

#define HAND_SIZE 5 

struct Card { 
    char suit; 
    char face; 
}; 

void printHandResults(struct Card *hand); 

int main(void) 
{ 
    struct Card hand[HAND_SIZE]; 
    ... 
    printHandResults(hand); 
} 

void printHandResults(struct Card *hand) 
{ 
    for (int i = 0; i < HAND_SIZE; ++i) 
    { 
     // print hand[i].suit and hand[i].face as needed... 
    } 
} 

:だから、あなたはより多くの代わりにこのような何かを行うことができます

#define HAND_SIZE 5 

struct Card { 
    char suit; 
    char face; 
}; 

typedef struct Card Hand[HAND_SIZE]; 

void printHandResults(Hand *hand); 

int main(void) 
{ 
    Hand hand; 
    ... 
    printHandResults(&hand); 
} 

void printHandResults(Hand *hand) 
{ 
    for (int i = 0; i < HAND_SIZE; ++i) 
    { 
     // print hand[i].suit and hand[i].face as needed... 
    } 
} 
+0

ありがとう、これは理にかなっています。なぜ2番目のintパラメータですか? – user2300867

+0

2番目のパラメータは、呼び出された関数の実際の配列のサイズを知ることです。私は参照してください。 – skrtbhtngr

+0

しかし、私はすでに一定のHAND_SIZEとしてそれを持っており、関数本体からそれを使用することができますが、関数のパラメータとしてそれを必要としますか?説明してください。 – user2300867

0

もっと簡単な方法:

#define HAND_SIZE 5 

typedef struct Cards{ 
    char suit; 
    char face; 
}card_t; 

void printHandResults(card_t*); 

int main(void) 
{ 
    card_t hand[HAND_SIZE]; 
    card_t* p_hand = hand; 
... 
    printHandResults(p_hand); 

} 
void printHandResults(card_t *hand) 
{ 
// Here you must play with pointer's arithmetic 
... 
} 
関連する問題