Очевидно, что вы застряли в понимании объявлений функций, где вы использовали int
и где вы использовали char
. (типы имеют значение).
Прежде чем обратиться к чему-либо еще, первое, что вы можете сделать, чтобы ваш компилятор помог вам с кодом, - включите предупреждения компилятора . Это означает, что как минимум для gcc / clang, добавьте -Wall -Wextra
в качестве параметров компилятора (рекомендуем: -Wall -Wextra -pedantic -Wshadow
), для VS (cl.exe
) используйте /W3
и - не принимайте код, пока он не скомпилируется без предупреждение ! Ваш компилятор скажет вам точную строку (и много раз столбец), где он видит проблемный код. Пусть компилятор поможет вам написать лучший код.
Далее вы используете константу SIZE
, чтобы указать размеры для board
. Хорошо! Если вам нужна постоянная - #define
одна или несколько - как у вас есть. Поймите, когда вы определяете константу, она имеет область видимости файла, ее можно увидеть и использовать в любой функции в этом файле (или в любом файле, который содержит заголовок, в котором определена константа). Таким образом, нет необходимости передавать SIZE
в качестве параметра вашим функциям. Они знают, что такое SIZE
, например ::1010 *
void display_table (char board[][SIZE]);
void clear_table (char board[][SIZE]);
Далее вы не можете повторно объявить char board[row][col];
, как в clear_table()
. Это объявление «затеняет» объявление board
от main()
, что вы передаете параметр, например void clear_table (char board[][SIZE]);
. (таким образом, совет по включению опции компилятора -Wshadow
, чтобы предупредить вас, когда вы попробуете что-то творческое ....) То же самое применимо к display_table
.
Когда вы повторно декларируете board
в clear_table
(например, char board[row][col];
) и затем используете board
в clear_table
, вы обновляете повторно объявленный board
, то есть local к функции (и, следовательно, уничтожается при возврате функции), поэтому изменения никогда не будут видны в main()
.
Далее вы объявляете плату как char
в main()
, например,
char board[SIZE][SIZE] = {{0}}; /* initialize all variables */
, но затем попытайтесь передать board
как тип int
, например,
void display_table (int board[][SIZE], int SIZE) {
Ваш параметр должен соответствовать вашему типу объявления.
С этими простыми настройками и очисткой clear_table
и display_table
просто немного, вы можете сделать что-то вроде:
/* display table function */
void display_table (char board[][SIZE])
{
int row, col;
printf ("\nThe current state of the game is:\n");
for (row = 0; row < SIZE; row++) {
for (col = 0; col < SIZE; col++) {
putchar (' ');
if (board[row][col])
putchar (board[row][col]); /* use putchar for a single char */
else
putchar ('_');
}
putchar ('\n');
}
}
/* clear table function */
void clear_table (char board[][SIZE])
{
int row, col;
// char board[row][col]; /* don't redeclare board */
/* your compiler should be screaming warnings */
for (row = 0; row < SIZE; row++)
for (col = 0; col < SIZE; col++)
board[row][col] = '_'; /* just clear, no need to check */
}
Теперь просто убедитесь, что вы предоставили прототип функций выше main()
в вашем файле, чтобы main()
знал о существовании обеих функций, прежде чем они будут вызваны в main()
(в качестве альтернативы вы можете просто переместить определение обеих функций выше main()
). (функция должна быть объявлена до того, как ее можно будет использовать - это означает, что над функцией, где она вызывается при «чтении сверху» файла)
Ваш код для обеих функций был не так уж и далек, вы просто упустили несколько деталей реализации (правил). Чтобы обеспечить рабочие clear_table
и display_table
(наряду с функцией cheezy diagonal_x
для инициализации диагонали для всех 'x'
, а оставшуюся часть для 'o'
, вы можете сделать:
#include <stdio.h>
#define SIZE 3 /* if you need a constant, #define one (Good!) */
void display_table (char board[][SIZE]);
void clear_table (char board[][SIZE]);
/* cheezy init funciton */
void diagonal_x (char (*board)[SIZE])
{
for (int row = 0; row < SIZE; row++)
for (int col = 0; col < SIZE; col++)
if (row == col)
board[row][col] = 'x';
else
board[row][col] = 'o';
}
int main (void) /* no comment needed, main() is main() */
{
char board[SIZE][SIZE] = {{0}}; /* initialize all variables */
clear_table (board); /* set board to all '_' */
display_table (board); /* output board */
diagonal_x (board); /* init board to diagonal_x */
display_table (board); /* output board */
/*
do {
get_player1_mover (board, row, col);
generate_player2_move (board, row, col);
} while (check_end_of_game (board) == false);
print_winner (board);
*/
return 0;
}
/* display table function */
void display_table (char board[][SIZE])
{
int row, col;
printf ("\nThe current state of the game is:\n");
for (row = 0; row < SIZE; row++) {
for (col = 0; col < SIZE; col++) {
putchar (' ');
if (board[row][col])
putchar (board[row][col]); /* use putchar for a single char */
else
putchar ('_');
}
putchar ('\n');
}
}
/* clear table function */
void clear_table (char board[][SIZE])
{
int row, col;
// char board[row][col]; /* don't redeclare board */
/* your compiler should be screaming warnings */
for (row = 0; row < SIZE; row++)
for (col = 0; col < SIZE; col++)
board[row][col] = '_'; /* just clear, no need to check */
}
( примечание: независимо от того, включаете ли вы '{'
и '}'
в циклы или условные выражения, содержащие только одно выражение, зависит только от вас. Это может помочь сделать все для вас - вплоть до вас. )
Также обратите внимание, что вы можете передать board
как указатель на массив из char [SIZE]
, например. char (*board)[SIZE]
, а также char board[][SIZE]
, они эквивалентны.
Пример использования / Вывод
Примечание: я добавил пробел перед каждым символом на доске, чтобы сделать отображение немного более читабельным - вы можете удалить его, если хотите.
$ ./bin/checkerinit
The current state of the game is:
_ _ _
_ _ _
_ _ _
The current state of the game is:
x o o
o x o
o o x
Это должно помочь вам. Дайте мне знать, если у вас есть дополнительные вопросы.