在 c 中初始化 2d 字符数组 - tic tac toe 游戏

Initialize 2d char array in c - tic tac toe game

我在尝试用 c 编写井字游戏时感到困惑。我正在关注一本书,该书使用一个包含 8 个元素的字符数组来创建电路板。我知道一个数组 [8] 包含 9 个元素,但是如果数组被声明为 char 数组,因为它必须包含空格来为游戏制作空板,它不应该是数组 [9],因为它必须包含 9 个字符和一个空字符 '\0'?在将电路板转换为二维数组时我也有同样的疑问,因为我知道电路板应该用数组 [3][3] 制作,但是如果我想将它声明为 char,那么空字符?

二维数组本质上是一维数组,为程序员增加了易用性。您阅读的书可能只是将值存储在单元格中,并将它们显示出来,而不是像您所说的那样将一大块字符显示为字符串。这比将整个板存储为字符串更有效。

假设您要存储一个 4x4 面积的二维数组。您可以将其表示为大小为 16 的一维数组,并像这样访问索引:

arr[j + i * 4]

j 是你在那个 4 单元块中的位置,i 是你所在的 4 单元块。

此外,大小为 [8] 的数组有 8 个元素。例如:

char arr[8]; // has 8 elements, not 9

I know an array[8] contains 9 elements

不,为什么会这样?定义为 int arry[8] 的数组仅包含 8 个元素。同样,在 C 中,数组索引是基于 0 的,这意味着对于上述数组,只有 array[0]array[7] 是有效访问。

也就是说,对于 char 数组,要用作 字符串 ,也应该有 space 作为空终止符。所以,如果你想要一个包含 9 个元素的 char 数组并想将它用作 字符串 ,你需要将它定义为 char[10].

使用字符作为数组的值与 char 的数组可以衰减为指针 char* 并被解释为 NUL 的事实无关终止字符串。

字符串在 C 语言中没有特定的类型,它只是一种解释某些数据的方式。所以你混合了两个概念。

一个 char 数组不必 NUL 终止,如果你打算将它与将数据用作字符串的函数一起使用,它需要 NUL 终止.

char board[3][3] 是完全合法的,并且有 9 个字符元素的空间,它不需要 [=17=],因为您不会将该数据用作字符串。

如果使用字符数组存储字符串,则需要终止零。

对于您的任务,无需在数组中存储字符串。

因此在 C 中,您可以通过以下方式声明例如 3*3 数组

char board[3][3] =
{
   "   ", // three spaces
   "   ",
   "   "
};

数组的每个元素都不会包含终止零,尽管它是由字符串文字初始化的。

另一方面,如果您认为输出这样的数组会更简单,则可以在每个元素中包含终止零。在这种情况下,数组应该定义为

char board[3][4] =
//           ^^^
{
   "   ", // three spaces
   "   ",
   "   "
};

至于你的说法

an array[8] contains 9 elements

然后数组被声明为恰好有八个元素。 :) 我认为你的意思是字符串文字。例如,由于存储在文字中的终止零,C 中的字符串文字 "Hi" 具有类型 char[3]

一个字符数组可以在任何位置保存任何值。只有当您想要使用某些函数时,您才需要确保字符串末尾有一个 NUL 字符(即 0,而不是 '0'!)——它告诉函数什么时候停止处理!

所以:char john[4] = { 'J', 'o', 'h', 'n' }; 是完全合法的 - 只是不要将 john 传递给 strlen(),因为它会一直计数直到找到 0 值,并且数组中没有!

此外:char tictactoe[3][3]; 在任何地方都不需要 0 - 除非你尝试将 整个 数组传递给 printf()原因...

请注意,您可以安全地执行以下操作:

printf(" %c | %c | %c \n", tictactoe[0][0], tictactoe[0][1], tictactoe[0][2]);
printf("---+---+---\n");
printf(" %c | %c | %c \n", tictactoe[1][0], tictactoe[1][1], tictactoe[1][2]);
printf("---+---+---\n");
printf(" %c | %c | %c \n", tictactoe[2][0], tictactoe[2][1], tictactoe[2][2]);

因为使用 %c 意味着 "print one character",而不是 "print a string of characters"。

以 NUL 结尾的字符串形式通常称为 ASCIIZ(ASCII-Zeroed)字符串,这也是九个字符的数组只能容纳八个字符的字符串的原因(与什么相反)你说的)-它需要第九个来保持 NUL。

而且,和 C 中一样,任何数组都从 0 到长度为 1,因此在我的示例中 [0][1][2]