吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1264|回复: 8
收起左侧

[学习记录] 学习c语言的第五天:结构指针变量的说明和简单使用以及简单链表的认识

  [复制链接]
laiyuou 发表于 2021-11-12 14:00

结构指针变量的说明和使用:
一个指针变量当用来指向一个结构变量时,称之为结构指针变量。结构指针变量中的值是所指向的结构变量的首地址。
通过结构指针可访问该结构变量,这与数组指针和函数指针的情况是相同的
结构指针变量的说明的一般形式:
struct 结构名 结构指针变量名
例如:
struct stu
pstu;
结构指针变量是要先赋值后才能使用。赋值是把结构变量的首地址赋予该指针变量,不能把结构名赋予该指针变量。
结构指针变量的一般访问形式:
(*结构指针变量).成员名
或者:结构指针变量->成员名

例子1:

struct stu {
    int num;
    char *name;
    char sex;
    float score;
}boy1 = {102,"Zhang ping",'M',78.5},*pstu;

int main()
{
    pstu = &boy1;//把结构变量的boy1的地址赋值给pstu
    printf("Number=%d\nName=%s\n", boy1.num, boy1.name);
    printf("Sex=%c\nScore=%f\n\n", boy1.sex, boy1.score);
    printf("Number=%d\nName=%s\n", (*pstu).num, (*pstu).name);
    printf("Sex=%c\nScore%f\n\n", (*pstu).sex, (*pstu).score);
    printf("Number=%d\nName=%s\n", pstu->num, pstu->name);
    printf("Sex=%c\nScore=%f", pstu->sex, pstu->score);
    return 0;
}

结构指针变量作函数参数
在ANSI的c标准中,是允许使用结构变量作为函数参数进行整体传送的。但是这种传送要将全部成员逐个传送,但是会花费很
的时间和空间。因此使用指针来进行传送更好

例子2:计算一组学生的平均成绩和不及格人数。使用结构指针变量作函数参数编程

struct stu
{
    int num;
    char *name;
    char sex;
    float score;
}boy[5] = {
    {101,"Li ping",'M',45},
{102,"Zhang ping",'M',62.5},
{103,"He feng",'F',92.5},
{104,"Cheng ling",'F',87},
{105,"Wang ming",'M',58}
};
int main()
{
    struct stu *ps;
    void ave(struct stu *ps);
    ps = boy;
    ave(ps);
    return 0;
}
void ave(struct stu *ps)
{
    int c = 0;
    float ave = 0,s=0;
    for (int i = 0; i < 5; i++, ps++)
    {
        s += ps->score;
        if ((ps->score) < 60)
        {
            c += 1;
        }
    }
    printf("s=%f\n", s);
    ave = s / 5;
    printf("average=%f\ncount=%d\n", ave, c);
}

动态存储分配;
在c语言中不允许动态数组类型
c语言提供了一些内存管理函数,主要有三种:

分配内存空间函数malloc:
调用的形式:(类型说明符)malloc(size)
功能:在内存的动态存储区中分配一块长度为“size”字节的连续区域。函数的返回值为该区域的首地址。
“类型说明符”表示把该区域用于何种数据类型。
(类型说明符
)表示把返回值强制转换为该类型指针。

分配内存空间函数:calloc
调用形式:(类型说明符)calloc(n,size)
功能:在内存动态存储区中分配n块长度为:“size”字节的连续区域。函数的返回值是为该函数的首地址。
(类型说明符
)用于强制类型转换。
calloc函数与malloc函数的去区别仅在于一次可以分配n块区域。
例如:ps=(struct stu*)calloc(2,sizeof(struct stu);-->其中siezeof(struct stu)是求stu的结构长度。因此该语句的意思:
按照stu的长度分配2块连续区域,强制转换为stu类型,并把其首地址赋予指针变量ps.

释放内存空间函数free
调用形式:free(void *ptr):释放ptr所指向的一块内存空间,ptu是一个任意类型的指针变量,它指向被释放区域的首地址。被释放区
应是由malloc或者calloc函数所分配的区域。
例子3:分配一个块区域,输入一个学生数据

int main()
{
    struct stu
    {
        int num;
        char *name;
        char sex;
        float score;
    }*ps;//ps这个指针变量指向一个stu结构的首地址
    ps = (struct stu*)malloc(sizeof(struct stu));
    ps->num = 102;
    ps->name = "Zhang ping";
    ps->sex = 'M';
    ps->score = 62.5;
    printf("Num=%d\nName=%s\n", ps->num, ps->name);
    printf("Sex=%c\nScore=%f\n", ps->sex, ps->score);
    free(ps);
    return 0;
}
链表的概念:即就是动态存储的办法,我们来存放一个学生的数据是,可以分配一块可用空间来存放,我也称之这样一块存储的空间为

一个节点,我们存放一个学生数据就分配一个节点,无须预先确定学生的准确人数,某学生退学,可以删去该节点,并释放该节点占用的空间
使用动态分配时,每个节点之间可以是不连续(结点内部之间是连续的),而结点之间的连续可以用指针来实现。即
在结点结构中定义一个成员项用来存放下一个结点的首地址,这个用于存放地址的成员,常把它称为指针域。
我们可以在结点的指针域中存放第二个结点的首地址,在第二个结点的指针域内与存放第三个结点的首地址,如此串联下去直到最后一个结点
最后一个结点因无后续结点连接,其指针域可赋值为0.这样的一种连接方式,在数据结构中称为:“链表”。
例如:一个存放学生学号和成绩的结点应为一下结构:

struct stu
{
    int num;
    int score;
    struct stu *next;
};//前面两个成员组成数据域,后一个成员项next构成指针域,他是一个指向stu类型结构的指针变量。

链表的基本操作对链表的主要操作有一下几种:
1.建立链表;
2.结构的查找与输出;
3.插入一个结点;
4.删除一个结点;

例子4:建立一个三个结点的链表,存放学生的数据。为了简单起见,我们假定学生数据结构中只有学号和年龄两项。可编写一个建立链表的函数creat。

#define NULL 0
#define TYPE struct stu
#define LEN sizeof(struct stu)

struct stu
{
    int num;
    int age;
    struct stu *next;
};
TYPE *creat(int n)
{
    struct stu *head, *pf, *pb;
    int i;
    for (i = 0; i < n; i++)
    {
        pb = (TYPE*)malloc(LEN);
        printf("input Number and Age:\n");
        scanf_s("%d%d", &pb->num, &pb->age);
        if (i == 0)
        {
            pf = head = pb;
        }
        else
        {
            pf->next = pb;
            pb->next = NULL;
            pf = pb;
        }
        return (head);
    }
}

在函数外首先用宏定义对三个符号常量作了定义。这样用TYPE表示struct stu,用LEN表示sizeof(struct stu)主要的目的是为了
在一下程序内减少书写并使阅读更加方便。结构stu定义为外部类型,程序中的各个函数均可使用该定义。
creat函数用于建立一个有n 个结点的链表,它是一个指针函数,他返回的指针指向stu结构。在creat函数内定义了三个stu结构的指针变量
head为头指针,pf为指向两相邻结点的前一结点的指针变量,bp为后指针变量

创建一个有n个结点的链表

创建链表:

typedef struct student {
    int score;
    struct student *next;
}LinkList;

一般我们创建链表都用typedef struct,因为这样定义结构体变量时,我们就可以直接使用LinkList,*a定义的结构体类型变量了。
初始化一个链表,n为链表结点个数。

LinkList *creat(int n)
{
    LinkList *head,*node ,*end;
    head = (LinkList*)malloc(sizeof(LinkList));//为头结点分配内存空间
    end = head;
    for (int i = 0; i < n; i++)
    {
        node = (LinkList*)malloc(sizeof(LinkList));//为不同结点分配内存空间
        scanf_s("%d\n", &node->score);
        end->next = node;//把当前结点的地址给到下一个结构体结点end的指针域
        end = node;
    }
    end->next = NULL;
    return head;
}

修改链表的结点值:

void change(LinkList *list, int n)
{
    LinkList *t = list;
    int i = 0;
    while (i < n && t!= NULL)
    {
        t = t->next;//通过这一步跳到下一个节点
        i++;
    }
    if (t != NULL)
    {
        puts("输入要修改的值\n");
        scanf_s("%d\n", &t->score);
    }
    else
    {
        puts("节点不存在");
    }
}

删除链表结点:也就是把前节点的指针域越过要删除的节点指向下下一个节点。

void delet(LinkList *list, int n)
{
    LinkList *t = list, *in;
    int i = 0;
    while (i < n  && t != NULL)
    {
        in = t;
        t = t->next;//通过这一步跳到下一个节点
        i++;
    }
    if (t != NULL)
    {
        in->next = t->next;
        free(t);
    }
    else
    {
        puts("结点不存在");
    }
}

插入链表节点:就是把插入前的head指针域即head->next赋值给想要插入的这个结点的指针域(假设插入的这个节点为e,即e->next = head->next)
然后再把插入的结点的首地址赋值给在head的指针域:head->next = e;

void insert(LinkList *list, int n)
{
    LinkList *t = list, *in;
    int i = 0;
    while (i < n && t != NULL)
    {
        t = t->next;
        i++;
    }
    if (t != NULL)
    {
        in = (LinkList*)malloc(sizeof(LinkList));
        puts("请输入要插入的值");
        scanf_s("%d", &in->score);
        in->next = t->next;
        t->next = in;
    }
    else
    {
        puts("节点不存在");
    }
}

输出链表:通过遍历输出链表

while (h->next != NULL)
{
    h = h->next;
    printf("%d\n", h->score);
}

免费评分

参与人数 1吾爱币 +7 热心值 +1 收起 理由
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

头像被屏蔽
偶尔平凡 发表于 2021-11-12 14:12
提示: 作者被禁止或删除 内容自动屏蔽
lsjhwei 发表于 2021-11-12 15:19
15071719559 发表于 2021-11-12 15:32
m350 发表于 2021-11-12 16:09
用的什么软件能分享下吗
okxiaobu 发表于 2021-11-12 16:23
跟着楼主学习,以前学的,不写代码都忘了,跟着复习下
bester 发表于 2021-11-12 17:20
你好 请问你看的是谁的视频教程呢 能不能推荐一下
 楼主| laiyuou 发表于 2021-11-12 17:28
m350 发表于 2021-11-12 16:09
用的什么软件能分享下吗

vs2017,好像是企业版
 楼主| laiyuou 发表于 2021-11-12 17:29
bester 发表于 2021-11-12 17:20
你好 请问你看的是谁的视频教程呢 能不能推荐一下

c语言程序设计谭浩强第三版+csdn+b站
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 21:49

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表