当前位置 博文首页 > m0_51723227的博客:结构体

    m0_51723227的博客:结构体

    作者:[db:作者] 时间:2021-08-03 21:07

    结构体的声明结构体的创建结构体成员的访问
    结构体传参

    (注意:文章最后有一定的对比解释,以理解结构体创建 声明 指针)

    1 结构体的声明与创建

    结构体是一些值的集合,这些值称为成员变量,结构体的每个成员可以是不同类型的变量

    结构体的声明语法:

    image-20210327205318046

    第一种声明:

    在创建结构体对象时候,必须写全称 struct target.

    第二种声明:

    在创建结构体对象时候,可以写全称,也可以写new-name

    请看下面两种不同声明的创建方法:

    image-20210327210830301

    很明显,第一种创建方法代码量就很多,但是如果不这样写就会报错

    ? 第二种创建方法就会省下代码量,而且创建方式还拥有第一种

    2 结构体成员的访问 . 和 ->

    注意:结构体的成员变量可以拥有 标量 数组 指针 结构体等等.

    点 . 访问结构体成员:

    #include <stdio.h>
    
    typedef struct s  /*结构体s*/
    {
       int a;
       char c;
       char arr[20];
       double d;
    }S;
    
    typedef struct t  /*结构体t*/
    {
        char ch[10];
        S s;/*简式创建*/
        char* pc;  /*指针*/
    }T;
    
    int main()
    {
        char arr[]="你好啊,憨憨!";
        T t = {"heihie", {10, 'A', "青山处处埋忠骨", 3.1415926}, arr}; /*创建结构体对象t*/
        printf("%s\n", t.ch);
        printf("%s\n",t.s.arr);/*访问结构体t里面的结构体s里面的字符数组arr*/
        printf("%lf\n",t.s.d);/*访问结构体t里面的结构体s里面的双精度浮点数d*/
        printf("%s",t.pc);
        return 0;
    }
    
    运行结果:
    heihie
    青山处处埋忠骨
    3.141593
    你好啊,憨憨!
    

    有人可能不理解上面printf("%s",t.pc); 这个为何能打印出字符串 “你好啊,憨憨!”.

    这里稍微解释下

    数组名就是首元素地址,如果我这样写想必就有人能理解 printf("%s",arr); 在上面创建的时候,pc就是指针变量,而pc里面存的就是arr

    箭头 -> 访问结构体成员 (结构体指针访问):

    #include <stdio.h>
    typedef struct student
    {
        char name[20];
        short age;
        char tele[12];
        char sex[5];
    }student;
    
    int main()
    {
        student xiaoming={"小明", 20,"18328061659", "男"};
        student* p = &xiaoming;
        printf("名字: %s\n", p->name);
        printf("年龄: %d\n", p->age);
        printf("电话: %s\n", p->tele);
        printf("性别: %s\n", p->sex);
        return 0;
    }
    

    运行结果:

    名字: 小明
    年龄: 20
    电话: 18328061659
    性别: 男
    

    3函数 结构体传参 以及两种传参的效率

    编写函数print1()和print2(),前者.访问 后者->访问

    #include <stdio.h>
    typedef struct student
    {
        char name[20];
        short age;
        char tele[12];
        char sex[5];
    }student;
    
    void print1(student tmp)   /*函数1 采用结构体传参,点式访问*/
    {
        printf("名字: %s\n", tmp.name);
        printf("年龄: %d\n", tmp.age);
        printf("电话: %s\n", tmp.tele);
        printf("性别: %s\n", tmp.sex);
    }
    
    void print2(student* tmp) /*函数2 采用结构体指针传参,箭头访问*/
    {
        printf("名字: %s\n", tmp->name);
        printf("年龄: %d\n", tmp->age);
        printf("电话: %s\n", tmp->tele);
        printf("性别: %s\n", tmp->sex);
    }
    
    int main()
    {
        student xiaoming={"小明", 20,"18328061659", "男"};
        print1(xiaoming);
        print2(&xiaoming); /*传递结构体指针*/
        return 0;
    }
    

    运行结果:

    名字: 小明
    年龄: 20
    电话: 18328061659
    性别: 男
        
    名字: 小明
    年龄: 20
    电话: 18328061659
    性别:

    如果student结构体里面包含大量的数组, long long,double 等,我们会发现如果给函数直接传结构体过去,内存资源将会消耗极大,而我们知道一个指针的大小(无论什么类型指针)在32位机上才4个字节,在64位上才8个字节,因此采用 print2的传参将会大大节约资源

    (主要原因是因为函数传参是在进行压栈操作)

    对比解释

    我们在创建 整数 ,数组 ,等会首先进行声明,然后写变量名

    比如:

    int a;
    char ch[10];
    

    而我们的结构体 struct tatget_name 就相当于int , char 等,

    比如:

    struct student a;     类似于     int   a;
    

    如果有typedef把struct student改成其他名字(即结构体末分号前面的名字)比如stu

    就可以这样写 stu a; 类似于 int a;

    同理,指针变量创建时候,int* char* double*等等 结构体指针也是 struct student *

    struct  student* pc;    类似于   int*  pc;       
    
    cs