C语言---链表(包括学习过程中的思想活动)

写链表想法的由来:

  链表---重要的数据结构,工作了这么长时间,再也没有写过链表,可能是由于工作中没有使用的原因,也可能是我太懒了,还可能是因为玩游戏玩过头了吧!总之我知道有链表,但是链表是什么好想就天马行空了,所以决定写一下,哈哈,虽然我很菜,但是再菜我也要它跑起来,万一哪天要用那么一下子呢!好了废话不多说,来满足一下自己的小小的一个期望(它跑起来)。

特简单的:

  首先呢!先码一个特别简单的,主要是为了先了解一下嘛!然后在一点点深入嘛!毕竟这么长时间没有写过了,不是嘛?

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

struct node {
    int number;
    struct node *next;
};

typedef struct node Node;

int main(void)
{
    Node *a, *b, *c; 

    a = (Node *)malloc(sizeof(Node));
    b = (Node *)malloc(sizeof(Node));
    c = (Node *)malloc(sizeof(Node));   

    a->number = 10;
    b->number = 20;
    c->number = 30; 

    a->next = b;
    b->next = c;

    while (a) {
        printf("---->%d", a->number);

        a = a->next;
    }
    printf("\n");

    return 0;
}// 执行结果

  [[email protected] misc]# gcc link_list.c
  [[email protected] misc]# ./a.out
  ---->10---->20---->30

  链表从表面的意思上就是链状的表,就像一根线上系了很多一样的结,这些结就是我们定义的结构体,而链就是我们定义的结构体中的指针next。next中存放着下一个节点的地址,这样我们就把所有的节点串联了起来,就像我们上边执行的结果一样。其实就是指针将数据串联。

稍微有点复杂的:

  (我觉得上边码的那个并不算是真正意义上的链表,我们只是把三个结构体变量串联了起来)写一个稍微复杂点的链表:

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4
  5 struct node {
  6     char name[16];
  7     char number[16];
  8     // long long number;
  9     struct node *next;
 10 };
 11
 12 typedef struct node Node;
 13
 14 Node *createList(int num)
 15 {
 16     Node *head = NULL;
 17     Node *tmp = NULL;
 18     Node *node = NULL;
 19     int i = 0;
 20     // int count = 0;
 21     // long long tmpNum;
 22
 23     head = (Node *)malloc(sizeof(Node));
 24     if (!head) {
 25         printf("malloc Node(head) error!\n");
 26         goto err;
 27     }
 28
 29     head->next = NULL;
 30
 31     tmp = head;
 32
 33     for(i = 1; i <= num; i++) {
 34         printf("create [%d] node!\n", i);
 35         node = (Node *)malloc(sizeof(Node));
 36         if (!node) {
 37             printf("malloc Node(node) error!\n");
 38         }
 39
 40         printf("Please enter your name :\n");
 41         scanf("%s", &node->name);
 42         if (!node->name) {
 43             printf("enter the name error! Please enter again!\n");
 44             goto err;
 45         }
 46
 47         printf("Please enter yout number :\n");
 48         // scanf("%d", &node->number);
 49         scanf("%s", &node->number);
 50         if (strlen(node->number) != 11) {
 51             printf("enter the number error! Please enter again!\n");
 52             goto err;
 53         }
 54
 55         // tmpNum = node->number;
 56         // while(tmpNum) {
 57         //  tmpNum /= 10;
 58         //  count++;
 59         // }
 60
 61         // if (count != 10) {
 62         //  printf("enter the number error! Please enter again!\n");
 63         //  goto err;
 64         // }
 65
 66         tmp->next = node;
 67         tmp = node;
 68     }
 69     node->next = NULL;
 70     return head;
 71
 72 err:
 73     return NULL;
 74 }
 75
 76 void printList(Node *node)
 77 {
 78     Node *tmp = NULL;
 79
 80     tmp = node->next;
 81
 82     while(tmp) {
 83         printf("name : %s, number : %s\n", tmp->name, tmp->number);
 84         tmp = tmp->next;
 85     }
 86 }
 87
 88 void freeList(Node *node)
 89 {
 90     Node *tmp = NULL;
 91     int i = 1;
 92
 93     tmp  = node->next;
 94
 95     while(tmp) {
 96         free(tmp);
 97         printf("clean up [%d] node!\n", i);
 98         tmp = tmp->next;
 99         i++;
100     }
101     tmp = NULL;
102
103     free(node);
104     node = NULL;
105
106     printf("clear finish!\n");
107 }
108
109 int main(void)
110 {
111     Node *node = NULL;
112     int num;
113
114     printf("Please enter the number of nodes int the link_list :\n");
115     scanf("%d", &num);
116     node = createList(num);
117     printList(node);
118     freeList(node);
119
120     return 0;
121 }
// 执行结果

[[email protected] address_list]# ./a.out 
Please enter the number of nodes int the link_list :
2
create [1] node!
Please enter your name :
test
Please enter your number :
12345678901
create [2] node!
Please enter your name :
test2
Please enter your number :
12345678902
name : test, number : 12345678901
name : test2, number : 12345678902
clean up [1] node!
clean up [2] node!
clear finish!

  代码中有部分注掉的,那部分是因为数字长度的问题,我试了%ll,%l64d, %lld,%ld输出的结果都不是期望值,所以就改用了字符串,这个问题有时间我在查一下吧!

  逐句分析:

    首先我们定义了一个结构体Node,结构体成员有三个,用来存储一个人名和其对应的电话号码(11位),next指针用来指向下一个节点;

    在main函数中,先要输入一个数字,来确定我们的链表的长度,然后创建链表,将其存储的内容打印出来,最后释放各个节点。

      createList函数中:

      生成一个头节点,根据num确定需要生成节点的个数,并对其各个节点进行赋值。

      createList函数中我们定义了三个结构体变量,一个是头节点head,一个是节点node,还有一个临时结构体变量tmp。我们将头节点head赋值给中间变量tmp,然后分配一个新的节点node,将node赋值给中间变量tmp结构体成员变量中的next指针变量(也就是头节点head结构体成员变量中的next指针变量),这样头节点就和新分配的节点node串联起来了。其中有一句tmp = node,这句话表示将新生成的节点node赋值给了中间变量tmp,这样做是为了在下一次循环中中间变量tmp表示的是上一次分配的node节点,再次分配新的节点后和现在的中间变量tmp(也就是上一次分配的节点)串联。描述的有点乱,仔细想一下也不是那么乱。

      当循环结束后,将最后分配的节点node结构体成员中的next指针变量指向NULL。

      返回头节点head。

    printList函数中:

      刚开始是这样写的:

void printList(Node *node)
{
    while(node) {
        printf("name : %s, number : %s\n", node->name, node->number);
        node = node->next;
    }
}// 执行结果

[[email protected] address_list]# ./a.out
Please enter the number of nodes int the link_list :
2
create [1] node!
Please enter your name :
test
Please enter your number :
12345678901
create [2] node!
Please enter your name :
test2
Please enter your number :
12345678902
name : , number :
name : test, number : 12345678901
name : test2, number : 12345678902
clean up [1] node!
clean up [2] node!
clear finish!

    从执行结果中可以看出,我们链表长度是2,但是在打印的出来的结果中去出现三个,只是因为其中空的那个是头节点。

  freeList函数:

    由于使用了malloc函数动态分配就需要free函数掉,防止内存泄漏,其中有一句tmp  = NULL;这句是为了防止野指针,但是NULL也是一个地址,只不过这个地址是确定的(void *)0;但是这句话加到循环里就会出现问题,因为在free掉tmp后这个指针还是存在的,可能就是野指针吧(这里我不确定),但是这时的tmp确确实实是存在的,所以才有了下面的操作。而当我们将tmp制空后,它的地址也就不存在了,我们在进行后边的操作的时候就操作非法地址,就会出现段错误。

    还需将头节点free掉。

原文地址:https://www.cnblogs.com/coolYuan/p/9261364.html

时间: 2024-10-08 19:52:35

C语言---链表(包括学习过程中的思想活动)的相关文章

学习过程中找到的一些好文章和我的一些想法记录

C# 中 点击button按钮时 那个焦点虚线框怎么去掉? 12楼亮了. 拖动无边框Form窗体 网站模板(Site Template)sitetemplate 参数代码 C#各种结束进程的方法详细介绍 [测试建议]测试tooltip的时候要多在内容中加一些标点单引号双引号之类的特殊符号,后面接上文字. GDI+发生generic错误,原因在于对图片存储的路径权限不够. 利用SmtpClient发送邮件 [翻译]表达式树基础 C# 参考:反射 -- 学习笔记整理,概念与应用 创建Windows服

C语言链表各类操作详解

链表概述 链表是一种常见的重要的数据结构.它是动态地进行存储分配的一种结构.它可以根据需要开辟内存单元.链表有一个“头指针”变量,以head表示,它存放一个地址.该地址指向一个元素.链表中每一个元素称为“结点”,每个结点都应包括两个部分:一为用户需要用的实际数据,二为下一个结点的地址.因此,head指向第一个元素:第一个元素又指向第二个元素:……,直到最后一个元素,该元素不再指向其它元素,它称为“表尾”,它的地址部分放一个“NULL”(表示“空地址”),链表到此结束.        链表的各类操

玩转C语言链表

链表概述 链表是一种常见的重要的数据结构.它是动态地进行存储分配的一种结构.它可以根据需要开辟内存单元.链表有一个“头指针”变量,以head表示,它存放一个地址.该地址指向一个元素.链表中每一个元素称为“结点”,每个结点都应包括两个部分:一为用户需要用的实际数据,二为下一个结点的地址.因此,head指向第一个元素:第一个元素又指向第二个元素;……,直到最后一个元素,该元素不再指向其它元素,它称为“表尾”,它的地址部分放一个“NULL”(表示“空地址”),链表到此结束. 链表的各类操作包括:学习单

JavaEE包括13中核心技术

java的大方向就是JavaEE,JavaEE不仅仅是socket编程,具体包括13中核心技术. JAVAEE的核心API与组件 JAVAEE平台由一整套服务(Services).应用程序接口(APIs)和协议构成,它对开发基于Web的多层应用提供了功能支持,下面对JAVAEE中的13种技术规范进行简单的描述(限于篇幅,这里只进行简单的描述): 1.JDBC(Java Database Connectivity) JDBC API为访问不同的数据库提供了一种统一的途径,象ODBC一样,JDBC对

Qt学习过程中遇到的问题

由于工作需要,开始使用Qt,由于在网上找的教程文档时针对qt3的,所以在学习的过程遇到了许多由于版本不一致造成的问题,因此记录下来. 参考的文档是:Qt入门教程 详细讲解版 本机Qt版本为:Qt5.3.1(windows.Linux(CentOS 6.2)) windows下 1.错误:C1083: 无法打开包括文件:“QApplication”: No such file or directory原因:Qt5里不再用QtGui模块,而是使用QtWidgets模块.解决办法:在工程文件.pro里

C语言-链表

单向链表:结构体非常适合链表结构,链表的组成:head指针.数据块节点指针p->nest.结束指针NULL. 链表操作:需要首先找到表头head指针.链表的操作包括动态链表的创建.顺序输出.删除节点.插入节点的操作. 动态存储操作函数:(ANSI规则返回的指针类型为void*,早期的为字符型指针) 分配一个块:void *malloc(unsigned int size)  //分配成功则返回指向起始地址的指针void * 分配多个块:void *calloc(unsigned n,unsign

从面相对象的学习过程中得出的程序开发者需要具备的类比学习能力

什么是对象?什么是类?哪些是属性?属性应该设计成什么访问权限?这个类是不是别的类的属性?这些类能不能提取出父类?这里的参数应该设置成什么? 面向对象已经学习了一段时间了,具体使用过程中,发现原来面向对象编程需要接触这么多新鲜的概念.我先给自己打了强心剂:这些概念的提出都是为了让编程更加的方便.还好,虽然"类"这个概念对我来说有些陌生,但我很自然地,把它与我之前接触过的C语言中的结构体联系了起来. 没错,又是C语言,Java学习的过程中,我少不了要提到我亲爱的C语言.这里我不是要讲它们具

【C语言学习】封装和模块化思想

刚学习完C后,做的关于C的课程设计是在一个源文件中放了几百行代码,而且各个功能之间都是相互依赖的,这样就会很麻烦.因为当我要修改某个地方的时候,就会牵连着要修改喝多的地方.而在实际的程序设计中,这也是不可取的.因此,模块化和封装的思想就显得很重要了!!! ★static变量 static变量的一个显著的作用就是可以实现一个模块的封装. static存储类别的特性决定了static声明的全局变量只能被本源文件的函数引用.当在一个源文件中定义一个static全局变量后,其他文件就不能通过使用"ext

关于c语言链表的操作

这几天又讲到链表了,但是又忘记了,所以重新把关于链表的建链表,对链表进行排序,然后是删除,插入,以及遍历等功能..但是最近要考试了,所以没有写成菜单的形式..等考试完了,在进行补充吧.. 代码如下... #include<stdio.h> #include<stdlib.h> #include<string.h> struct node { int data; struct node *next; }; int main() { /*建立链表操作*/ int n,x,p