• DAY 12 结构体(重点) 共用体 枚举01


    1.结构体

    1.概念

    将基本类型或构造类型封装在一起,拥有独立空间,这个数据结构 就叫结构体。
    结构体 使用的关键字 struct.
    一个结构体可以定义多个结构体变量

    2.定义

    注意:

            1,结构体定义一般在头文件中
            2,不要在定义结构体时给其成员初始化
    方式一:

            struct 结构体名称  

    {

            成员

    };

    定义结构体变量:
            struct 结构体名称 结构体对象名 ;
    特点
             将定义结构体与定义结果体变量分开
    示例:
            
    struct stu
    {
            char name[50];
            char sex[5];
            int age;
    };
    void fun01()
    {
            struct stu s1;
    }

    方式二:

    语法:

            struct 结构体名称  

    {

            成员

    }结构体变量名;

    特点
            定义结构体同时定义一个结构体变量
    示例
            
    struct stu
    {
            char name[50];
            char sex[5];
            int age;
    } s1;
    方式三:
    语法:
            

     struct 

    {

            成员

    }结构体变量名;

    特点

            该结构体变量只有一个,我们将其称为一次性结构体

    示例:     

    struct
    {
            char name[50];
            char sex[5];
            int age;
    } s1;

    初始化

    语法:

    struct 结构体名称 结构体变量名 = { 1, 2, 3};
    结构体对象清 0
    memset(& 结构体变量名 ,0,sizeof(struct 结构体名称 ));
    注意:
    1, 结构体初始化 必须准许成员顺序和成员自身类型
    2, 定义与初始化必须同时进行

    使用

    获取结构体成员
             结构体变量名 . 成员变量名
    赋值
            
            普通类型
                    结构体变量名.成员变量名 = ;
            字符数组
                    strcpy(结构体变量名. 成员变量名 , );
            整体赋值
                    结构体变量名1 = 结构体变量名 2;
            使用memcpy 内存拷贝
                    memcpy(目标结构体变量地址, 原结构体变量地址 , 长度 );
    示例:
    struct stu s1 = { " 张桑 " , " " , 18 };
    struct stu s2 = s1 ;
    s2 . age = 20 ;
    struct stu s3 ;
    memcpy ( & s3 , & s1 , sizeof ( struct stu ));
    s3 . age = 21 ;
    printf ( "%s\n" , s1 . name );
    printf ( "%s\n" , s1 . sex );
    printf ( "%d\n" , s1 . age );
    printf ( "%s\n" , s2 . name );
    printf ( "%s\n" , s2 . sex );
    printf ( "%d\n" , s2 . age );
    printf ( "%s\n" , s3 . name );
    printf ( "%s\n" , s3 . sex );
    printf ( "%d\n" , s3 . age );
    注意: 每个结构体变量都有其独立的内存 , 互不干扰

    typedef与结构体

    作用 : 简化结构体
    语法
            
    typedef struct 结构体名
    {
            成员
    } 别名 ;
    示例:
    typedef struct dog
    {
            char name [ 50 ];
            char sex [ 5 ];
            int age ;
    } Dog ;
    void fun08 ()
    {
            Dog d1 = { " 旺财 " , " " , 2 };
            Dog d2 = { " 富贵 " , " " , 1 };
            printf ( "%s %s %d\n" , d1 . name , d1 . sex , d1 . age );
            printf ( "%s %s %d\n" , d2 . name , d2 . sex , d2 . age );
            Dog * p = & d1 ;
            printf ( "%s %s %d\n" , p -> name , p -> sex , p -> age );
            strcpy ( p -> name , " 黑豹 " );
            printf ( "%s %s %d\n" , p -> name , p -> sex , p -> age );
    }

    结构体指针变量

    定义

            struct 结构体名称 *指针变量名 = &结构体变量;

    操作语法

            指针变量名->成员名称

    示例1

    void fun03 ()
    {
            struct stu s1 = { " 小明 " , " " , 18 };
            struct stu * p = & s1 ;
            printf ( "%s %s %d\n" ,( * p ). name ,( * p ). sex ,( * p ). age );
            printf ( "%s %s %d\n" , p -> name , p -> sex , p -> age );
            strcpy ( p -> name , " 大明 " );
            printf ( "%s %s %d\n" , p -> name , p -> sex , p -> age );
    }

    示例2堆区申请内存

    void fun04 ()
    {
            struct stu * p = ( struct stu * ) calloc ( 1 , sizeof ( struct stu ));
            printf ( "%s %s %d\n" , p -> name , p -> sex , p -> age );
            strcpy ( p -> name , " 大明 " );
            strcpy ( p -> sex , " " );
            p -> age = 18 ;
            printf ( "%s %s %d\n" , p -> name , p -> sex , p -> age );
    }

    结构体数组

    定义

            struct 结构体名称 数组名[长度];

    初始化      

    struct 结构体名称 数组名 [ 长度 ] = {{ 成员值 1, 成员值 2,..},{ 成员值 1, 成员值2,..},...};

    示例1        

    struct person
    {
            char name[50];
            char sex[5];
            int age;
    };
    void fun05()
    {
            struct person persons[] = {{"张三 "," ",18},{" 李四 "," ",20},{" 小红"," ",19}};
            int len = sizeof(persons)/sizeof(struct person);
            for(int i = 0; i < len; i++)
            {
            printf("%s %s %d\n",persons[i].name,persons[i].sex,persons[i].age);
            }
    }

    示例2

    struct person
    {
            char name [ 50 ];
            char sex [ 5 ];
            int age ;
    };
    void fun06 ()
    {
            struct person ps [ 3 ];
            memset ( ps , 0 , sizeof ( ps ));
            for ( int i = 0 ; i < 3 ; i ++ )
            {
            scanf ( "%s %s %d" , ps [ i ]. name , ps [ i ]. sex , & ps [ i ]. age );
            }
            for ( int i = 0 ; i < 3 ; i ++ )
            {
            printf ( "%s %s %d\n" , ps [ i ]. name , ps [ i ]. sex , ps [ i ]. age );
            }
    }
    示例3
    void fun07 ()
    {
            struct person * ps = ( struct person * ) calloc ( 3 , sizeof ( struct person ));
            memset ( ps , 0 , sizeof ( ps ));
            for ( int i = 0 ; i < 3 ; i ++ )
            {
            scanf ( "%s %s %d" , ps [ i ]. name , ps [ i ]. sex , & ps [ i ]. age );
            }
            for ( int i = 0 ; i < 3 ; i ++ )
            {
            printf ( "%s %s %d\n" , ps [ i ]. name , ps [ i ]. sex , ps [ i ]. age );
            }
    }

    指针变量作为结构体成员

    注意 : 不要操作结构体变量中未初始化指针
    示例
    typedef struct cat
    {
            char *name;
            int age;
    }Cat; void fun09()
    {
    //1, 不要操作结构体变量中未初始化指针
    // 定义结构体变量 , 但不初始化 , 此时其中的指针为野指针
    // Cat c1;
    // printf("%s\n",c1.name);
    // 定义结构体变量 , 使用 memset 0, 此时其中的指针为空指针
            Cat c2;
            memset(&c2,0,sizeof(c2));
            printf("%s\n",c2.name);
    }
    指针成员初始化
    void fun10()
    {
            Cat c = {"布丁 ",2};
            printf("%s\n",c.name);
    }
    // 注意 : 此时结构体变量 c 中指针成员指向文字常量区 , 此时不能修改其指向地址中的值 ,只能读取或修改其指向的地址
    指针成员堆区初始化
    void fun11()
    {
            Cat c;
            c.name = (char *)malloc(50);
            strcpy(c.name,"tom");
            c.age = 2;
            printf("%s\n",c.name);
            c.name[0] = 'T';
            printf("%s\n",c.name);
            if (c.name != NULL)
            {
            free(c.name);
            c.name = NULL;
            }
    }
    // 使其指针成员指向堆区 , 那么就可以对其进行读写
    结构体指针变量堆区初始化 , 指针成员堆区初始化:
    void fun12()
    {
    /*
    1, 先在堆区初始化结构体指针变量
    2. 然后在堆区初始化成员指针变量
    3,...
    4, 释放成员指针变量堆区空间 5, 释放结构体指针变量堆区空间
    */
            Cat *c = (Cat *) malloc(sizeof(Cat));
            c->age = 3;
            c->name = (char *)malloc(20);
            strcpy(c->name,"布丁 ");
            printf("%s %d\n",c->name,c->age);
            if (c->name != NULL)
            {
            free(c->name);
            c->name = NULL;
            }
            if (c != NULL)
            {
            free(c);
            c = NULL;
            }
    }
    结构体指针数组堆区初始化 , 结构体指针变量堆区初始化 , 指针成员堆区初始化
    void fun13()
    {
    /*
    1, 先在堆区初始化结构体指针数组
    2, 再在堆区初始化结构体指针变量
    3. 然后在堆区初始化成员指针变量
    3,...
    4, 释放成员指针变量堆区空间
    5, 释放结构体指针变量堆区空间
    6, 释放结构体指针数组堆区空间
    */
            Cat **cs = (Cat **) calloc(3,sizeof(Cat *));
            for(int i = 0; i < 3; i++)
            {
            Cat *c = (Cat *)malloc(sizeof(Cat));
            c->name = (char *)malloc(20);
            scanf("%s %d",c->name,&(c->age));
            cs[i] = c;
            }
            for(int i = 0; i < 3; i++)
            {
            printf("%s %d\n",cs[i]->name,cs[i]->age);
                    if (cs[i]->name != NULL)
                    {
                    free(cs[i]->name);
                    cs[i] = NULL;
                    }
                    if (cs[i] != NULL){
                    free(cs);
                    cs[i] = NULL;
                    }
            }
            if (cs != NULL)
            {
            free(cs);
            cs = NULL;
            }
    }
    浅拷贝 : 拷贝地址
            
    typedef struct test01
    {
            char *str;
    } Test01;
    void fun14()
    {
            Test01 t01;
            t01.str = (char *) malloc(20);
            strcpy(t01.str,"德玛西亚 ");
            Test01 t02;
            t02 = t01;//此时 t02 的中 str t01 中的 str 指向同一堆区地址 , 发生浅拷贝
            printf("t01.str = %s\n",t01.str);
            printf("t02.str = %s\n",t02.str);
            strcpy(t02.str,"艾欧尼亚 ");
            printf("t01.str = %s\n",t01.str);
            printf("t02.str = %s\n",t02.str);
    // 当释放是会产生错误
            if (t01.str != NULL)
            {
            free(t01.str);
            t01.str = NULL;
            }
            if (t02.str != NULL)
            {
            free(t02.str);
            t02.str = NULL;
            }
    }
    深拷贝: 拷贝内容
    void fun15()
    {
            Test01 t01;
            t01.str = (char *) malloc(20);
            strcpy(t01.str,"德玛西亚 ");
            Test01 t02;
            t02.str = (char *) malloc(20);
            strcpy(t02.str,t01.str);//深拷贝
            printf("t01.str = %s\n",t01.str);
            printf("t02.str = %s\n",t02.str);
            strcpy(t02.str,"艾欧尼亚 ");
            printf("t01.str = %s\n",t01.str);
            printf("t02.str = %s\n",t02.str);
            if (t01.str != NULL)
            {
            free(t01.str);
            t01.str = NULL;
            }
            if (t02.str != NULL)
            {
            free(t02.str);
            t02.str = NULL;
            }
    }
  • 相关阅读:
    春播秋收 “羊”鸣德州 一场“苏尼特羊”跨越千里的美丽邂逅
    第四十六章 命名空间和数据库 - 系统提供的数据库
    记一次 .NET 某工控数据采集平台 线程数 爆高分析
    领域驱动模型DDD(一)——服务拆分策略
    在Kubernetes环境中有关Nginx Ingress与API Gateway的连接问题
    java版工程管理系统Spring Cloud+Spring Boot+Mybatis实现工程管理系统源码
    【线性代数】P1 行列式基本概念
    HR领域有哪些含金量高的证书?这个证书了解一下!
    《计算机网络 - 自顶向下方法》阅读笔记
    外网优秀的排序解析
  • 原文地址:https://blog.csdn.net/aisheisadas/article/details/134274006