二维数组自定义函数读取异常:指针地址偏移问题排查
问题分析与修复方案
嘿,我一眼就看出问题出在哪了——你在frame()函数里对二维数组的指针访问逻辑完全搞错了,才导致地址偏移不符合预期,出现了重复的2、3、4这类输出。
核心错误原因
先看你的二维数组定义:
char spot[][3]={"123","456","789"};
这是一个3行3列的二维字符数组,内存里是连续存储的:'1','2','3','4','5','6','7','8','9'(每行3个字符)。
你调用frame(*spot);时,*spot等价于spot[0],也就是第一行数组的首地址,类型是char*,指向spot[0][0](也就是'1'的地址)。
但在frame()里,你用*(count+i)+j来访问元素,这完全搞错了二维数组的地址计算:
count是char*类型,count+i表示从首地址偏移i个char的位置,而不是偏移i行(每行3个char)。- 当
i=0时,*(count+0)是spot[0][0]('1'),加j后得到'1'、'2'、'3',这部分是对的。 - 当
i=1时,*(count+1)是spot[0][1]('2'),加j后得到'2'、'3'、'4'——这就是你看到的第二轮错误输出。 - 当
i=2时,*(count+2)是spot[0][2]('3'),加j后得到'3'、'4'、'5',对应第三轮的错误输出。
简单说:你没有考虑二维数组的行跨度(每行3个元素),指针一直在第一行内部偏移,根本没跳到下一行的开头。
修复方案
有两种简单的修复方式,选哪种都可以:
方案1:直接用二维数组类型作为参数(推荐,更直观)
修改frame()的函数声明和定义,指定二维数组的列数(C语言要求必须指定列数才能计算行跨度):
// 函数声明也要对应修改 void frame(char count[][3]){ int i,j; printf(" "); line(24); for (i = 0; i < 3; i++){ printf(" "); for (j = 0; j < 3; j++){ // 直接用二维数组的下标访问,清晰不易错 printf("| %c ", count[i][j]); } printf("|\n "); line(24); } }
然后调用的时候,直接传数组名spot即可:
frame(spot); // 不需要解引用*spot
方案2:手动计算行偏移(如果坚持用char*参数)
如果不想改参数类型,就手动计算每行的起始地址(每行3个元素,所以偏移量是i*3):
void frame(char *count){ int i,j; printf(" "); line(24); for (i = 0; i < 3; i++){ printf(" "); for (j = 0; j < 3; j++){ // 第i行第j列的地址 = 首地址 + i*每行元素数 + j printf("| %c ", *(count + i*3 + j)); } printf("|\n "); line(24); } }
调用方式不变:
frame(*spot); // 或者frame(&spot[0][0]); 效果一样
验证效果
修复后,frame()就能正确遍历二维数组的所有元素,输出你预期的1 2 3 4 5 6 7 8 9了。
内容的提问来源于stack exchange,提问作者Anish
相关产品推荐
相关产品推荐

