2016-11-08 4 views
6

Новый для указателей и C и для моей программы нужен указатель на массив структур и возможность передать этот указатель на функцию.Как объявить указатель на массив структур в C

Каков правильный способ объявить указатель на тип массива struct и какой должен быть параметр моей функции, который может принимать такой указатель?

Это моя попытка:

#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: Вы делаете это на C++ в онлайн-среде. Вопрос о такой же функциональности в C. – skrtbhtngr

+0

@skrtbhtngr Извините, я не понял, что изменить 'g ++' на 'gcc' недостаточно, когда файл заканчивается на' .cpp'. – Angew

4

Массив деградирует в исходный указатель на первый элемент массива. Таким образом, вы можете сделать что-то больше, как это вместо:

#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; 
}; 

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... 
    } 
} 

С другой стороны, создать новый ЬурейеЕ для массива карт, а затем вы можете создавать переменные и указатели этого типа:

#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

Спасибо, что имеет смысл. Почему второй параметр int? – user2300867

+0

Второй параметр - узнать размер фактического массива в вызываемой функции. – 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 
... 
} 
Смежные вопросы