鱼C论坛

 找回密码
 立即注册
查看: 1581|回复: 8

c语言结构体指针赋值,未赋值却有了正确的指向,我已经绕了

[复制链接]
发表于 2015-3-18 21:02:55 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
struct student    //构建结构体
{   char name[20];
    struct student * pnext;
};
void buildstu(struct student*p,int n);
void print(struct student*p,int n);
int main()        //主函数
{
            int n;
            puts("please input how many students:\nnum = ");
            scanf("%d",&n);    //链表的个数
            struct student * phead=(struct student *)malloc(sizeof(struct student));
            buildstu(phead,n);    //构建链表
            print(phead,n);    //输出

            return 0;
}
void buildstu(struct student*p,int n)    //构建链表函数
{
        struct student* ptail=p;    //就是此处不明白,p内的指针,一直也没赋值,但是居然指向的是首节点
            for(int i=0;i<n;i++)    //下面只对ptail赋值,p应该一直就是个随机值才对
            {
                        struct student *pnew=(struct student *)malloc(sizeof(struct student));
                        if(pnew==NULL)
                                    {        puts("Allocation failure!!!");        exit(-1);        }
                        ptail->pnext=pnew;
                        scanf("%s",pnew->name);
                        ptail=pnew;
            }
}
void print(struct student*p,int n)    //输出函数
{
            struct student* ptail=p->pnext;
            for(int i=0;i<n;i++)
            {
                        printf("%s\n",ptail->name);
                        ptail=(ptail->pnext);
            }
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-3-18 21:46:39 | 显示全部楼层
本帖最后由 lightninng 于 2015-3-18 21:47 编辑

楼主如果画个图应该就能明白
主函数运行到struct student * phead=(struct student *)malloc(sizeof(struct student));这一句时
创建了一个链表的结点(我们给它起个名字叫做temp结点),此时phead指针指向temp结点
buildstu(phead,n);这条语句时,phead这个指针传入函数中,赋值给函数中的p,即p也指向temp结点,
进入函数
struct student* ptail=p;#ptail指向temp结点
然后进入循环体
struct student *pnew=(struct student *)malloc(sizeof(struct student));
创建新的结点,它的地址由pnew来保存,或者说pnew指向新创建的结点
ptail->pnext=pnew;
把新创建的结点挂在ptail指向的结点的后面,第一次循环时,由于ptail指向的是temp结点,所以它挂在了temp结点的后面,注意此时函数体中的p以及主函数中的phead指针仍指向temp结点没有变过
scanf("%s",pnew->name);
ptail=pnew;
给新的结点赋值,并把ptail指针指向新的结点,此时注意到ptail指针实际是指向了链表的尾部。这就是“尾插法”创建链表,另外说一点,这个尾插法的函数有一个小问题,当链表构建完成之后,要将尾结点的指针设为NULL,否则它将指向一个随即的位置
也就是在buildstu的最后一行加上
ptail->pnext=NULL;
PS:指针变量其实是一个地址,*操作符就是找到指针变量所存地址处的值,知道这个,再一步步的去还原程序每一步所作的事情,这个问题基本就明白了,明白了这个,参数的传入问题按照同样的方法也很好理解





想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-3-18 21:59:20 | 显示全部楼层
lightninng 发表于 2015-3-18 21:46
楼主如果画个图应该就能明白
主函数运行到struct student * phead=(struct student *)malloc(sizeof(struc ...

很谢谢你的讲解,虽然还是很绕。多少也明白了些。指针实在有些麻烦。
我开始想的是ptail对指向的值赋值了。p也是指向同一个目标。
后来在想,ptail整个指针被赋值了,p不是也被影响了。

现在想来;
应该是ptail语句中对ptail的对象进行赋值,也就是对phead的对象赋值。
后来ptail=pnew;语句是让ptail指针指向pnew。所以对phead无影响。
我说的对吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-3-18 22:12:11 | 显示全部楼层
本帖最后由 lightninng 于 2015-3-18 22:13 编辑
秀丽江山 发表于 2015-3-18 21:59
很谢谢你的讲解,虽然还是很绕。多少也明白了些。指针实在有些麻烦。
我开始想的是ptail对指向的值赋值 ...
你说的对,改变ptail的指向,并不影响phead的指向
所谓对指针赋值,其实就是改变指针的指向
->这个符号其实和*有异曲同工之妙,好久没碰c了,没记错的话结构体对成员的引用 是用.的,也就是说以下两种表达方式相同
p->pnext;和(*p).pnext
也就是说ptail->pnext=pnew;和(*ptail).pnext=pnew;
由于ptail和函数体内的p以及主函数中的phead都指向的是已经创建好的头结点,所以以上语句其实是在对头结点进行操作
这里涉及到一个问题,我们传入的是一个指向头节点的指针,假如我们传入的是头结点本身会怎么样,如果你不明白我的意思,看一下下面这个贴子的我举的形参和实参的例子http://bbs.fishc.com/thread-58889-1-1.html
然后再好好理解一下指针变量的内容其实是一个地址,而*操作之后便得到了指针存着的地址所指向位置的内容
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-3-18 22:19:15 | 显示全部楼层
pHead的指向一直都是不变的,就是在主程序中分配的那个结构体的内存空间
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-3-18 22:21:46 | 显示全部楼层
lightninng 发表于 2015-3-18 22:12
你说的对,改变ptail的指向,并不影响phead的指向
所谓对指针赋值,其实就是改变指针的指向
->这个符号其 ...

看不懂那是什么东西。
我刚学c语言20天来着
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-3-18 22:27:44 | 显示全部楼层
Victory_6226 发表于 2015-3-18 22:19
pHead的指向一直都是不变的,就是在主程序中分配的那个结构体的内存空间

恩恩。只是这些东西多了就有些绕了。当时学的时候感觉都理解了,但是用的时候感觉不够用。
定义一个指针不对指针赋值,他就一直指向一个目标。即使这个目标的值变了。指针始终不离不弃。
我了个去。哎~~~~
链表今天下午的时候接触,感觉有些高深。就自己打了这个。。。开始有点点错误。参考了答案后那一点却不怎么理解。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-3-18 22:36:23 | 显示全部楼层
秀丽江山 发表于 2015-3-18 22:27
恩恩。只是这些东西多了就有些绕了。当时学的时候感觉都理解了,但是用的时候感觉不够用。
定义一个指针 ...

额。。不好意思。c语言基础不劳的话。指针确实迷糊。这个问题主要是指针的问题。带着指针就是地址的想法把指针那章好好看看就都懂了
另外如果你是在学习数据结构,建议看严蔚敏版老师的《数据结构(C语言版)》,把代码敲一敲,很有帮助
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-3-18 22:51:56 | 显示全部楼层
lightninng 发表于 2015-3-18 22:36
额。。不好意思。c语言基础不劳的话。指针确实迷糊。这个问题主要是指针的问题。带着指针就是地址的想法 ...

好的,谢谢你
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-25 19:21

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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