超详解结构体

本文详细介绍了C语言中的结构体,包括结构体的声明方式、特殊声明、创建与初始化、使用typedef的便利性,以及结构体成员的访问操作符。还讨论了结构体的内存对齐规则和过程。
摘要由CSDN通过智能技术生成

前言:

        若我们想要定义一个学生,我们需要得到他\她的名字、 性别、身高等等,那我们之前学的单单char类型int类型就不够用了,为了使一个变量可以有多个类型,就有了结构体。


一.结构体的声明

   1.结构体的一般声明

        例如我们要描述一个学生:

struct STU
{
    char name[20];//名字
    char sex[5];//性别
    double height;//身高
}stu;//注意:这里要打分号

        struct是结构体的关键字;

        STU是自定义的结构体标签名;

        struct STU是结构体类型;

        stu是自定义的变量名;

        {}里放的是结构体成员;

        注:结构体必须要以分号( ; )结尾

   2.结构体的特殊声明 

        前面结构体的声明有自定义类型结构体标签名,若没有它确实就是一个结构体的特殊申明。

struct
{
    char name[20];
    char sex[5];
    double height;
}stu;

struct STU
{
    char name[20];
    char sex[5];
    double height;
}*p;

int main()
{
    *p = &stu//这样的代码可以吗?
    return 0;
}

        编译器会把上⾯的两个声明当成完全不同的两个类型,所以是⾮法的。
        匿名的结构体类型,如果没有对结构体类型重命名的话,基本上只能使⽤⼀次。


二.结构体的创建和初始化

   1.结构体的一般创建

struct STU
{
    char name[20];//名字
    char sex[5];//性别
    double height;//身高
};

int main()
{

    struct STU stu1 = {"张三" , "男" , 175};//初始化stu1
    printf("%s %s %lf", stu1.name, stu1.sex,stu1.height);打印stu1

    struct STU stu2 = {.sex = "男", .name = "李四", .height = 180};//初始化stu2
    printf("%s %s %lf", stu1.name, stu1.sex,stu1.height);打印stu2
    
    struct STU stu3[2]={{"王五","女",165},{"赵六","男",177}};//可以用数组来创建多个结构体

    return 0;
}

        这里有两种方法初始化结构体成员。


   2.typedefy的运用

        我们每次创建结构体都要写结构体类型 + 变量名,确实有更加方便的写法——用typedefy。

typedeyf struct STU
{
    char name[20];//名字
    char sex[5];//性别
    double height;//身高
}S;

int main()
{
    S s ={ 0 };//初始化结构体
    return 0;
}

三.结构体的访问操作符

        如果我们要修改结构体里的成员,那我们该如何访问呢?

        我们这里有两种方法:

1.用 . 通过结构体变量名直接访问结构体成员。

2.用 -> 通过结构体变量名的地址来访问结构体成员。

struct STU
{
	char name[20];//名字
	char sex[5];//性别
	double height;//身高
};

int main()
{
	struct STU stu1 = { 0 };
	struct STU stu2 = { 0 };
	struct STU* pstu = &stu2;

    //修改结构体成员
	scanf("%s %s %lf", stu1.name, stu1.sex, &stu1.height);//通过 . 来访问结构体成员
	scanf("%s %s %lf", pstu->name, pstu->sex, &pstu->height);//通过 -> 来访问结构体成员
    
    //打印结果
    printf("%s %s %lf", stu1.name, stu1.sex, stu1.height);
    printf("%s %s %lf", pstu->name, pstu->sex, pstu->height);
    
	return 0;
}

注意:修改和打印的时候格式字符串和参数类型要一致。


四.结构体的内存对齐

   1.结构体的内存对齐规则

1.结构体的第⼀个成员对⻬到和结构体变量起始位置偏移量为0的地址处
2.其他成员变量要对⻬到某个数字(对⻬数)的整数倍的地址处。
对⻬数编译器默认的⼀个对⻬数与该成员变量⼤⼩的较⼩值。
3.结构体总⼤⼩为最⼤对⻬数(结构体中每个成员变量都有⼀个对⻬数,所有对⻬数中最⼤的)的整数倍。
4.如果嵌套了结构体的情况,嵌套的结构体成员对⻬到⾃⼰的成员中最⼤对⻬数的整数倍处,结构体的整体⼤⼩就是所有最⼤对⻬数(含嵌套结构体中成员的对⻬数)的整数倍。


   2.结构体的内存对齐的过程

我们已经创建好了结构体,那我们创建的结构体的大小是多少?(为了方便运算改一下)

struct STU
{
	char name;//名字
	char sex;//性别
	double height;//身高
};

int main()
{
    int sz = sizeof(struct STU);//算出结构体的大小
    printf("%zd",sz);//打印

    return 0;
}

        这里的打印结果是:

         这里就是发生了结构体的内存对齐。细节过程如下:

        开始时第一个成员的对齐数是1占一个字节 ,第二个成员的对齐数是1占一个字节,第三个成员的对齐数是8,所以会跳过偏移量不是8的倍数的地址,最后结构体结构体总⼤⼩为最⼤对⻬数8的倍数。

  • 17
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值