Hacker_DL 2023-01-09 01:40 采纳率: 16.7%
浏览 46
已结题

指针变量如何在函数参数中传递并带回

想请教一下大家,C++语法关于函数指针传参并带回值的问题,这里我一直糊涂。
问题来源
是我在做PAT的乙级1008题,链接如下:点击即可跳转

img

我的思路
通过循环单链表实现数据的存储。目的是避免当数据循环右移时,无需像顺序表一样逐个移动元素。
但是具体实现过程中我发现了问题。问题出在第16和84行(CreatList_fromTail的函数的声明和调用上)

CreatList_fromTail的函数的声明

img

CreatList_fromTail的函数的调用

img

现在问题是
代码的运行逻辑就插入数据这一步来说,经过断点调试都是_正确的_。但是,我发现主函数中定义的LNode类型的h和r却没有因CreatList_fromTail函数中的业务逻辑而发生改变,还是NULL类型的。详见下图:

img

这该如何是好?!

最后,我把我完整的代码放一下。恳请大家帮我看一下,这里应该怎么修改代码?

#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;
}
  • 写回答

1条回答 默认 最新

  • 於黾 2023-01-09 09:05
    关注

    改变形参的值永远不会改变实参的值
    我们抛开形参实参不谈,就两个变量
    int a=0;
    int b=a;
    b=1;
    你会发现b变成1并不会把a也变成1.
    换成指针也一样
    int c=0;
    int *a=&c;
    int *b=a;
    int d=1;
    b=&d;
    你会发现b指向d的地址了,但是a还是指向c,改变b的值并不会改变a的值。
    如果你想要改变b的指向时同时也改变a的指向,那你必须传递一个二级指针

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 1月12日
  • 创建了问题 1月9日

悬赏问题

  • ¥15 is not in the mmseg::model registry。报错,模型注册表找不到自定义模块。
  • ¥15 安装quartus II18.1时弹出此error,怎么解决?
  • ¥15 keil官网下载psn序列号在哪
  • ¥15 想用adb命令做一个通话软件,播放录音
  • ¥30 Pytorch深度学习服务器跑不通问题解决?
  • ¥15 部分客户订单定位有误的问题
  • ¥15 如何在maya程序中利用python编写领子和褶裥的模型的方法
  • ¥15 Bug traq 数据包 大概什么价
  • ¥15 在anaconda上pytorch和paddle paddle下载报错
  • ¥25 自动填写QQ腾讯文档收集表