• 结构体初阶


    1.结构体的声明

    1.1 结构的基础知识

    结构是一些值的集合,这些值称为成员变量。例如数组是一组相同类型元素的集合,但是结构的每个成员可以是不同类型的变量

    C语言内置了一部分内置类型,例如int,char,short,int,long long,double等;能够描述一些简单的事物,但是我们日常生活中有很多复杂的事物,例如人,一本书,人:名字+电话+性别+身高,书:书名+作者+定价+书号。这时候单个类型就无法描述,我们就可以利用结构体。

    1.2 结构的声明

    //声明的结构体类型struct tag
    struct tag//tag是结构体标签
    {
    	member-list;//成员变量
    }variable-list;//变量列表,可有可无
    
    • 1
    • 2
    • 3
    • 4
    • 5

    例如描述一个学生:

    struct Stu
    {
        char name[20];//名字
        int age;//年龄
        char sex[5];//性别
        char id[20];//学号
    };//分号不能丢
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    例如描述一本书:

    struct Book
    {
        char name[20];//名字
        int price;//价格
        char writer[10];//性别
        char id[20];//书号
    }b1,b2;//b1,b2是使用struct Book结构类型创建的2个全局的结构体变量
    
    int main()
    {
        struct Book b3 = {0};//结构体变量的创建,b3是局部变量
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    image-20220808200154762

    结构体类型就相当于图纸,结构体变量就相当于房子,类比java中的类和对象思想,就像图纸并未占据空间,而房子是占据空间;结构体类型只是一个模板,并没有占据内存空间,只有创建的结构体变量才占据了一定的内存空间。

    1.3 结构成员的类型

    结构的成员可以是标量、数组、指针,甚至是其他结构体。

    sturct At
    {
        int arr[20];
        int* pa;
    };
    
    struct St
    {
        struct Peo p;
        int num;
        float f;
    };
    
    struct Node
    {
        int data;
        struct Point p;
        struct Node* next;
    }n1;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    1.4 结构体变量的定义和初始化

    有了结构体类型,我们可以直接创建结构体变量,并且对结构体变量进行初始化。

    struct Peo 
    {
        char name[20];
        char tele[12];
        char sex[5];
        int height;
    }p3,p4;
    
    struct Peo p5,p6;
    
    struct St
    {
        struct Peo p;
        int num;
        float f;
    };
    
    struct Node
    {
        int data;
        struct Point p;
        struct Node* next;
    }n1 = {10, {4,5}, NULL}; //结构体嵌套初始化
    
    int main()
    {
        //初始化的顺序要于结构体类型的成员变量一一对应
        struct Peo p1 = {"zhangsan", "13503532463", "男", 190};
        struct St s = {{"lisi","15235335492","女",168}, 100, 3.14f};
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    2.结构体成员的访问

    2.1 结构体变量访问成员

    结构变量的成员是通过点操作符(.)访问的。点操作符接受两个操作数。 例如:

    struct Peo 
    {
        char name[20];
        char tele[12];
        char sex[5];
        int height;
    };
    
    struct St
    {
        struct Peo p;
        int num;
        float f;
    };
    
    int main()
    {
        struct Peo p1 = {"zhangsan", "13503532463", "男", 190};
        struct St s = {{"lisi","15235335492","女",168}, 100, 3.14f};
    	printf("%s %s %s %d\n",p1.name, p1.tele, p1.sex, p1.height);//结构体.成员变量
        printf("%s %s %s %d %d %f\n",s.p.name, s.p.tele, s.p.sex, s.p.height, s.num, s.f);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    运行结果:image-20220808211901666

    2.2 结构体指针访问指向变量的成员

    有时候我们得到的不是一个结构体变量,而是指向一个结构体的指针。那该如何访问成员。 如下:

    struct Peo
    {
        char name[20];
        char tele[12];
        char sex[5];
        int height;
    };
    
    struct St
    {
        struct Peo p;
        int num;
        float f;
    };
    
    void print1(struct Peo* p)
    {
        printf("%s %s %s %d\n", p->name, p->tele, p->sex, p->height);// 结构体指针->成员变量
        printf("%s %s %s %d\n", (*p).name, (*p).tele, (*p).sex, (*p).height);// *(结构体指针).成员变量
    }
    void print2(struct St* s)
    {
        printf("%s %s %s %d %d %f\n", (*s).p.name, (*s).p.tele, (*s).p.sex, (*s).p.height, (*s).num, (*s).f);
        printf("%s %s %s %d %d %f\n", s->p.name, s->p.tele, s->p.sex, s->p.height, s->num, s->f);
    }
    
    int main()
    {
        struct Peo p1 = { "zhangsan", "13503532463", "男", 190 };
        struct St s1 = { {"lisi","15235335492","女",168}, 100, 3.14f };
        print1(&p1);
        print2(&s1);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    运行结果:image-20220808215324945

    3.结构体传参

    直接上代码:

    struct S
    {
        int data[1000];
        int num;
    };
    struct S s = {{1,2,3,4}, 1000};
    //结构体传参
    void print1(struct S s)
    {
    	printf("%d\n", s.num);
    }
    //结构体地址传参
    void print2(struct S* ps)
    {
    	printf("%d\n", ps->num);
        printf("%d\n", *(ps).num);
    }
    int main()
    {
        print1(s); //传结构体
        print2(&s); //传地址
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    上面的 print1和 print2函数哪个好些?

    答案是:首选print2函数。

    原因:

    函数传参的时候,参数是需要压栈的。 你传递结构体作为参数,传递的其实是结构体的一份临时拷贝,如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统空间开销比较大,并且时间耗费严重,所以会导致性能的下降。而我们传递结构体地址(指针)作为参数,传递的其实是结构体所占空间的地址,地址的大小无非是4/8字节,空间较小,指针会指向地址所在的空间进行访问,并且还可以更改结构体。

    结论: 结构体传参的时候,尽量传结构体的地址。

  • 相关阅读:
    [附源码]java毕业设计同城搬家平台
    自动化测试类型有哪些?是怎么分类的
    Zotero文献管理软件入门使用方法:软件下载、文献导入、引文插入
    ArcGIS要点和难点以及具体应用和优缺点介绍
    【brpc学习实战二】brpc client构建基本流程
    《工程伦理与学术道德》之《工程活动中的环境伦理》
    redisson使用全解——redisson官方文档+注释(下篇)
    redis 搭建主从
    Spring Boot 日志文件
    网工方向基本常识(持续更新)
  • 原文地址:https://blog.csdn.net/m0_64224788/article/details/126237304