C语言详解(六) - 结构体

2023-04-27 21:08:39 浏览数 (2)

前言

数组是一类具有相同类型变量的值的集合。结构体是一些值的集合,这些值也叫成员变量。成员变量可以是不同类型的变量。

1. 结构体类型声明

代码语言:javascript复制
struct tag{
    members_list;
}variable_list;

eg:

代码语言:javascript复制
//声明描述一本书的结构体类型
struct book{
    char name[20];//书名
    char author;//作者
    int price;//价格
    char press;//出版社
}b1,b2;//末尾的结构体变量定义不必一定写
代码语言:javascript复制
//声明描述一本书的结构体类型
struct book{
    char name[20];//书名
    char author;//作者
    int price;//价格
    char press;//出版社
};

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

2.1 定义

代码语言:javascript复制
#include <stdio.h>

//声明描述一本书的结构体类型
struct book{
    char name[20];//书名
    char author;//作者
    int price;//价格
    char press;//出版社
}b1;//定义结构体变量b1,全局变量

struct book b2;//定义结构体变量b2,全局变量

int main(){
    struct book b3;//定义结构体变量b3,全局变量
    return 0;
}

2.2 初始化

代码语言:javascript复制
#include <stdio.h>

//声明描述一本书的结构体类型
struct book{
    char name[20];//书名
    char author[20];//作者
    int price;//价格
    char press[20];//出版社
};


int main(){
    //完全初始化
    struct book b1 = {"shanhaijing", "yiming", "40", "dianzigongyechubanshe"};
    //不完全初始化
    struct book b2 = {"西游记"};
    return 0;
}
代码语言:javascript复制
//结构体嵌套初始化
#include <stdio.h>

struct birth{
    int year;
    int month;
    int day;
};

struct student{
    char name[20];
    char sex;
    char num[20];
    struct birth n;
};

int main{
    struct student s = {"sunwukog", 'm', "00000001", {0,2,12}};
    return 0;
}

3. 结构成员变量

结构成员的类型不必相同,可以是内置类型、数组、指针、另一个结构体类型。

4. 结构体成员的访问

4.1 圆点操作符

当引用结构体具体的某一个成员变量时可以借助圆点操作符.来实现。

代码语言:javascript复制
#include <stdio.h>

//声明描述一本书的结构体类型
struct book{
    char name[20];//书名
    char author[20];//作者
    int price;//价格
    char press[20];//出版社
};


int main(){
    struct book b1 = {"shanhaijing", "yiming", "40", "dianzigongye"};
    printf("%s %s %d %sn", b1.name, b1.author, b1.price, b1.press);
    
    return 0;
}

4.2 箭头操作符

当获得一个结构体的地址时,可以通过另一种形式:指向该结构体的指针与箭头操作符来访问该结构体具体的成员变量。

代码语言:javascript复制
#include <stdio.h>

//声明描述一本书的结构体类型
struct book {
    char name[20];//书名
    char author[20];//作者
    int price;//价格
    char press[20];//出版社
};


int main() {
    struct book b1 = { 0 };
    struct book* p = &b1;
    //数组名就是数组首元素的地址,不再需要取地址操作符
    scanf("%s %s %d %s", p->name, p->author, &p->price, p->press);
    //借助解引用操作符也可以实现
    printf("%s %s %d %sn", (*p).name, (*p).author, (*p).price, (*p).press);
    //相比解引用操作符来说更加简洁,达到的效果也完全相同
    printf("%s %s %d %sn", p->name, p->author, p->price, p->press);

    return 0;
}

5. 结构体传参

分为两种方式,把整个该结构体传递过去;把结构体的地址传递过去。

代码语言:javascript复制
#include <stdio.h>

void scanf1(struct book *p);
void printf1(struct book b);

struct book {
    char name[20];//书名
    char author[20];//作者
    int price;//价格
    char press[20];//出版社
};


int main() {
    struct book b1 = {0};
    //传入的是整个结构体
    scanf1(&b1);
    //传入的是结构体的地址
    printf1(b1);

    return 0;
}
//
void scanf1(struct book *p) {
    scanf("%s %s %d %s", p->name, p->author, &p->price, p->press);
}
//
void printf1(struct book b) {
    printf("%s %s %d %sn", b.name, b.author, b.price, b.press);
}

运行结果:

两种传参方式中传入结构体地址的方式比较灵活且占用内存空间较小,应为指针的大小要么是4字节要么是8字节,而一个结构体的大小可能非常大。 在函数传参时,参数要经过压栈处理,结构体较大时,压栈的系统开销也会比较大,性能便会有所下降。

6. 结束语

本节主要讲解了结构体的相关知识,包括结构体的声明、定义、初始化。另外讲了结构体成员的三种访问方法、结构体传递参数时一般传递地址,这样程序的效率会更高。

END

0 人点赞