C_结构体

发布于:2024-12-07 ⋅ 阅读:(147) ⋅ 点赞:(0)

1.结构体介绍

结构体是一种数据类型,叫结构体类型。

用结构体类型定义的变量叫结构体变量。

结构体变量可以同时存储不同类型的数据。

2.声明结构体类型

说明:
        结构体是一种构造数据类型,需要根据需求人为构造成员信息。

格式:

        struct 类型名
        {        
                成员1 数据类型 变量名;

                成员2 数据类型 变量名;

                成员3 数据类型 变量名;

                .

                .

                .

                成员n 数据类型 变量名;

             };

位置:

        放在.h文件中

        没有.h就放在全局位置

练习:

        声明一个可以存书的信息的结构体类型;

// 定义一个结构体类型来存储书籍信息
struct book

{
    char title[50];            // 书名
    char author[50];       // 作者
    char id[50];               // 书籍编号
    float pop;                  // 热度
    int stock;                  // 库存
    float price;                // 价格
};

3.定义结构体变量

用声明过多的结构体类型定义变量

格式:

1.用类型名定义

 结构体类型名 变量;

 struct book bk1;

2.声明结构体类型的同时定义结构体变量

struct 类型名

{

        成员1 数据类型 变量名;

        成员2 数据类型 变量名;

         .      

         .

         .

        成员n 数据类型 变量名;

}结构体变量名;

 (不建议用这种类型,因为结构体变量名的位置通常要用来写类型的别名,就是格式3)

3.重命名类型后用别名定义结构体变量

typedef struct 类型名

{

        成员1 数据类型 变量名;

        成员2 数据类型 变量名;

        .

        成员n 数据类型 变量名;

}类型的别名;

别名  结构体变量;

(常用)

#include <stdio.h>

typedef struct book
{
    char title[50];     // 书名
    char author[50];    // 作者
    char id[50];        // 书籍编号
    float pop;          // 热度
    int stock;          // 库存
    float price;        // 价格
} BOK;  // 结构体类型的别名 BOK

int main()
{
    struct book bk1;  // 格式1
    BOK bk2;          // 格式3

    return 0;
}

4.结构体变量初始化

整体使用{ }列表形式,需要注意的是列表中数据的类型一定要与结构体类型中成员的顺序一致,列表中,各个成员之间使用逗号间隔。

初始化不能跳跃式的初始化。

结构体变量也支持部分初始化,未被初始化的成员是 0。

结构体只能再定义的时候初始化。

#include <stdio.h>

typedef struct book
{
    char title[50];     // 书名
    char author[50];    // 作者
    char id[50];        // 书籍编号
    float pop;          // 热度
    int stock;          // 库存
    float price;        // 价格
} BOK;  // 结构体类型的别名 BOK

int main()
{
    // 初始化 bk1 使用格式1(结构体变量)
    struct book bk1 = {
        "C Programming",    // title
        "Dennis Ritchie",   // author
        "001",              // id
        4.5,                // pop
        10,                 // stock
        39.99               // price
    };

    // 初始化 bk2 使用格式3(typedef类型)
    BOK bk2 = {
        "Data Structures",  // title
        "Aaron",            // author
        "002",              // id
        4.8,                // pop
        20,                 // stock
        49.99               // price
    };

    return 0;
}

5.结构体成员访问

数组通过下标访问具体的元素,但结构体没有下标,结构体是通过成员名来访问具体成员的。

 格式:

结构体变名.成员名

 赋值:

bk1.title = "C语言";

如果有人尝试这样赋值,会发现程序会报错。

bk1.price = 29.99;

但这样的赋值是没有问题的。

这是因为title是一个字符数组,bk1.title是字符的首元素地址,将一个字符串赋值给地址肯定是不行的。正确的方法是:

strcpy(bk1.title,"C语言");

运用<string.h> 中的strcpy函数。

#include <stdio.h>
#include <string.h>
typedef struct book
{
    char title[50];     // 书名
    char author[50];    // 作者
    char id[50];        // 书籍编号
    float pop;          // 热度
    int stock;          // 库存
    float price;        // 价格
} BOK;  // 结构体类型的别名 BOK

int main()
{
    // 初始化 bk1 使用格式1(结构体变量)
    struct book bk1 = {
        "C Programming",    // title
        "Dennis Ritchie",   // author
        "001",              // id
        4.5,                // pop
        10,                 // stock
        39.99               // price
    };

    // 初始化 bk2 使用格式3(typedef类型)
    BOK bk2 = {
        "Data Structures",  // title
        "Aaron",            // author
        "002",              // id
        4.8,                // pop
        20,                 // stock
        49.99               // price
    };

    bk1.price = 29.99;
//    bk1.title = "C语言";    //错误的方法
    strcpy(bk1.title,"C语言");
    
    // 打印bk1和bk2的内容
    printf("Book 1: %s by %s\n ID: %s\n Popularity: %.2f\n Stock: %d\n Price: %.2f\n",
           bk1.title, bk1.author, bk1.id, bk1.pop, bk1.stock, bk1.price);
    printf("Book 2: %s by %s\n ID: %s\n Popularity: %.2f\n Stock: %d\n Price: %.2f\n",
           bk2.title, bk2.author, bk2.id, bk2.pop, bk2.stock, bk2.price);

    return 0;
}

思考:

        如何把一个结构体变量的信息复制给另一个结构体变量?

很简单,直接复制,如:

bk2 = bk1;    //成员信息一一复制

但2个结构体变量的类型要相同。而且这种赋值方式仅适用于没有指针成员或动态分配内存的情况。如果结构体中包含指针成员,复制时仅会复制指针的值,而不会复制指针所指向的内容,这可能会导致问题。

6.结构体指针

关于结构体与指针的内容在这里不讲,有需要的看这==》C与指针

7.结构体数组

如果要存储100本书的信息,如果不用结构体数组,就需要定义100个结构体变量,每个变量都需要单独命名并赋值,这样的做法不仅麻烦,而且代码冗长且难以管理。而使用结构体数组后,只需定义一个数组,数组的每个元素都是一个结构体,代表一本书的信息,这样可以有效减少代码量,便于访问和操作。

所以,

结构体数组非常适用于存储大量相同类型数据的场景。

定义一个结构体数组也非常简单:

BOK bks[100];

 结构体数组的初始化也和其它类型的数组一样:(但一般不会初始化结构体数组)

BOK bks[100] = {  { "C Programming", "Dennis Ritchie", "001", 4.5, 10, 39.99},

                              {"Data Structures",  "Aaron",  "002", 4.8, 20, 49.99 },

                              {    } 

                           };

对结构体数组的元素访问: 

1.通过下标访问:

bks[i].title

bks[i].price

 2.通过数组名访问:

数组名代表数组首元素的地址

通过数组名到元素:

bks+i           //某个元素的地址

*(bks+i)        //某个元素

*(bks+2) = *(bks+3)

 通过元素到具体成员:

(bks+i)->title           //*(bks+i).name

(bks+i)->price

这个符号:                ->                不懂的点上面那个链接去看,里面有讲。

3.通过指针访问:

定义一个结构体指针,指向结构体数组的首元素地址

通过指针到元素:

BOK bks[100];

BOK *f;

f = bks;

f+i;                //i号元素的地址

f++;               //下一个元素的地址(指针偏移)

*(f+2) = *(f+3)

 通过元素到具体成员:

(f+i)->name

(f+i)->hot

8.结构体的使用场景 

①要想存储多个数据类型的数据放在一个整体,用结构体变量存储处理或多个数据类型的数据要统一处理

②子函数中有两个数据要返回,int 和 float

方案1:地址传递(父亲函数中的变量参与到子函数中)

方案2:子函数定义一个结构体变量,结构体变量有两个成员(int 和 float)

           函数返回一个结构体变量.函数返回值是结构体类型.

           调用的时候用一个结构体变量接收

练习:

1.

定义一个3个元素的结构体数组(书的类型),对每个元素信息手动输入

然后打印。

2.

用户在子函数定义一个整型变量,定义一个实型变量.

要求通过返回值的形式将两个数据返回.

在主函数中打印.

1.

#include <stdio.h>
#include <stdlib.h>

typedef struct book
{
    char title[50];     // 书名
    char author[50];    // 作者
    char id[50];        // 书籍编号
    float pop;          // 热度
    int stock;          // 库存
    float price;        // 价格
} BOK;  // 结构体类型的别名 BOK

// 清理输入缓冲区
void clear_input_buffer() {
    char ch;
    while ((ch = getchar()) != '\n' && ch != EOF);  // 清除直到换行符或文件结束符
}

int main()
{
    BOK bks[3];
    int i;
    for(i = 0; i < 3; i++)
    {
        printf("请输入第%d本书的信息:\n", i+1);

        printf("书名: ");
        fgets(bks[i].title, sizeof(bks[i].title), stdin);
        bks[i].title[strcspn(bks[i].title, "\n")] = '\0'; // 去掉末尾的换行符

        printf("作者: ");
        fgets(bks[i].author, sizeof(bks[i].author), stdin);
        bks[i].author[strcspn(bks[i].author, "\n")] = '\0'; // 去掉末尾的换行符

        printf("id: ");
        fgets(bks[i].id, sizeof(bks[i].id), stdin);
        bks[i].id[strcspn(bks[i].id, "\n")] = '\0'; // 去掉末尾的换行符

        printf("热度: ");
        scanf("%f", &bks[i].pop);
        clear_input_buffer(); // 清除缓冲区换行符

        printf("库存: ");
        scanf("%d", &bks[i].stock);
        clear_input_buffer(); // 清除缓冲区换行符

        printf("价格: ");
        scanf("%f", &bks[i].price);
        clear_input_buffer(); // 清除缓冲区换行符

        system("cls");
    }
    for(i = 0;i < 3;i++)
    {
        printf("第%d本书:\n 书名:%s\n 作者:%s\n 书籍编号:%s\n 热度:%.1f\n 库存:%d\n 价格:%.2f\n",
               i+1,(bks+i)->title,(bks+i)->author,(bks+i)->id,(bks+i)->pop,(bks+i)->stock,(bks+i)->price);
    }
    return 0;
}

2.

#include <stdio.h>


typedef struct
{
    int a;
    float b;
}Date;

Date rec(void);

int main()
{
    Date val;
    val = rec();
    printf("输入的整数为:%d\n输入的浮点数为:%.2f",val.a,val.b);

    return 0;
}

Date rec(void)
{
    Date date;
    printf("请输入一个整数:\n");
    scanf("%d",&date.a);
    printf("请输入一个浮点数:\n");
    scanf("%f",&date.b);

    return date;
}


网站公告

今日签到

点亮在社区的每一天
去签到