在C语言中如何创建存储{S2、R4}类字符串的不可修改二维数组?
解决方案:用二维字符串数组替代char二维数组
你的需求是存储包含多字符的字符串(比如"S6"、"accept"),原有的char二维数组只能存单个字符,完全满足不了。最直接的替代方案是二维字符串数组,也可以根据场景选择结构体数组,以下是具体实现:
1. 字符指针二维数组(推荐,节省空间)
用char*类型定义二维数组,每个元素指向字符串字面量,结构和原代码完全一致,只需要修改类型和初始化内容:
#include <stdio.h> int main(void) { char* parsing_table[12][9] = { {"0","0","0","0","0","0","0","0","0"}, {"0","0","0","0","0","0","0","0","1"}, {"0","0","0","0","S6","0","0","0","0"}, {"0","0","0","0","0","R3","0","0","0"}, {"0","R3","0","0","0","0","accept","0","0"}, {"0","0","0","0","0","0","0","0","0"}, {"0","0","0","0","0","R1","0","4","0"}, {"0","0","S11","0","0","0","0","0","5"}, {"0","0","0","0","S8","0","0","0","0"}, {"0","R5","0","0","0","0","0","1","0"}, {"0","0","0","0","0","0","0","0","0"}, {"0","0","0","0","0","0","0","2","0"} }; for(int i = 0; i < 12; i++) { for (int j = 0; j < 9; j++) { printf("%s ", parsing_table[i][j]); } puts(""); } return 0; }
- 优点:不需要预先分配固定长度的字符数组,内存占用更高效,初始化和原结构完全匹配。
- 注意:字符串字面量是只读的,如果需要修改数组中的字符串,这种方式不适用。
2. 固定长度的三维char数组(支持修改)
如果需要后续修改数组中的字符串内容,可以定义三维char数组,每个元素是固定长度的字符数组:
#include <stdio.h> #include <string.h> int main(void) { // 第三维的10表示每个字符串最多存9个字符+1个结束符'\0' char parsing_table[12][9][10] = {0}; // 初始化内容 strcpy(parsing_table[1][8], "1"); strcpy(parsing_table[2][4], "S6"); strcpy(parsing_table[3][5], "R3"); strcpy(parsing_table[4][1], "R3"); strcpy(parsing_table[4][6], "accept"); strcpy(parsing_table[6][5], "R1"); strcpy(parsing_table[6][7], "4"); strcpy(parsing_table[7][2], "S11"); strcpy(parsing_table[7][8], "5"); strcpy(parsing_table[8][4], "S8"); strcpy(parsing_table[9][1], "R5"); strcpy(parsing_table[9][7], "1"); strcpy(parsing_table[11][7], "2"); // 未初始化的元素默认是空字符串,可以根据需求补充 for(int i = 0; i < 12; i++) { for (int j = 0; j < 9; j++) { printf("%s ", parsing_table[i][j]); } puts(""); } return 0; }
- 优点:可以随时修改数组中的字符串内容(用
strcpy等函数)。 - 缺点:需要预先定义字符串的最大长度,内存占用比指针数组高。
3. 结构体二维数组(适合复杂场景)
如果每个元素除了字符串,还需要额外的元数据(比如标记是移进、规约还是接受),可以定义结构体:
#include <stdio.h> typedef struct { char type; // 'S'=移进, 'R'=规约, 'A'=接受, 'N'=空 int value; // 对应数字,空或接受时可以设为-1 } Action; int main(void) { Action parsing_table[12][9] = {0}; // 初始化示例 parsing_table[1][8] = (Action){'N', 1}; parsing_table[2][4] = (Action){'S', 6}; parsing_table[3][5] = (Action){'R', 3}; parsing_table[4][6] = (Action){'A', -1}; // 其他元素按需求初始化 for(int i = 0; i < 12; i++) { for (int j = 0; j < 9; j++) { switch(parsing_table[i][j].type) { case 'S': printf("S%d ", parsing_table[i][j].value); break; case 'R': printf("R%d ", parsing_table[i][j].value); break; case 'A': printf("accept "); break; case 'N': if(parsing_table[i][j].value != -1) printf("%d ", parsing_table[i][j].value); else printf("0 "); break; } } puts(""); } return 0; }
- 优点:结构化存储信息,便于后续逻辑处理,避免字符串解析的麻烦。
- 缺点:初始化和打印逻辑比字符串数组复杂。
内容的提问来源于stack exchange,提问作者Daghan
相关产品推荐
相关产品推荐

