如何在未知数组大小的情况下将数组末尾的指针移动到起始位置
解决方案
你之前尝试递减指针直到遇到起始位置空指针的方案不可行,核心原因有两个:
- C语言原生数组不会在头部自带空哨兵标记,指针递减越过数组起始边界后会访问未定义内存,自然会读取到随机值,没有合法的终止判断条件
- 你提供的示例代码存在笔误:
char ** point = &word[9];中的word应为数组名words,且原数组9个元素的合法下标为0~8,&words[9]属于合法的尾后指针,但不可解引用。
方案1:调整递归函数参数携带起始边界(最推荐)
不需要修改原数组结构,也没有额外遍历开销,只需要在递归入参中固定传递数组起始地址即可,无论递归到多少层,都可以直接拿到数组起始位置,不需要反向扫描指针。
示例代码如下:
// 递归函数定义:start固定为数组起始地址,curr为当前递归层的指针 void traverse(char **start, char **curr) { // 递归终止条件示例:当前指针走到数组尾后位置就返回 if (curr - start == 9) { // 直接通过start访问数组起始位置,无需任何扫描操作 printf("数组首元素:%s\n", *start); return; } // 递归逻辑:当前指针自增进入下一层 traverse(start, curr + 1); } // 调用示例 int main() { char *words[] = {"The", "Quick", "Brown", "Fox", "Jumped", "Over", "The", "Lazy", "Dog"}; // 初始调用时传入数组起始地址作为start和初始curr traverse(words, words); return 0; }
方案2:给数组新增末尾哨兵标记
如果不能修改递归函数的参数定义,可以在数组末尾增加NULL作为哨兵标记,正向遍历到哨兵位置即可得到数组总长度,从当前位置回退对应长度就能得到起始位置。
示例代码如下:
// 数组末尾新增NULL哨兵,总长度变为10 char *words[] = {"The", "Quick", "Brown", "Fox", "Jumped", "Over", "The", "Lazy", "Dog", NULL}; // 尾后指针现在指向哨兵位置 char **point = &words[9]; // 从任意指针位置获取数组起始位置的实现 char** get_start(char **curr) { // 正向走到哨兵位置统计总长度 char **p = curr; while (*p != NULL) p++; int total_len = p - curr; // 回退对应长度得到起始位置 return curr - total_len; }
注意:C语言原生数组本身不存储任何边界元信息,如果你仅持有一个指向数组内部的指针,没有任何额外的边界参数或者哨兵标记,不可能通过合法操作得到数组的起始位置,任何越界扫描的行为都属于未定义行为,可能出现随机值、程序崩溃等问题。
内容的提问来源于stack exchange,提问作者undertaker
相关产品推荐
相关产品推荐

