C语言如何正确打印存储MIPS寄存器名的char类型二维数组
问题原因与解决方案
核心问题根因
- 字符串输出规则问题:C语言中
printf的%s格式符要求输入的字符数组必须以\0(空终止符)作为结束标志。你定义的reg[][3]每个子数组仅占3字节,刚好存满$、s、数字三个字符,没有预留空终止符的存储空间,printf读取时会持续向后访问相邻的数组元素内存,直到碰到随机的\0才停止,因此出现所有寄存器名拼接输出的问题。 - 循环计数错误:
sizeof(reg)返回的是整个二维数组的总字节数(7个元素×3字节=21字节),而非数组的元素总个数,循环次数远大于实际元素数,会触发非法内存访问。
解决方案
方案1:修改原有二维数组适配字符串规则
如果要保留二维数组的存储结构,有两种修改方式:
- 预留空终止符存储空间
// 每个子数组长度改为4,最后1字节自动存储字符串的空终止符 char reg[][4] = { "$s0", "$s1", "$s2", "$s3", "$s4", "$s5", "$s6" }; int main(void){ // 正确计算数组元素个数:总字节数 / 单个元素的字节数 int reg_cnt = sizeof(reg) / sizeof(reg[0]); for(int i = 0; i < reg_cnt; i++) { printf("%s\n", reg[i]); } return 0; }
- 固定输出长度,不依赖空终止符
如果不想改动数组的长度定义,可以使用%.*s格式符指定单次输出的字符长度:
char reg[][3] = { {'$', 's', '0'}, {'$', 's', '1'}, {'$', 's', '2'}, {'$', 's', '3'}, {'$', 's', '4'}, {'$', 's', '5'}, {'$', 's', '6'} }; int main(void){ int reg_cnt = sizeof(reg) / sizeof(reg[0]); for(int i = 0; i < reg_cnt; i++) { // 指定每次输出3个字符,不需要读取空终止符 printf("%.*s\n", 3, reg[i]); } return 0; }
方案2:使用字符指针数组(即你提到的char类型双指针数组)实现
完全可以用字符指针数组实现,这种方案更灵活,不需要手动计算字符串长度,字符串常量会自动携带空终止符:
// 每个元素是指向字符串常量的指针,自动带\0终止符 char *reg[] = { "$s0", "$s1", "$s2", "$s3", "$s4", "$s5", "$s6" }; int main(void){ int reg_cnt = sizeof(reg) / sizeof(reg[0]); for(int i = 0; i < reg_cnt; i++) { printf("%s\n", reg[i]); } return 0; }
内容的提问来源于stack exchange,提问作者nonkooshy
相关产品推荐
相关产品推荐

