arrays - 使在 main 中初始化的数组可供其他函数访问
问题描述
我正在尝试制作井字游戏,并且我正在使用一种单独的方法,该方法将在每回合后更新棋盘。但是,我似乎无法访问在board
中初始化的 2D 数组main()
。我已经尝试将其公开,就像您在 Java 中所做的那样,但它似乎不起作用。任何帮助将不胜感激。
#include <stdio.h>
#include <stdlib.h>
#define public
#define static
#define private static
int main(void) {
public char board[5][8] = { " | | ", "--+--+--", " | | ", "--+--+--", " | | " };
int turn = 0;
public static int base = 0;
for (size_t row = 0; row < sizeof(board) / sizeof(board[0]); row++) {
for (size_t col = 0; col < sizeof(board[0]) / sizeof(board[0][0]); col++)
printf("%c", board[row][col]);
printf("\n");
}
printf("Player1's turn\n ");
fflush(stdout);
scanf("%i", &turn);
updateBoard(&turn);
}
void updateBoard(int a){
switch (a) {
case 1:
board[0][0] = 'X';
break;
case 2:
board[0][4] = 'X';
break;
case 3:
board[0][6] = 'X';
break;
case 4:
board[2][0] = 'X';
break;
case 5:
board[2][4] = 'X';
break;
case 6:
board[2][6] = 'X';
break;
case 7:
board[4][0] = 'X';
break;
case 8:
board[4][4] = 'X';
break;
case 9:
board[4][6] = 'X';
break;
default:
printf("Please input a correct value (1-9)");
}
for (size_t row = 0; row < sizeof(board) / sizeof(board[0]); row++) {
for (size_t col = 0; col < sizeof(board[0]) / sizeof(board[0][0]); col++)
printf("%c", board[row][col]);
printf("\n");
}
base = 1;
}
解决方案
最简单的解决方案是在文件范围(通常称为“全局范围” )声明board
(并且base
,假设它将用于将来的某些事情) :
static int base = 0;
static char board[5][9] = { " | | ", "--+--+--", " | | ", "--+--+--", " | | " };
void updateBoard(int a);
int main(void)
{
int turn = 0;
// ...
它们被声明为static
,这意味着它们仅对该文件中的代码可见,并且不能从同一程序的其他文件中访问。
我已经删除了#define
's。C中不存在关键字public
and ;private
它们通常仅用于支持面向对象(或基于类)编程的语言中。关键字static
确实存在,但根据上下文具有不同的含义。最好不要重新定义。
请注意,第二维应为 9:8 个字符和 1 个空终止符。
在文件范围内具有变量的缺点是它们在整个文件中都是可见的,并且随着多个函数修改它们的内容,可能难以监督和推理程序的行为。
也许最好的解决方案是保留board
并base
声明 in main
,并将它们传递给updateBoard
. 尽管这立即引入了一些更高级的 C 概念。向函数原型和函数调用添加必要的附加参数/参数可能对您来说很熟悉。问题是数组参数转换为指针(参见此处,通常称为“数组到指针衰减”)。这意味着sizeof
不再提供整个数组的大小,而是提供指向数组第一个元素的指针的大小。在下面的解决方案中,这是通过在 main 中获取维度,将它们存储在变量中并将这些值传递给函数来解决的。可以说,这比使用sizeof
到处计算。一旦设置了变量,这也将适用于动态分配的数组。
// Forward declaring the function, so main knows it exists
void updateBoard(char board[5][9], size_t nRows, size_t nCols, int base, int a);
int main(void)
{
int base = 0;
// Note the 9 for the second dimension
char board[5][9] = { " | | ", "--+--+--", " | | ", "--+--+--", " | | " };
int turn = 0;
// Initializing the variables for the dimensions...
size_t nRows = sizeof(board) / sizeof(board[0]);
size_t nCols = sizeof(board[0]) / sizeof(board[0][0]);
// ...which we can now use here as well...
for (size_t row = 0; row < nRows; row++) {
for (size_t col = 0; col < nCols; col++)
printf("%c", board[row][col]);
printf("\n");
}
printf("Player1's turn\n ");
fflush(stdout);
scanf("%i", &turn);
// ... and here, along with passing board and base.
updateBoard(board, nRows, nCols, base, turn);
}
void updateBoard(char board[5][9], size_t nRows, size_t nCols, int base, int a){
switch (a) {
// ... code omitted for brevity ...
}
// Use the passed dimension values here
for (size_t row = 0; row < nRows; row++) {
for (size_t col = 0; col < nCols; col++)
printf("%c", board[row][col]);
printf("\n");
}
base = 1;
}
像这样传递变量,通过引用传递变量和通过值传递变量之间有一个重要的区别。也许这是您在 C 旅程中要研究的一个很好的下一个主题,static
以及“字符串文字”/“空终止符”。
推荐阅读
- ios - iOS 为什么 NSParagraphStyle 会重置原始文本样式
- java - javax.mail.Part.getContent() ArrayIndexOutOfBoundsException:16448
- kubernetes - Kubernetes 集群自动扩缩器似乎不适用于 GKE?
- sql - 复制列中的所有数字并将其粘贴到 ID 值小 1 的行
- ruby - 使用 Ruby 正则表达式删除子字符串
- d3.js - 使用功能图绘制的最后一个图形的坐标
- mysql - mysql连接表和联合表有修改结果?
- ios - iOS 将 ARSCNView 推送到 UINavigationController 并从中返回
- fiware - 使用 HTTPS 在 docker 上运行 Orion
- google-app-engine - Datanucleus GAE 拥有的关系不起作用