读书人

【新手求教】建立单向动态链表程序的若

发布时间: 2013-03-14 10:33:15 作者: rapoo

【新手求教】建立单向动态链表程序的若干问题,请各位大神详解
本帖最后由 anjsy6 于 2013-03-07 17:07:00 编辑 学到结构体的链表这块了,但是创建单向动态链表的代码让我有点头晕,请各位大侠指教:
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>

#define LEN sizeof(struct student)

struct student *creat(); 问题1.这句话是什么意思?是声明一个类型为struct
student的creat函数吗?那为什么creat前面要加*?
而且这个函数为什么也没有参数?
void print(struct student *head);

struct student
{
int num;
float score;
struct student *next;
};

int n; //全局变量,用来记录存放了多少数据。

void main()
{
struct student *stu; 分析1:这里是定义一个结构体指针变量stu

stu = creat(); 问题2:这里就是将结构体指针变量stu指向creat函数返回
值的首地址?
print( stu );

printf("\n\n");
system("pause");
}

struct student *creat() 问题3:重点:为啥creat函数的定义前面还要加*
{
struct student *head;
struct student *p1, *p2;

p1 = p2 = (struct student *)malloc(LEN); 分析2:这句话的意思是利用malloc函数给
struct student这个结构体类型分配动态存储
空间,然后malloc函数返回的是这个分配的动
态空间的首地址,这个首地址再被(struct


student *)函数强制转换为指针,然后将这个
指针所指的地址赋给p1和p2
printf("Please enter the num :"); 分析3+问题4:这四行算是已经创建的第一个节点然后给赋值
吗?如果是,那为何head不直接指向p1->next?还要
在后面赋初值等于NULL?如果不是,那输入这些数据
有什么用?
scanf("%d", &p1->num);
printf("Please enter the score :");
scanf("%f", &p1->score);

head = NULL;
n = 0;

while( 0 != p1->num )
{
n++;
if( 1 == n )
{
head = p1;
}
else
{
p2->next = p1;
}

p2 = p1;

p1 = (struct student *)malloc(LEN);

printf("\nPlease enter the num :");
scanf("%d", &p1->num);


printf("Please enter the score :");
scanf("%f", &p1->score);
}

p2->next = NULL;

return head;
}

void print(struct student *head)
{
struct student *p;
printf("\nThere are %d records!\n\n", n);

p = head;
if( NULL != head ) 问题5:这里的head!=0意思是head->num不为0吧?那
可否将括号内的内容改为:head->num!=0
{
do
{
printf("学号为 %d 的成绩是: %f\n", p->num, p->score);
p = p->next;
}while( NULL != p );
}
}

麻烦各位前辈看看,我自己分析的那几条是否正确,还有顺便解答一下我的以上几个问题,谢谢了

[解决办法]
LZ的基本知识欠缺啊,连函数的声明都搞不清啊。
Q1: 声明了一个返回struct student 指针 的无参 函数create
Q2:是
Q3:同Q1.
Q4: 这代码水平有限,head = NULL 是考虑到了num = 0时的退出,但是也num=0时 也内存泄漏了。
Q5:跟Q4一起理解。
[解决办法]
1.*不是指给函数的,struct student*是函数的返回类型,函数不一定非要传入参数
2.指向函数的返回地址
3.见 1
4.head是链表头,为NULL表示链表中没有元素
5.head!=NULL 是一种判断指针是否为空的写法 head都没有自然没有创建链表,head->num这个值当然是不存在的,无法访问。

PS,楼主应该认真学一下函数,指针……的基础知识
[解决办法]
问题1: 申明函数,此函数返回值为结构体指针, 类似于 int main() ,main()返回值是int类型是一样的.
问题2: stu接收creat()函数的返回值.
问题3: 与问题1一样的.
问题4: head顾名思义存放的是链表的第一组数据.
问题5: 判断链表中的第一组是否为空,如果为空,那后边可想而知肯定没有数据.
[解决办法]
楼主刚刚开始接触程序吧?有前途!这精神值得鼓励啊


#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>

#define LEN sizeof(struct student)

struct student *creat(); // 问题1.这句话是什么意思?是声明一个类型为structstudent的creat函数吗?那为什么creat前面要加*?而且这个函数为什么也没有参数?
// 答:这是声明一个函数,函数名creat,参数void,返回值struct student*(现在这个返回值你看起来可能觉得怪怪的,看习惯了也就明白了)
void print(struct student *head);

struct student {
int num;
float score;
struct student *next;
};

int n; //全局变量,用来记录存放了多少数据。

void main() {
struct student *stu; // 分析1:这里是定义一个结构体指针变量stu



stu = creat(); // 问题2:这里就是将结构体指针变量stu指向creat函数返回值的首地址?
// 答:这表示调用creat函数,然后creat函数返回了一个struct student*类型的值,并把这个值赋给stu这个局部变量
print(stu);

printf("\n\n");
system("pause");
}

struct student *creat() // 问题3:重点:为啥creat函数的定义前面还要加*
// 答:同问题1. *不是跟creat 一起的,*是与struct student一起的,合起来表示一个struct student的指针类型
{
struct student *head;
struct student *p1, *p2;

p1 = p2 = (struct student *) malloc(LEN); // 分析2:这句话的意思是利用malloc函数给struct student这个结构体类型分配动态存储空间,然后malloc函数返回的是这个分配的动态空间的首地址,这个首地址再被(struct student *)函数强制转换为指针,然后将这个指针所指的地址赋给p1和p2
// 分析的对了一般,这个首地址再被(struct student *)函数强制转换为指针==>你好像不大理解地址与指针的关系,指针里面存放的就是地址,malloc返回的是一个void *类型的地址,所以要进行强制转换,把void*==>struct student*
printf("Please enter the num :"); // 分析3+问题4:这四行算是已经创建的第一个节点然后给赋值吗?如果是,那为何head不直接指向p1->next?还要在后面赋初值等于NULL?如果不是,那输入这些数据有什么用?
// struct student *head; 这是声明,不是定义,head = NULL;这是定义,之所以head=NULL,这是为了防止野指针出现,是一个好习惯,否则在以后的编程中可能会出现莫名其妙的问题
scanf("%d", &p1->num);
printf("Please enter the score :");
scanf("%f", &p1->score);

head = NULL;
n = 0;

while (0 != p1->num) {
n++;
if (1 == n) {
head = p1;
} else {
p2->next = p1;
}

p2 = p1;

p1 = (struct student *) malloc(LEN);

printf("\nPlease enter the num :");
scanf("%d", &p1->num);
printf("Please enter the score :");
scanf("%f", &p1->score);
}

p2->next = NULL;

return head;
}

void print(struct student *head) {
struct student *p;
printf("\nThere are %d records!\n\n", n);

p = head;
if (NULL != head) // 问题5:这里的head!=0意思是head->num不为0吧?那可否将括号内的内容改为:head->num!=0
// 答:这个你根据具体的逻辑去判断就好了,写什么我倒觉得无所谓
{
do {
printf("学号为 %d 的成绩是: %f\n", p->num, p->score);
p = p->next;
} while (NULL != p);
}
}


[解决办法]
引用:
感谢楼上3位~1、2、3、5问题都搞清了~就是第四个~可能我没表达清楚问题,所以还没理解~

我的意思是这段代码不是一共有两组
printf("Please enter the num :");
scanf("%d", &p1->num);
printf("Please enter the score :");
scanf("%f", &amp……


在使用前给局部指针变量赋值NULL,这是个好习惯,是防止野指针的出现,你当然也可以直接按照你的理解去使用它。
但是要记住,习惯这东西不容投机取巧,有时候宁可多写点代码,也不要把习惯破坏了
[解决办法]
如果照你那样的话,head就成为最后一个接点了
本来是h->1->2->3
你那样的话就成了1->2->3->h
[解决办法]
引用:
引用:引用:感谢楼上3位~1、2、3、5问题都搞清了~就是第四个~可能我没表达清楚问题,所以还没理解~

我的意思是这段代码不是一共有两组
printf("Please enter the num :");
scanf("%d", &p1->num);


printf("……



这个没什么可回答的,你也可以在那四行里把p1换成head,怎样理解起来方便就怎么做,好代码是给人看的,你觉得怎么写能逻辑表达的更清楚就怎么写。

至于head为什么要先赋值为NULL,这个就是我说的习惯问题了,虽然在这里如果你不赋值NULL可能也不会出错,但是下次不同的情况里面你忘记了head=NULL,那么可能造成的野指针问题就不是那么容易发现了

读书人网 >C语言

热点推荐