鱼C论坛

 找回密码
 立即注册
查看: 5926|回复: 5

结构体指针从经一个函数调用改变其地址后回到main其地址又变成原来的值

[复制链接]
发表于 2013-9-1 20:45:20 | 显示全部楼层 |阅读模式
1鱼币
  在学到链表删除的那一课,写小甲鱼老师留的课后作业遇到的问题(当要删除第一个节点的时候(n=1))。源代码如下:
//这是main.c文件中的

#include <stdio.h>

struct student
{
        int num;
        char *name;
        struct student *next;
}
;

void delete_node(struct student *, int n);        //删除链表第n个节点
void print(struct student *);                //打印链表

int
main()
{
        struct student stu1 = {1, "Jade"}, stu2 = {2, "Mioroa"}, stu3 = {3, "Judy"}, *head;
        int n;
        int error;
       
        head = &stu1;
        stu1.next = &stu2;
        stu2.next = &stu3;
        stu3.next = NULL;

        printf("input which node you want to delete: ");
        error = scanf("%d", &n);
       
        if (error != 1)                //检查输入合法性
        {       
                printf("error!\n");
                return 1;
        }
        if (n > 3 || n < 0)                //检查输入范围
        {
                printf("no such node!\n");
                return 1;
        }

        delete_node(head, n);        //执行删除操作
        printf("\n\n");
        print(head);                        //打印链表

        return 0;
}



//这是delete_node.c 中的
#include <stdio.h>
extern struct student
{
        int num;
        char *name;
        struct student *next;
}
;

void delete_node(struct student *head, int n)
{
        struct student *p1, *p2;
       
        p1 = head;

        while (p1->num != n)        //查找要删除节点的位置
        {
                p2 = p1;
                p1 = p1->next;
        }
        if ( n == 1 )                        //头节点则直接删除
                head = p1->next;
        else
                p2->next = p1->next;        //删除一个节点
}


//这是print.c 中的
#include <stdio.h>
extern struct student
{
        int num;
        char *name;
        struct student *next;
}
;

void print(struct student *head)
{
        while (head)
        {
                printf("number = %d, name = %s\n", head->num, head->name);
                head = head->next;
        }
}


当我输入使n=1时,结果还是输出三个节点的参数。经调试发现n=1时,在delete_node()函数内head的值确实发生了改变,但是当回到main()函数的时候,head的值又恢复了。。。这不传的是地址么,照说应该不会发生改变的说。。。求大神解释~

dele*()中

dele*()中

回到main()

回到main()



最佳答案

查看完整内容

最好写带头结点的链表。。。 这个是带头结点的链表,在你的基础上修改的,不知道对不对。。。 PS:按你的程序,删除头结点的话,你传的就不是地址了,是按值传递,只不过传递的值正好是个地址而已。。。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-9-1 20:45:21 | 显示全部楼层
  1. #include <stdio.h>

  2. struct student
  3. {
  4.         int num;
  5.         char *name;
  6.         struct student *next;
  7. }
  8. ;

  9. void delete_node(struct student *, int n);        //删除链表第n个节点
  10. void print(struct student *);                //打印链表

  11. int
  12. main()
  13. {
  14.         struct student stu1 = {1, "Jade"}, stu2 = {2, "Mioroa"}, stu3 = {3, "Judy"}, *head=NULL;
  15.         int n;
  16.         int error;
  17.        
  18.         head = (struct student *)malloc(sizeof(struct student));
  19.         head->next = &stu1;
  20.         stu1.next = &stu2;
  21.         stu2.next = &stu3;
  22.         stu3.next = NULL;
  23.        
  24.         printf("input which node you want to delete: ");
  25.         error = scanf("%d", &n);
  26.        
  27.         if (error != 1)                //检查输入合法性
  28.         {      
  29.                 printf("error!\n");
  30.                 return 1;
  31.         }
  32.         if (n > 3 || n < 0)                //检查输入范围
  33.         {
  34.                 printf("no such node!\n");
  35.                 return 1;
  36.         }
  37.        
  38.         print(head);
  39.         delete_node(head, n);        //执行删除操作
  40.         printf("\n\n");
  41.         print(head);                        //打印链表
  42.        
  43.         return 0;
  44. }



  45. void delete_node(struct student*head, int n)
  46. {
  47.         struct student *p1, *p2;
  48.        
  49.         p1 = head;
  50.        
  51.         while (p1->num != n)        //查找要删除节点的位置
  52.         {
  53.                 p2 = p1;
  54.                 p1 = p1->next;
  55.         }
  56.         if ( n == 1 )                        //头节点则直接删除
  57.                 head->next = p1->next;
  58.         else
  59.                 p2->next = p1->next;        //删除一个节点
  60. }


  61. void print(struct student *head)
  62. {
  63.         struct student *p;
  64.         p=head->next;
  65.         while (p)
  66.         {
  67.                 printf("number = %d, name = %s\n", p->num, p->name);
  68.                 p=p->next;
  69.         }
  70. }
复制代码
最好写带头结点的链表。。。
这个是带头结点的链表,在你的基础上修改的,不知道对不对。。。
PS:按你的程序,删除头结点的话,你传的就不是地址了,是按值传递,只不过传递的值正好是个地址而已。。。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-9-1 21:51:09 | 显示全部楼层
你的链表程序怎么没分配动态内存啊,当然可以说你这不是一个链表程序!
我觉得你应该去看下郝斌的C语言链表的构造
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-9-2 10:18:35 | 显示全部楼层
本帖最后由 Miorioa 于 2013-9-2 10:26 编辑

知道原因了 就同你说的一样 函数传递的还是值,只不过是地址的值。设置头结点(我之前的代码用的是头指针)的话就可以利用head->next = p1->next从而达到删除第一个节点的目的(当然head的值,即储存的地址在返回main()后都不会改变,除非把head设为全局变量,这样可以不用设置头结点了)。
PS:还是我对于函数的参数传递没有彻底弄懂才导致这个问题。。。谢谢了哈~~~这是我利用全局变量的头指针来修改这个程序的开头的部分代码:

#include <stdio.h>

struct student
{
        int num;
        char *name;
        struct student *next;
}
;

//全局变量头指针head
struct student *head;

void delete_node(int n);        //删除链表第n个节点
void print();                //打印链表

int
main()
.......................
.......................

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-9-2 10:22:03 | 显示全部楼层
Miorioa 发表于 2013-9-2 10:18
知道原因了 就同你说的一样 函数传递的还是值,只不过是地址。设置头结点(我之前的代码用的是头指针)的 ...

不用谢,我也是蒙的。。。
PS:你理解的比我透彻。。。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-9-2 19:50:16 | 显示全部楼层
{:1_1:}不错
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-11-6 01:24

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表