【问题标题】:Make an array that was initalised in main accessible to other functions使在 main 中初始化的数组可供其他函数访问
【发布时间】:2021-11-01 23:25:06
【问题描述】:

我正在尝试制作井字游戏,并且我正在使用一种单独的方法,该方法会在每回合后更新棋盘。但是,我似乎无法访问在main() 中初始化的二维数组board。 我已经尝试将其公开,就像在 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;
}

【问题讨论】:

  • 发送板作为函数 updateBoard 的参数。
  • 或者在主函数之外“全局”声明它。
  • #define private static 似乎很糟糕。 static 在 c 中有多种含义。如果它位于函数范围之外的声明中,则它可以表示“仅此翻译单元(例如 *.c 文件)的范围”,而在函数范围内则表示(简化)“保留此变量的值重复调用此函数。”同样通过#define static,您可能会在不知情的情况下破坏很多东西,例如,如果头文件的任何地方都包含static

标签: arrays c function scope


【解决方案1】:

最简单的解决方案是在file scope 声明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中不存在关键字publicprivate;它们通常仅用于支持面向对象(或基于类)编程的语言中。关键字static 确实存在,但根据上下文具有不同的含义。最好不要重新定义。
注意第二维应该是9:8个字符和1个null-terminator

在文件范围内具有变量的缺点是它们在整个文件中可见,并且由于多个函数修改其内容,因此很难监督和推理程序的行为。

也许最好的解决方案是在main 中声明boardbase,并将它们传递给updateBoard。尽管这立即引入了一些更高级的 C 概念。向函数原型和函数调用添加必要的附加参数/参数可能对您来说很熟悉。问题在于数组参数转换为指针(参见here,通常称为“数组到指针衰减”)。这意味着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 和“字符串文字”/“null-terminator”。

【讨论】:

    猜你喜欢
    • 2012-08-25
    • 2017-09-17
    • 1970-01-01
    • 2023-03-04
    • 2015-08-28
    • 1970-01-01
    • 2013-10-21
    • 2020-02-17
    • 2019-10-26
    相关资源
    最近更新 更多