如何使用紧凑指针表示法访问二维数组并遍历数组元素
紧凑表示法遍历二维字符数组方案说明
两种定义的内存差异
你给出的两种数组定义属于完全不同的内存布局,适用的遍历方式也不一样:
- 第一种
char *a[2]是指针数组:数组的每个元素是char*类型的指针,分别指向两个独立存储的字符串常量,字符串在内存中不是连续排布的 - 第二种
char a[2][10]是连续内存的二维数组:所有字符按行连续存放在同一块内存空间里,没有额外的指针开销,支持单指针紧凑遍历
你贴的第二份代码是连续二维数组的正确遍历实现,如果你需要处理的是第一种指针数组的场景,可以参考下面的说明。
对应场景的实现方案
连续二维数组的紧凑遍历(你给出的方案已验证可用)
int main(void) { char a[2][10] = { "databytes", "dataword" }; // char **p = a; 写法错误,二者类型不匹配,编译不通过 char *q = &a[0][0]; for(int i = 0; i < 2; i++) for(int j = 0; j < 10; j++) printf("%c\n", *q++); return 0; }
原理:二维数组的元素按行连续存储,指针q每次自增1就会指向下一个相邻的字符,不需要额外计算行偏移,访问效率很高。
注意:char**和二维数组名类型不兼容,直接赋值会触发编译错误
指针数组的遍历方案
由于指针数组指向的字符串是分散存储的,没法直接用单指针自增的紧凑方式遍历所有字符,只能先遍历外层的指针数组,再逐个遍历每个指针指向的字符串:
#include <stdio.h> int main(void) { char *a[2] = { "databytes", "dataword" }; char **q = a; // 遍历外层的2个指针元素 for(int i = 0; i < 2; i++) { char *cur_str = q[i]; // 遍历当前字符串的每个字符,直到遇到结束符'\0' while(*cur_str != '\0') { printf("%c\n", *cur_str++); } } return 0; }
如果要在指针数组场景下用紧凑遍历,需要你手动把所有字符串存放在同一块连续的内存空间里,再给指针数组的元素赋值对应偏移的地址,否则无法实现单指针连续访问。
内容的提问来源于stack exchange,提问作者embedded3d
相关产品推荐
相关产品推荐

