C语言结构体

287 阅读5分钟

结构体是C语言核心,结构体是进行开发必备!

结构体属于一种复合数据类型,本质上与char int double 是一样的。

结构体三种使用方式:

1.直接定义结构型变量

struct{
    数据类型1 成员1;
    数据类型2 成员2;
    ...
}变量;
#include <stdio.h>
#include <string.h>

int main(void){
    //直接定义结构体数据类型变量team1并且初始化
    struct{
        char name[32];//存储队员的姓名,字符串
        int age;//存储队员的年龄
    }stu1 = {"dagu", 22};
    
    //打印队员的信息
    printf("%s, %d\n", team1.name, team1.age);//通过变量名访问其中的成员语法:变量名.成员名
    
    //修改成员的内存值
    team1.age++;
    strcpy(team1.name, "dijia");
    
    //打印队员的信息
    printf("%s, %d\n", team1.name, team1.age);
    
    return 0;
}

2.先声明结构类型,再用该类型定义变量

struct name{
    类型1 成员1;
    类型2 成员2;
    ...
};
struct 结构类型名 变量;//把struct结构体类型名类比成int类型
#include <stdio.h>
#include <string.h>

//声明描述队员信息的结构体数据类型,类似于创造自己的int一样
struct team{
    char name[32];//存储队员的姓名,字符串
    int age;//存储队员的年龄
};//讲struct team当做int类型使用,声明数据类型的时候,不会分配内存
int main(void){
    //拿着新的数据类型来定义变量
    struct team team1 = {"dagu", 22};//类比int team1
    //定义结构体类型变量的指针pteam指向team1
    struct team* pteam = &team1;
    
    //打印队员信息
    printf("%s, %d\n", team1.name, team1.age);
    printf("%s, %d\n", pteam -> name, pteam -> age);//通过指针变量访问成员语法:指针变量 -> 成员
    
    team1.age++;//修改age年龄
    strcpy(pteam -> name, "dijia");//修改name成员
    
    //打印队员信息
    printf("%s, %d\n", team1.name, team1.age);
    printf("%s, %d\n", pteam -> name, pteam -> age);
    return 0;
}

3.通过typedef定义类型别名,再用该别名定义变量

struct 结构类型{
    数据类型1 成员1;
    数据类型2 成员2;
    ...
};
typedef struct 结构体类型 别名;
typedef struct [结构类型]{//[]里的内容可省略
    数据类型1 成员1;
    数据类型2 成员2;
    ...
}类型别名;
//使用typedef的数据类型别名,加上"_t"
#include <stdio.h>
#include <string.h>

typedef struct team{
    char name[32];//存储队员的姓名,字符串
    int age;//存储学生的年龄
}team_t;//使用typedef关键字给struct team数据类型起别名叫做team_t,以后就把team_t当做int来看

int main(void){
    //使用新的数据类型来定义变量
    team_t team1 = {"dagu", 22};//类比int team1
    //定义结构体类型变量的指针pteam指向team1
    team_t* pteam = &team1;//pteam保存team1的首地址,类比int* pteam = &team1;
    
    //打印队员信息
    printf("%s, %d\n", team1.name, team1.age);
    printf("%s, %d\n", pteam -> name, pteam -> age);//通过指针变量访问成员语法:指针变量 -> 成员
    
    team1.age++;//修改age年龄
    strcpy(pteam -> name, "dijia");//修改name成员
    
    //打印队员信息
    printf("%s, %d\n", team1.name, team1.age);
    printf("%s, %d\n", pteam -> name, pteam -> age);
    return 0;
}

结构体数组

#include <stdio.h>
#include <string.h>

struct team{
    char name[32];
    int age;
};

typedef struct team team_t;

int main(void){
    //定义初始化三个队员信息的结构体数组
    team_t team_info[3] = {
        {.age = 22, .name = "大古"},
        {.age = 21, .name = "丽娜"},
        {.age = 20, .name = "新城"}
    };
    int size = sizeof(team_info)/sizeof(team_info[0]);
    for(int i = 0; i < size; i++){
        printf("%s:%d\n", team_info[i].name, team_info[i].age);
    }
    for(int i = 0; i < size; i++){
        team_info[i].age++;
    }
    for(int i = 0; i < size; i++){
        printf("%s:%d\n", team_info[i].name, team_info[i].age);
    }
    
    return 0;
}

结构体和函数

#include <stdio.h>

struct team{
    char name[32];
    int age;
};
typedef struct team team_t;

void show(team_t tm){//tm = t1
    printf("%s:%d\n", tm.name, tm.age);
}
void grow(team_t tm){//tm = t1,修改的是tm的age,并没有修改实参t1的值
    tm.age++;//年龄加一岁
}
void show_p(const team_t* pteam){//pteam = &t1
    printf("%s:%d\n", pteam -> name, pteam -> age);
}
void grow_p(team_t* pteam){//pteam = &t1
    pteam -> age++;//pteam直接修改了实参t1的值
}

team_t get_team_info(void){
    team_t t2 = {"juejing", 19};//局部结构体变量
    return t2;//返回局部结构体变量的值
}

team_t* get_team_info_p(void){
    team_t t3 = {"juejing", 100};//局部结构体变量
    return &t3;//返回局部变量的地址,不行,返回的就是一个野指针/NULL
}

int main(void){
    team_t t1 = {"野瑞", 18};
    show(t1);//传递实参结构体变量t1
    grow(t1);//传递实参结构体变量t1
    show(t1);//传递实参结构体变量t1
    show_p(&t1);//传递实参结构体变量t1的地址
    grow_p(&t1);
    show_p(&t1);//传递实参结构体变量t1的地址
    
    team_t team = get_team_info();//team保存函数的返回值
    printf("%s:%d\n", team.name, team.age);
    team_t* pteam = get_team_info_p();//pteam保存函数返回的结构体指针
    printf("%s:%d\n", pteam -> name, pteam -> age);
    
    return 0;
}

结构体嵌套

#include <stdio.h>
#include <string.h>

typedef struct birthday{
    int year;
    int month;
    int day;
}birth_t;

typedef struct team{
    char name[32];
    int age;
    birth_t birth;//嵌套birth_t结构体变量来存储队员的出生日期
}team_t;

int main(void){
    //定义结构体变量t1嵌套的birth变量也会自动分配好并且初始化好
    team_t t1 = {"大古", 22, {2000, 1, 9}};
    team_t* pt1 = &t1;//pt1指向t1
    
    printf("%s,%d,%d-%d-%d\n", t1.name, t1.age, t1.birth.year, t1.birth.month, t1.birth.day);
    printf("%s,%d,%d-%d-%d\n", pt1 -> name, pt1 -> age, pt1 -> birth.year, pt1 -> birth.month, pt1 -> birth.day);
    
    //修改
    t1.age++;
    pt1 -> birth.year = 1999;
    
    printf("%s,%d,%d-%d-%d\n", t1.name, t1.age, t1.birth.year, t1.birth.month, t1.birth.day);
    printf("%s,%d,%d-%d-%d\n", pt1 -> name, pt1 -> age, pt1 -> birth.year, pt1 -> birth.month, pt1 -> birth.day);
    
    return 0;
}

嵌套结构体指针

#include <stdio.h>
#include <string.h>

typedef struct birthday{
    int year;
    int month;
    int day;
}birth_t;

typedef struct team{
    char name[32];
    int age;
    birth_t* pbirth;//嵌套birth_t结构体指针指向存储学生的出生日期变量的地址
}team_t;

int main(void){
    //定义结构体变量t1嵌套的birth变量也会自动分配好并且初始化好
    team_t t1 = {"大古", 22, NULL};
    team_t* pt1 = &t1;//pt1指向了t1
    //定义结构体变量birth来存储大古队员的出生日期
    birth_t birth = {2000, 1, 9};
    //给大古队员关联出生的日期,此时pbirth指向了一个有效内存
    t1.pbirth = &birth;
    
    //打印
    printf("%s,%d,%d-%d-%d\n", t1.name, t1.age, t1.pbirth -> year, t1.pbirth -> month, t1.pbirth -> day);
    printf("%s,%d,%d-%d-%d\n", pt1 -> name, pt1 -> age, pt1 -> pbirth -> year, pt1 -> pbirth -> month, pt1 -> pbirth -> day);
    
    //修改
    t1.age++;
    pt1 -> pbirth ->year = 2001;
    
    //打印
    printf("%s,%d,%d-%d-%d\n", t1.name, t1.age, t1.pbirth -> year, t1.pbirth -> month, t1.pbirth -> day);
    printf("%s,%d,%d-%d-%d\n", pt1 -> name, pt1 -> age, pt1 -> pbirth -> year, pt1 -> pbirth -> month, pt1 -> pbirth -> day);
    
    return 0;
}