C语言学习记录6

        接上次的结构体之后,本篇记录C语言的tydef用法。链表的知识。

都属于较为重要的部分,学习中须多加理解。

链表:

动态内存:

        malloc/free

void *malloc(size_t num)

        void free(void *P)

int *array = malloc(10 * sizeof(int)); // 分配一个容纳10个int的数组

注意点 :malloc函数并不识别要申请的内存是什么类型的,他只关心内存的字节数。

        malloc申请到的是一块连续的内存,有时申请到的大,申请不到的时候会返回null。

        malloc的类型是void,在调用时要进行显示转化。转换成所需的类型,

        free的参数是 null的话,没有任何效果。

        释放内存的一部分是不被允许的。

malloc与free配套使用,注意野指针非常危险。

链表是一种常见的数据结构后,是动态的进行储存分配的一种结构,

组成由头指针和节点组成。

链表结构的定义: 

        typedef struct Node {

int data ;

struct Node *next;

}Node;

写一个简单的链表在这里作为记录:

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

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


int main()
{
    struct student a,b,c,*head;

    a.num = 2001;
    a.score = 99 ;
    b.num = 2002;
    b.score = 91;
    c.num = 2009;
    c.score = 88;

    head = &a;
    a.next= &b;
    b.next = &c;
    c.next = NULL;

    do{
        printf("%ld %5.1f \n", head->num,head->score );
        head = head->next;
    }while(head != NULL);
    return 0;
}

结果:

链表可以分为        单链表,双链表,循环链表。

 链表的特点

  • 动态大小:链表的大小可以在运行时动态变化。
  • 无需连续内存:链表的节点可以在内存中分散存储,不需要像数组那样连续。
  • 插入和删除效率高:可以在 O(1) 时间复杂度内完成,只要提供了适当的指针或引用。

下面记录一个关于动态链表的

题目:

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

#define LEN sizeof(struct student)            //student的结构体长度

struct student *creat();                 //链表创建函数。
void print(struct student *haed);        //打印函数,

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

    int n ;           //全局变量,存放记录的节点数。


struct student *creat()
{
    struct student *head;
    struct student *p1,*p2;
    p1 = p2 = (struct student *)malloc(LEN);

    printf("please input your num :");
    scanf("%d", &p1->num );
    printf("please input your score:");
    scanf("%f", &p1->score);
    head = NULL;

    n = 0;

    while (p1 ->num)
    {

        n++;
        if(n == 1 )
        {

            head = p1;
        }
        else
        {
            p2 ->next = p1;
        }
        p2 = p1;
        p1 = (struct student *)malloc(LEN);
        printf("please input next your  num :");
        scanf("%d", &p1->num );
        printf("please input next your score:");
        scanf("%f", &p1->score);

    }
    p2 ->next = NULL;
    return head;
}

void print(struct student *head)
{

    struct student *p;
    printf("There are have %d record student\n", n);
    p = head;
    if(head != NULL){
        do {
            printf("num is %d ,score is %f",p->num,p->score);
            p = p->next;
            printf("\n");
        }while(p);
    }
}



int main()
{
    struct student *stu;
    stu  = creat();
    print(stu);
    printf(" \n");
return 0 ;
}

结果验证: 

删除一个节点:

        从动态链表删除一个节点,并不是从内存中 ,把他抹掉,而是把他从链表分离开,撤销掉原来的连接关系即可。

当然要进行内存节点的释放,否则会发生内存泄漏的情况。

链表插入节点:

无论是插入还是删除节点,

需要注意的都是创建节点,更新节点的指针,注意顺序的正确,以及头尾节点的情况,具体程序将在之后记录

typedef的用法:

声明新的类型名代替已有的类型名,

#include <stdio.h>
typedef int INTEGER;
int main()
{
INTEGER i = 1;
int j = 2;
printf("%d %d ", i , j );
}

还可以为结构体类型创建别名。 (类似的联合体union,枚举类型enum

typedef struct

{

int x;

int y;

} Point;

Point p; // 使用别名声明结构体变量

         还有指针类型 别名,   结合类型限定符,    数组类型别名。

 当不同源文件中用到同一数据类型时,常用typedef声明一些数据类型,把他们单独放在一个文件中,然后在需要用到的文件中用#include把他们包含进来。

                有利于程序的通用与移植。

#define和typedef的区别:

        #define是在预编译的时候处理的,只能做简单的字符串替换,

而typedef是在编译时候处理的,实际上他并不是简单的字符替换,而是采用如同定义变量的方法那样来声明一个类型。

记录到typedef,下次记录位运算。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值