2015-04-20 2 views
-1

Хорошо, я работаю над проектом, который имеет дело с карточками и должен знать, сколько из каждого костюма и сколько у каждого из них есть, чтобы он мог его оценить. (Я не ожидаю, что вы делаете это для меня, я просто нужна помощь понимание.) Я продолжаю получать предупреждения, которые говорят:Проблемы с указателями в программе C

«слишком много аргументов для формата»

«передавая аргумент 1 из«suitsInHand из несовместимого указателя»

„инициализация делает целое число от указателя без броска“

„сравнение между указателем и целым“

Я перечитал главу на указателях в 3 раза, и теперь я до сих пор путаю с как использовать t рубчик. Если кто-то может объяснить, что не так с моим кодом, поэтому я могу попытаться правильно его закодировать, я бы очень признателен. Я помещал ** ** вокруг предупреждающих строк, чтобы я их написал.

Эти функции, определенные в начале программы

// prototypes 
void shuffle(unsigned int wDeck[][ FACES ]); // shuffling modifies wDeck 
void deal(unsigned int wDeck[][ FACES ], const char *wFace[], const char *wSuit[]); // dealing doesn't modify the arrays 
void handDeal(unsigned int wDeck[][ FACES ], const char *wFace[], const char *wSuit[]); 
void determineHand(unsigned int suitsInHand[], unsigned int facesInHand[]); 

int suitsInHand(unsigned int wDeck[][ FACES ], const char *wSuit[ ]); 
int facesInHand(unsigned int wDeck[][ FACES ], const char *wFace); 

И это позже в функции, где я, имеющий наибольшие проблемы. wDeck и wFace происходят из функций тасования и обработки. Рука наносит 5 карт в порядке, это получает эту информацию, вот в чем проблема.

void handDeal(unsigned int wDeck[][ FACES ], const char *wFace[], const char *wSuit[]) 
{ 
size_t cardCount; 
size_t row; 
size_t column; 

// deal each of the cards 
for (cardCount = 1; cardCount <= 5; ++cardCount) { 
    // loop through the rows of wDeck 
    for (row = 0; row < SUITS; ++row) { 
     // loop through columns of deck for current row 
     for (column = 0; column < FACES; ++column) { 
      // if slot contains current card, display card 
      if (wDeck[ row ][ column ] == cardCount) { 
       **printf("\n%5s of %-8s", wFace[ column ], wSuit[ row ], cardCount);** 
      } // end if 
     } // end 2nd inner for 
    } // end inner for 
} // end outer for 

//int *suitPtr = &wSuit[ & wFace[ column ], &wSuit[ row], cardCount ]; 
//in *facePtr = &wFace[ column ]; 

**suitsInHand(&wDeck, wSuit[ row ]);** 
//facesInHand(&wDeck, &wFace[ column ]); 

} // end function handDeal 

// determine suits in hand 
int suitsInHand(const char ) 
{ 
size_t suitCount; // counter 
size_t row; 
int totalSuits; // total number of suits in hand 
**int suit = wSuit[ row ];** 

// determine number of suits 
for (suitCount = 0; suitCount <= 4; ++suitCount) { 
    **if (wSuit[ row ] <= 4) {** 
     totalSuits = suit % 4; 
     printf("\nYou have %d suits", totalSuits); 
    } // end if 
} // end for 

} // end function suitsInHand 

// determine faces in hand 
/*int facesInHand(unsigned int wDeck[][ FACES ], const char *wFace[]) 
{ 
int totalFaces = 0; 

*facePtr = *facePtr % 13; 

printf("\nYou have %d faces", *facePtr); 

} // end function facesInHand */ 

ответ

0

В вашем объявлении void handDeal(unsigned int wDeck[][ FACES ], const char *wFace[], const char *wSuit[]) вы определяете, wFace и wSuit как указатели на массивы. Это эквивалент указателя на указание char ** wSuit.

Когда вы выделяете массив, например char wSuit[5], wSuit указывает на первый элемент массива. вы можете получить значение первого элемента массива либо по индексу wSuit[0], либо путем разыменования указателя *wSuit. Когда вы указываете указатель на этот массив (т. Е. Char * wSuit [] OR char ** wSuit), вы создаете указатель, который содержит адрес указателя, который указывает на первый член массива. Имеет ли это смысл?

Еще одна проблема, с которой вы сталкиваетесь, заключается в том, что вы используете неопределенную переменную для выделения вашего массива в стеке. Во время компиляции значение row неизвестно, поэтому компилятор не может правильно выделить память, необходимую для вашего массива. используя определенное значение (например, 5) или динамически выделяя память (например, (char *) malloc (sizeof (char) * row)), должны работать на вас.

Я вижу здесь несколько других вопросов, но, надеюсь, это должно помочь вам немного дальше.

+0

строка определенно не определена, но распределение массивов отлично подходит для C99 (VLA). – Olaf

+0

@Olaf - я неправильно читаю строку, где, как я думал, код выделяет массив на основе неопределенной переменной. Приведенный выше пример кода фактически не показывает, как распределяется массив. Если, однако, массив выделяется неизвестным размером, у вас возникнут потенциально опасные проблемы. Например, если 'char wSuit [строка]' и строка получает программно, как компилятор знает, определять ли массив как размер 5 или 5000 или ??? – jfrattarola

+0

@jfrattarola Массивы 'define'd в начале кода, у меня просто не было этой части. И спасибо, это помогло немного по крайней мере. –

0

слишком много аргументов для формата

должно быть легко понять. Давайте посмотрим на заявление вызывает проблему:

printf("\n%5s of %-8s", wFace[ column ], wSuit[ row ], cardCount); 

У вас есть два заполнителей в строке формата, %5s и %-8s, но вы передаете три дополнительные аргументы (wFace[column], wSuit[row] и cardCount). Один из них не нужен, и это будет тот, который не является строкой.

передавая аргумент 1 из «suitsInHand из несовместимых указатель

Вот заявление на suitsInHand:

int suitsInHand(unsigned int wDeck[][ FACES ], const char *wSuit[ ]); 

Вот где вы это называете:

suitsInHand(&wDeck, wSuit[ row ]); 

У вас есть тип несоответствия здесь. Во-первых, давайте посмотрим на то, как wDeck объявлен в handDeal:

unsigned int wDeck[][ FACES ] 

В списке параметров функции, объявление о формах T a[N] и T a[] оба рассматриваются как T *a; все три объявляют a в качестве указателя на T. Это означает, что объявление типа T a[][N] объявит a в качестве указателя на массив N - T или T (*)[N].

Таким образом, выражение wDeck имеет тип «указатель на FACES -элементного массив unsigned int», или unsigned int (*)[FACES].

Это тот же тип, что и первый параметр suitsInHand, поэтому все, что вам нужно сделать, это просто передать выражение wDeck. К сожалению, вы проходите &wDeck, у которого есть тип «указатель на указатель на FACES -элементный массив unsigned int», или unsigned int (**)[FACES], что является несовместимым.

У вас будет аналогичная проблема со вторым аргументом; wSuit[row] даст вам одно значение char *, но функция ожидает значение char **.

инициализация делает целое число от указателя без броска

Другого типа рассогласования. wSuit объявлен как char *[], что совпадает с char ** в объявлении параметра функции, поэтому выражение wSuit[row] имеет тип char *. Это не того же типа, что и int (указатели не являются целыми числами).

сравнение между указателем и целое

Те же проблемы, как и раньше, - вы хотите, чтобы лечить wSuit[row] как целое, но вы объявили его как указатель на char, и вы не можете напрямую сравнивать целые значения с указательными значениями.

Вам нужно решить, является ли wSuits массив строк или целых чисел.

+0

Это очень помогло, спасибо! –

Смежные вопросы