想请教一下大家,C++语法关于函数指针传参并带回值的问题,这里我一直糊涂。
问题来源:
是我在做PAT的乙级1008题,链接如下:点击即可跳转。
我的思路:
通过循环单链表实现数据的存储。目的是避免当数据循环右移时,无需像顺序表一样逐个移动元素。
但是具体实现过程中我发现了问题。问题出在第16和84行(CreatList_fromTail的函数的声明和调用上)
CreatList_fromTail的函数的声明
CreatList_fromTail的函数的调用
现在问题是:
代码的运行逻辑就插入数据这一步来说,经过断点调试都是_正确的_。但是,我发现主函数中定义的LNode类型的h和r却没有因CreatList_fromTail函数中的业务逻辑而发生改变,还是NULL类型的。详见下图:
这该如何是好?!
最后,我把我完整的代码放一下。恳请大家帮我看一下,这里应该怎么修改代码?
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
// FUNCTION: 定义链表结点结构
typedef struct LNode {
ElemType data;
struct LNode *next;
} LNode, *LinkList;
// FUNCTION: 尾插法新建链表(不带头结点)
void CreatList_fromTail(LinkList &L, LNode *head, LNode *rear, int len) {
// NOTE: 变量声明
// STEP: 声明一个结构体指针变量*s和*rear。前者用于存储程序临时申请的内存空间始址,后者用于存储链表表尾结点地址。
// ALERT: 此处有严重理解错误!在创建头结点之前,传入的指针L此时是结构类型的空指针。所以,此时用L赋值给*rear(即:“*rear = L”起不到尾指针的作用)。
// LNode *s, *rear = L;
LNode *s;
// STEP: 声明一个整型变量x,用于接收用户输入。
int x;
// NOTE: 尾插法,建立链表
for (int i = 0; i < len; ++i) {
// STEP: 从标准输入读取用户输入
scanf("%d", &x);
// STEP: 创建新节点
// HINT: 申请一个新空间给s,强制类型转换为LNode类型
s = (LNode *) malloc(sizeof(LNode));
// HINT: 新结点中的数据,初始化为读取到的值
s->data = x;
// HINT: 新结点的指针域,初始化为空
s->next = NULL;
// HINT: 对于链表的第一个结点需额外处理(即:初始化链表)
if (L == NULL) {
// 链表指针L指向s
L = s;
// 构建循环链表的形式
L->next = L;
// 初始化首、尾指针
head = L;
rear = L;
}
// STEP: 让新结点链接在表尾
// HINT: 让尾指针所指结点(尾结点)的指针域,指向s指针所指结点始址
rear->next = s;
// HINT: 因为构建的是循环单链表,所以当尾插法插入新结点后,需要将新结点的指针域指向重新指向头指针所指结点(即:指向头结点)。
s->next = head;
// STEP: 更新尾指针r的指向。即:让r与s同指向即可实现r指向新表尾
rear = s;
}
}
// REVIEW: 本程序的底层数据结构采用带头结点,带首、尾指针的循环单链表实现。问题的解决方案分为3大步骤:1. 建表;2. 对表按要求进行调整;3. 按照格式要求输出数据。其中,建表时链表通过尾插法,不断向数据集
int main() {
setbuf(stdout, NULL);
// NOTE: Variable declaration
// STEP: 定义链表头指针,是结构体指针类型
LinkList L = NULL;
// STEP: 定义临时变量len和offset。前者用于获取题目要求的表长,后者用于记录表需右移的偏移量
int len, offset;
// NOTE: Inputs
// STEP: 获取表长和偏移量
scanf("%d %d", &len, &offset);
// STEP: 根据表长生成循环单链表
LNode *h = NULL, *r = NULL;
CreatList_fromTail(L, h, r, len);
// NOTE: Process
// STEP: 对于循环单链表进行循环右移操作
// HINT: 实际上相等于将头指针向右移len - offset个结点
for (int i = 0; i < len - offset; ++i) {
h = h->next;
}
// NOTE: Outputs
LNode *s = h;
for (int i = 0; i < len; ++i, s = s->next) {
if (i != len-1) {
printf("%d ", s->data);
} else {
printf("%d", s->data);
}
}
// NOTE: Ending
return 0;
}