打印
[软件资料]

结构体的声明与定义

[复制链接]
414|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
OKAKAKO|  楼主 | 2024-4-7 12:31 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

1、声明

结构体的声明使用struct关键字,如果我们想要把我们的学籍信息组织一下的话,可以这样表示:

struct Info
{
    unsigned long identifier;//学号,用无符号长整数表示
    char name[20];//名字,用字符数组表示
    unsigned int year;//入学年份,用无符号整数表示
    unsigned int years;//学制,用无符号整数表示
}

这样,我们就相当于描绘好了一个框架,以后要用的话直接定义一个这种类型的变量就好了。

2、定义
我们刚刚申请了一个名叫Info的结构体类型,那么理论上我们可以像声明其他变量的操作一样,去声明我们的结构体操作,但是C语言中规定,声明结构体变量的时候,struct关键字是不可少的。

struct 结构体类型名 结构体变量名


不过,你可以在某个函数里面定义:

#include <stdio.h>

struct Info
{
    unsigned long identifier;//学号,用无符号长整数表示
    char name[20];//名字,用字符数组表示
    unsigned int year;//入学年份,用无符号整数表示
    unsigned int years;//学制,用无符号整数表示
};

int main(void)
{
    /**
     *在main函数中声明结构体变量
     *结构体变量名叫info
     *struct关键字不能丢
     */
    struct Info info;
    ...
}


也可以在声明的时候就把变量名定义下来(此时这个变量是全局变量):


#include <stdio.h>

struct Info
{
    unsigned long identifier;//学号,用无符号长整数表示
    char name[20];//名字,用字符数组表示
    unsigned int year;//入学年份,用无符号整数表示
    unsigned int years;//学制,用无符号整数表示
} info;
/**
*此时直接定义了变量
*该变量是全局变量
*变量名叫info
*/

int main(void)
{
    ...
}

使用特权

评论回复
沙发
OKAKAKO|  楼主 | 2024-4-7 12:32 | 只看该作者

3、访问结构体成员

结构体成员的访问有点不同于以往的任何变量,它是采用点号运算符.来访问成员的。比如,info.name就是引用info结构体的name成员,是一个字符数组,而info.year则可以查到入学年份,是个无符号整型。

比如,下面开始录入学生的信息:

//Example 01
#include <stdio.h>

struct Info
{
    unsigned long identifier;//学号,用无符号长整数表示
    char name[20];//名字,用字符数组表示
    unsigned int year;//入学年份,用无符号整数表示
    unsigned int years;//学制,用无符号整数表示
};

int main(void)
{
    struct Info info;

    printf("请输入学生的学号:");
    scanf("%d", &info.identifier);
    printf("请输入学生的姓名:");
    scanf("%s", info.name);
    printf("请输入学生的入学年份:");
    scanf("%d", &info.year);
    printf("请输入学生的学制:");
    scanf("%d", &info.years);

    printf("\n数据录入完毕\n\n");

    printf("学号:%d\n姓名:%s\n入学年份:%d\n学制:%d\n毕业时间:%d\n", \
        info.identifier, info.name, info.year, info.years, info.year + info.years);
    return 0;
}

运行结果如下:

//Consequence 01
请输入学生的学号:20191101
请输入学生的姓名:Harris
请输入学生的入学年份:2019
请输入学生的学制:4

数据录入完毕

学号:20191101
姓名:Harris
入学年份:2019
学制:4
毕业时间:2023

使用特权

评论回复
板凳
OKAKAKO|  楼主 | 2024-4-7 12:33 | 只看该作者

4、初始化结构体
像数组一样,结构体也可以在定义的时候初始化,方法也几乎一样:

struct Info info = {
    20191101,
    "Harris",
    2019,
    4
};

在C99标准中,还支持给指定元素赋值(就像数组一样):

struct Info info = {
    .name = "Harris",
    .year = 2019
};

对于没有被初始化的成员,则「数值型」成员初始化为0,「字符型」成员初始化为‘\0’。

对齐
下面这个代码,大家来看看会发生什么:

//EXample 02 V1
#include <stdio.h>

int main(void)
{
    struct A
    {
        char a;
        int b;
        char c;
    } a = {'a', 10, 'o'};
   
    printf("size of a = %d\n", sizeof(a));
   
    return 0;
}

我们之前学过,char类型的变量占1字节,int类型的变量占4字节,那么这么一算,一个结构体A型的变量应该就是6字节了。别急,我们看运行结果:

//COnsequence 02 V1
size of a = 12

怎么变成12了呢?标准更新了?老师教错了?都不是。我们把代码改一下:

//EXample 02 V2
#include <stdio.h>

int main(void)
{
    struct A
    {
        char a;
        char c;
        int b;
    } a = {'a', 'o', 10};
   
    printf("size of a = %d\n", sizeof(a));
   
    return 0;
}

结果:

//Consequence 02 V2
size of a = 8

实际上,这是编译器对我们程序的一种优化——内存对齐。在第一个例子中,第一个和第三个成员是char类型是1个字节,而中间的int却有4个字节,为了对齐,两个char也占用了4个字节,于是就是12个字节。

而在第二个例子里面,前两个都是char,最后一个是int,那么前两个可以一起占用4个字节(实际只用2个,第一个例子也同理,只是为了访问速度更快,而不是为了扩展),最后的int占用4字节,合起来就是8个字节。

关于如何声明结构体来节省内存容量,可以阅读下面的这篇文章,作者是艾瑞克·雷蒙,时尚最具争议性的黑客之一,被公认为开源运动的主要领导者之一:

英文原版,中文版

使用特权

评论回复
地板
中国龙芯CDX| | 2024-4-10 11:08 | 只看该作者
结构体的声明与定义、初始化等操作非常重要

使用特权

评论回复
5
szt1993| | 2024-4-10 13:25 | 只看该作者
结构体的声明与定义很详细,适合新手学习

使用特权

评论回复
6
小夏天的大西瓜| | 2024-4-10 13:42 | 只看该作者
学籍信息的案例解释结构体非常清晰

使用特权

评论回复
7
jf101| | 2024-4-14 15:28 | 只看该作者
访问结构体成员这个是一般经常使用的

使用特权

评论回复
8
小小蚂蚁举千斤| | 2024-4-16 09:00 | 只看该作者
其实访问结构体大大提升了数据的完整性

使用特权

评论回复
9
OKAKAKO|  楼主 | 2024-4-19 18:48 | 只看该作者
结构体的声明使用struct关键字

使用特权

评论回复
10
星辰大海不退缩| | 2024-4-21 11:40 | 只看该作者
结构体成员的访问有点不同于以往的任何变量,它是采用点号运算符.来访问成员的。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

209

主题

1446

帖子

4

粉丝