首页 > 解决方案 > 使在 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;
}

标签: arrayscfunctionscope

解决方案


最简单的解决方案是在文件范围(通常称为“全局范围” )声明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中不存在关键字publicand ;private它们通常仅用于支持面向对象(或基于类)编程的语言中。关键字static确实存在,但根据上下文具有不同的含义。最好不要重新定义。
请注意,第二维应为 9:8 个字符和 1 个空终止符

在文件范围内具有变量的缺点是它们在整个文件中都是可见的,并且随着多个函数修改它们的内容,可能难以监督和推理程序的行为。

也许最好的解决方案是保留boardbase声明 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以及“字符串文字”/“空终止符”。


推荐阅读