c语言结构体指针赋值,未赋值却有了正确的指向,我已经绕了
#include <stdio.h>#include <malloc.h>
#include <stdlib.h>
struct student //构建结构体
{ char name;
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);
}
}
本帖最后由 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:指针变量其实是一个地址,*操作符就是找到指针变量所存地址处的值,知道这个,再一步步的去还原程序每一步所作的事情,这个问题基本就明白了,明白了这个,参数的传入问题按照同样的方法也很好理解
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无影响。
我说的对吗? 本帖最后由 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
然后再好好理解一下指针变量的内容其实是一个地址,而*操作之后便得到了指针存着的地址所指向位置的内容
pHead的指向一直都是不变的,就是在主程序中分配的那个结构体的内存空间 lightninng 发表于 2015-3-18 22:12
你说的对,改变ptail的指向,并不影响phead的指向
所谓对指针赋值,其实就是改变指针的指向
->这个符号其 ...
看不懂那是什么东西。
我刚学c语言20天来着 Victory_6226 发表于 2015-3-18 22:19
pHead的指向一直都是不变的,就是在主程序中分配的那个结构体的内存空间
恩恩。只是这些东西多了就有些绕了。当时学的时候感觉都理解了,但是用的时候感觉不够用。
定义一个指针不对指针赋值,他就一直指向一个目标。即使这个目标的值变了。指针始终不离不弃。
我了个去。哎~~~~
链表今天下午的时候接触,感觉有些高深。就自己打了这个。。。开始有点点错误。参考了答案后那一点却不怎么理解。。 秀丽江山 发表于 2015-3-18 22:27
恩恩。只是这些东西多了就有些绕了。当时学的时候感觉都理解了,但是用的时候感觉不够用。
定义一个指针 ...
额。。不好意思。c语言基础不劳的话。指针确实迷糊。这个问题主要是指针的问题。带着指针就是地址的想法把指针那章好好看看就都懂了
另外如果你是在学习数据结构,建议看严蔚敏版老师的《数据结构(C语言版)》,把代码敲一敲,很有帮助 lightninng 发表于 2015-3-18 22:36
额。。不好意思。c语言基础不劳的话。指针确实迷糊。这个问题主要是指针的问题。带着指针就是地址的想法 ...
好的,谢谢你
页:
[1]