关于结构体的使用

一、结构体的作用

生活中我们会遇到很多的表格,就比如你的学习成绩表,有姓名 ,学号,各科的成绩,总的成绩等等,这是一些不同的数据类型,我们要是在c语言中想同时使用这些不同的数据怎么办呢? 可以使用结构体变量,结构体变量在c语言中是一种构造类型的数据,顾名思义,它跟基本的如int这种原子类型的变量不同.可以把他看作这些基本变量的集合.

1.1:结构体变量的基本定义格式

struct 结构体名
{
	<基本类型名>  <成员变量名>;
	<基本类型名>  <成员变量名>;
	<基本类型名>  <成员变量名>;
};

注意:struct 是关键字是结构体类型的说明标识符,不能省略,结构体名可以省略,我们在使用 typedef struct 时就省略了就不写结构体名

例子:
##方法一
typedef struct Node
{
    int age;
    struct Node *next;
} Node;

##方法二
struct Node
{
    int age;
    struct Node *next;
};

方法一是帮结构体取好了名字  为Node
方法二是仅仅定义了结构体

1.2结构体变量的定义

        首先结构体就是一个各种基本数据类型的集合,而就结构体变量就像我们定义一个集合s={1,2,3,4},s就相当于一个结构体变量,结构体变量包含结构体中的各个成员变量,我们可以对成员变量进行引用

struct 结构体名  a, b;     //定义了两个结构体变量
strcut 结构体名 S[4];      //定义一个结构体变量数组,有四个元素
strcut 结构体名* p = &a;   //定义一个结构体指针,指向结构体变量a


定义结构体的三种方式,这个是在需要用到结构体的时候才进行定义

1.3结构体变量的三种引用方法

结构体变量.成员名
(*结构体指针).成员名
结构体指针->成员名       //使用指针的时候推荐使用这一种,因为在数据结构中,很多这种引用方式

二、结构体传参部分

结构体传参包括三种传参方式

        1.普通传参:函数接收到结构体参数后,会复制一份原来的结构体作为形参供函数使用,而函数内的任何操作都是对拷贝结构体的修改,不会影响到原本的结构体变化。
        2.单指针传参:函数接收的是一个结构体的地址,该指针指向的是结构体起始地址,也就相当于传入了结构体内所有变量的地址,函数接收到该结构体指针后,我们就可以根据地址访问结构体中每个变量的真实数据,在函数内对结构体内数据的操作,都会影响到原本结构体内数据的变化
        3.双指针传参:函数接收的是结构体指针变量的地址,因为一级指针代表的是结构体的地址,在函数中能够操作结构体内的数据,则二级指针指向的是结构体的地址,则同理我们可以根据二级指针访问修改结构体的地址
即通过一级指针,对结构体内数据的操作会影响到原本结构体内数据的变化
而通过二级指针,对结构体地址的操作会影响到原本结构体地址的变化,例如为结构体分配空间

2.1普通传参

#include <stdio.h>
#include <stdlib.h>
typedef struct Node
{
    int age;
    struct Node *next;
} Node;

// 普通传参
void test(Node p)
{

    printf("test():\n");

    printf("数据: p.age = %d\n", p.age);
    printf("地址: p = %x, p->next = %x\n\n", &p, p.next);

    // 在函数内定义一个新的结构体
    Node q;
    q.age = 3;
    q.next = NULL;
    
    // 修改结构体内的数据
    p.age = 2;
    p.next = &q;
    printf("数据: p.age = %d\n", p.age);
    printf("地址: p = %x, p->next = %x\n", &p, p.next);

    printf("数据: q.age = %d\n", q.age);
    printf("地址: q = %x, q->next = %x\n\n", &q, q.next);
}

int main()
{
    Node p;
    p.age = 1;
    p.next = NULL;

    printf("main():\n");
    printf("数据: p.age=%d\n", p.age);
    printf("地址: p=%x, p->next=%x\n\n", &p, p.next);

    test(p);

    printf("main():\n");
    printf("数据: p.age=%d\n", p.age);
    printf("地址: p=%x, p->next=%x\n\n", &p, p.next);

    return 0;
}

 2.2单指针传参

#include <stdio.h>
#include <stdlib.h>
typedef struct Node
{
    int age;
    struct Node *next;
}Node;

// 单指针传参,修改结构体数据
void ModifyData(Node *p)
{
    printf("ModifyData:\n");

    printf("数据: p.age = %d\n", p->age);
    printf("地址: p = %x, p->next = %x\n\n", p, p->next);

    // 在函数内定义一个新的结构体
    Node q;
    q.age = 3;
    q.next = NULL;
    
    // 修改数据(age,next)
    p->age = 2;
    p->next = &q;

    printf("数据: p.age = %d\n", p->age);
    printf("地址: p = %x, p->next = %x\n\n", p, p->next);

    printf("数据: q.age = %d\n", q.age);
    printf("地址: q = %x, q->next = %x\n\n", &q, q.next);

}

int main()
{
    Node p;
    p.age = 1;
    p.next = NULL;

    printf("main():\n");
    printf("数据: p.age = %d\n", p.age);
    printf("地址: p = %x, p->next = %x\n\n", &p, p.next);

    ModifyData(&p);

    printf("main():\n");
    printf("数据: p.age = %d\n", p.age);
    printf("地址: p = %x, p->next = %x\n\n", &p, p.next);

    return 0;
}

2.3修改结构体地址

#include <stdio.h>
#include <stdlib.h>
typedef struct Node
{
    int age;
    struct Node *next;
}Node;

// 单指针传参, 尝试修改结构体地址
Node *ModifyAddress(Node *p)
{
    printf("ModifyAddress():\n");

    printf("数据: p.age = %d\n", p->age);
    printf("地址: p = %x, p->next = %x\n", p, p->next);
    printf("形参指针变量p的地址 = %x\n\n", &p);

    // 尝试为指针重新分配地址,并修改原本结构体内部数据
    p = (Node *)malloc(sizeof(Node));
    p->age = 4;
    p->next = NULL;

    printf("数据: p.age = %d\n", p->age);
    printf("地址: p = %x, p->next = %x\n", p, p->next);
    printf("形参指针变量p的地址 = %x\n\n", &p);

    // 返回修改后的结构体指针p
    return p;
}

int main()
{
    Node p;
    p.age = 1;
    p.next = NULL;

    printf("main():\n");
    printf("数据: p.age = %d\n", p.age);
    printf("地址: p = %x, p->next = %x\n\n", &p, p.next);

    Node *new_p = ModifyAddress(&p);

    printf("main():\n");
    printf("数据: p.age = %d\n", p.age);
    printf("地址: p = %x, p->next = %x\n", &p, p.next);

    printf("数据: new_p.age = %d\n", new_p->age);
    printf("地址: new_p = %x, new_p->next = %x\n\n", new_p, new_p->next);

    return 0;
}

2.4 双指针传参

#include <stdio.h>
#include <stdlib.h>
typedef struct Node
{
    int age;
    struct Node *next;
} Node;

// 双指针传参
void test(Node **p)
{

    printf("test:\n");
    printf("数据: p.age = %d\n", (*p)->age);
    printf("地址:p = %x, (*p) = %x, (*p)->next = %x\n", p, (*p), (*p)->next);
    printf("指针p的地址 = %x\n\n", &p);
    
    // 在函数内定义一个新的结构体
    Node q;
    q.age = 3;
    q.next = NULL;
    

    // 为结构体(*p)重新分配地址,并修改变量数据
    (*p) = (Node *)malloc(sizeof(Node));
    (*p)->age = 2;
    (*p)->next = &q;
    
    printf("数据: p.age = %d\n", (*p)->age);
    printf("地址:p = %x, (*p) = %x, (*p)->next = %x\n", p, (*p), (*p)->next);
    printf("指针p的地址 = %x\n\n", &p);

    printf("数据: q.age = %d\n", q.age);
    printf("地址: q = %x, q->next = %x\n\n", &q, q.next);
}

int main()
{

    Node *p;
    // 为指针结构体p分配地址
    p = (Node *)malloc(sizeof(Node));
    p->age = 1;
    p->next = NULL;

    printf("main():\n");
    printf("数据: p.age = %d\n", p->age);
    printf("地址: p = %x, p->next = %x\n", p, p->next);
    printf("指针p的地址 = %x\n\n", &p);

    test(&p);

    printf("main():\n");
    printf("数据: p.age = %d\n", p->age);
    printf("地址: p = %x, p->next = %x\n", p, p->next);
    printf("指针p的地址 = %x\n\n", &p);

    return 0;
}

 

  • 12
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Gallagher_SF

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值