首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

【新手求教】建立单向动态链表程序的若干有关问题,请各位大神详解

2013-03-14 
【新手求教】建立单向动态链表程序的若干问题,请各位大神详解本帖最后由 anjsy6 于 2013-03-07 17:07:00 编

【新手求教】建立单向动态链表程序的若干问题,请各位大神详解
本帖最后由 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", &amp;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", &amp;amp;amp;p1->num);


 printf("……



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

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

热点排行