
#include<stdioh>//这两句表示预编译包含两个标准函数头文件,
#include<stdlibh>//标准函数头文件里面定义有一些标准函数的方法如scanf等
#define LEN sizeof(struct Student)//这一句是把“sizeof(struct Student)”定义为“LEN”
//预编译时程序中所有的“LEN”将会被替换成“sizeof(struct Student)”
//sizeof(struct Student)作用是计算Student结构体占用的内存空间
struct Student//建立一个结构体,命名为"Student"
{
int num;//结构体中定义一个int(整型) 成员变量,命名为"num"
float score; //结构体中定义一个float(浮点型) 成员变量,命名为"score"
struct Student next;//结构体中定义一个 “Student ”(Student结构体的指针)
//成员变量,命名为"next"。很多人会问这是在定义“Student”的过程中,
//怎么就能使用“Student ”呢?实际上在大括号之前的“struct Student”时,
//“Student”就已经声明,编译器就知道有“Student”这个结构体了,
//而我们定义的是它的指针,不必关心结构体里有什么,自然能使用了
};
int n;//定义一个int(整型) 变量,命名为“n”
struct Student creat(void)//定义一个函数,命名为“creat”。该函数没有参数输入
{//("void"代表没参数),返回值类型为“Student ”,即一个指向Student结构体的指针
struct Student head;//定义一个"Student "变量,命名为“head”
struct Studnet p1,p2;//定义两个"Student "变量,分别命名为“p1”和“p2”
n=0;//赋值0到n
p1=p2=(struct Studet ) malloc(LEN);//p1和p2同时指向一块新分配的内存空间
//其中LEN上面已经介绍,预编译替换后,作用是计算Student结构体的大小(字节为单位)
//malloc(LEN)的作用是分配LEN字节的一块空间,并返回分配的内存首地址(void类型)
//(struct Studet ) 的作用是类型转换,将void转换为Studet
//这里我们注意到,指针实际上就是内存地址,指针的赋值实际上就是地址值的复制
scanf(“”,&p1->num,&p1->score);//(这句有问题)格式化输入两个数值,分别赋值到
//num和score成员变量中,其中->的作用是通过指针取成员变量,
//比如p1->num就是取p1指向的结构体的成员变量num;
//&的作用是取变量地址,比如&p1->num就是取变量“p1->num”的地址
head=NULL; //赋值NULL到指针head,NULL是一个宏,在包含的头文件有定义,
//代表空指针
while(p1->num!=0)//开始一个循环,每循环到这里都判断一下,如果p1->num为0则退出循环。
//如果还没进入循环就有p1->num为0则不循环,显然是否循环跟刚才的
//scanf格式化输入有关,由此知道是否循环决定于scanf输入的第一个数
{n=n+1;//n变量加1后再复制给n变量,相当于n++;,即自增1,可知n代表循环次数
if(n==1) head=p1;//当n为1的时候将p1指针赋值给head,注意到p1指向一个新建的Student
//结构体,n为1代表第一次循环而函数返回变量为head,可知head为链表的头结点
else p2->next=p1;//n为其他循环次数时将p1赋值给p2结构体中的next
p2=p1;//p1赋值给p2
p1=(struct Student ) malloc(LEN);//每循环一次就通过分配内存空间给p1来新建结构体(节点),
//可见,在这个循环中,p1指向新建的结构体,p2指向前一个结构体
//循环不断把新建的Student结构体的指针 赋值给前一个结构体中的成员变量next,
//以此来形成链表
scanf(“%d,%f”,&p1->num,&p1->score);//输入并赋值到p1指向结构体的两个成员变量,
//当第一个数值为0时将退出循环,结束链表节点的创建
}
p2->next=NULL;//循环结束最后一个结构体中的next设置为空指针,表示链表已终结
return(head);//返回一个链表头
}
//这个例子展示的是一个简单链表的制作。链表怎么使用?假如我们有一个链表头,
//指向一个结构体,那么我们就能通过使用“->”来访问该结构体(或者称为头结点)的成员变量,
//如果成员变量中还有指向另一个结构体的指针,我们就又能通过使用“->”来访问那个结构体的
//成员变量,依次类推,就能访问链表的所有节点
可以在结构体中添加指针类成员变量,并在成员函数中实现动态数组的分配。
以下以一个仅实现整型动态数组,不包含其它功能的类为例做说明。
class array //类名
{
public:
int v; //动态数组首地址。
int length; //动态数组长度。
array(int len)
{
if(len <= 0)//初始化长度非法。
{
length = 0;
v = NULL;
}
else
{
length = len;
v = new int[length];//内存分配。
}
}
~array()
{
delete [] v;//析构中释放内存。
}
};
1、可以在结构体中添加指针类成员变量,并在成员函数中实现动态数组的分配。
2、以下以一个仅实现整型动态数组,不包含其它功能的类为例做说明。
class array //类名{
public:
int v; //动态数组首地址。
int length; //动态数组长度。
array(int len)
{
if(len <= 0)//初始化长度非法。
{
length = 0;
v = NULL;
}
else
{
length = len;
v = new int[length];//内存分配。
}
}
~array()
{
delete [] v;//析构中释放内存。
}
};
以上就是关于关于C语言动态链表的问题,请高手详细解释下面程序的每一句,以及作用!全部的内容,包括:关于C语言动态链表的问题,请高手详细解释下面程序的每一句,以及作用!、c++如何声明动态的结构体数组、C语言动态分配内存给结构体数组等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)