如何在 C 中分配子数组的值?
Posted
技术标签:
【中文标题】如何在 C 中分配子数组的值?【英文标题】:How do I assign the value of a subarray in C? 【发布时间】:2022-01-01 01:40:42 【问题描述】:我已经初始化了以下数组来存储井字游戏中的移动(最多可以有 100 个移动(10x10 网格)。每个子数组需要存储移动的行和列,以及放置在那里的符号。
char moves[100][3];
然后我想将这三个值插入到每个子数组中。我使用变量moveCount
作为我想要存储移动数据子数组的索引。
moves[moveCount] = row, col, symbol;
但是这会引发错误“表达式必须是可修改的左值”。如何将移动数据的子数组插入到整个数组中?
【问题讨论】:
请出示minimal reproducible example 【参考方案1】:这个语句有两个错误
moves[moveCount] = row, col, symbol;
第一个是表达式moves[moveCount]
是一个数组,数组没有赋值运算符。
第二个是大括号中的列表不是表达式。
你需要写
moves[moveCount][0] = row;
moves[moveCount][1] = col;
moves[moveCount][2] = symbol;
考虑定义一个结构类型的对象的一维数组,而不是定义二维数组,该数组将包含三个数据成员行、列和符号。
【讨论】:
【参考方案2】:在 C 中,您不能将值分配给数组,而只能分配给单独的数组成员。
但我怀疑数组是否适合您。 您想存储 3 个具有不同含义的值。那将需要一个结构而不是一个数组:
typedef struct
char row;
char col;
char symbol;
move_t;
move_t moves[100];
然后您可以使用复合文字为每个元素分配新值:
moves[movecount]=(move_t)row, col, symbol;
【讨论】:
【参考方案3】:我不确定如何在一行中做到这一点,但这对我有用:
char moves[10][3];
moves[0][0] = 'a';
moves[0][1] = 'b';
moves[0][2] = 'c';
因此,如果您可以一个一个地分配值,那将是一种选择。
我还发现here 是您可以创建一个额外的数组并使用您的值对其进行初始化,然后将其复制到您需要的位置。
char moves[10][3];
char values[3] = '1', '2', '3';
memcpy(moves[0], values, sizeof(values));
【讨论】:
【参考方案4】:来自莫斯科的 Vlad 是对的,您不能以这种方式分配数组。 它的解决方案是正确的方法,但您可以考虑使用更紧凑的方式来表示您的网格。
您只需要 1 位来表示游戏的 2 种状态“O”或“X”中的一种,并且需要 4 位来表示行或列的值。因此,4 + 4 + 1 = 9 位就足够了,您可以将它们一起存储在一个 16 位变量 (uint16_t) 中。
考虑一种特殊情况,当值为 0 时,该位置没有发生任何移动。
使用宏来获取和设置正确的值:
#define FIELD_SIZE ((1 << 4) - 1)
#define GET_ROW(x) (x & FIELD_SIZE)
#define GET_COL(x) ((x >> 4) & FIELD_SIZE)
#define IS_EMPTY(x) (x == 0)
#define GET_SYMBOL(x) (!(x >> 8))
位架构:
+---UNUSED---+-SYMBOL-+--COL--+--ROW--+
16-9 8 7-4 3-0
GET_SYMBOL 返回 1 或 0。
但是,我更喜欢 Gerhardh 的解决方案。它清晰且易于管理。 您仍然可以节省一些位:
typedef struct
char row:4;
char col:4;
char symbol;
move_t;
【讨论】:
您不应该使用普通的char
来输入结构位域。如果编译器使用有符号字符和有符号位域范围,则该范围不足以容纳 10 行或列。一般来说,我认为结构位域不值得在这里节省几个字节。
你是对的,你可以用uint8_t替换char。节省字节的用处可能取决于上下文。以上是关于如何在 C 中分配子数组的值?的主要内容,如果未能解决你的问题,请参考以下文章