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 中指针成员指向文字常量区 , 此时不能修改其指向地址中的值 ,只能读取或修改其指向的地址
DAY 12 结构体(重点) 共用体 枚举01_第1张图片
指针成员堆区初始化
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;
        }
}

你可能感兴趣的:(C语言,c语言,开发语言)