C语言--一文读懂自定义类型之结构体

本文深入探讨C语言中的结构体,包括结构体的声明、引用、变量定义与初始化、内存对齐原理及应用。通过实例解析结构体自引用、结构体内的位段,并讨论结构体在内存分配和跨平台问题上的挑战。了解结构体和内存对齐对于优化C程序性能至关重要。
摘要由CSDN通过智能技术生成

笔者原博链接。

本章将涉及的内容有:

  • 结构体
    1. 结构体类型的声明
    2. 结构的自引用
    3. 结构体变量的定义和初始化
    4. 结构体内存对齐
    5. 结构体传参
    6. 结构体实现位段(位段的填充&可移植性)

结构体

初识结构体一文中我们已经简单了解过结构体了,这里将再次学习结构体并了解一些更加深入的内容。

1.1 什么是结构体?

结构体是C语言中一种重要的数据类型,该数据类型由一组称为成员(或称为域,或称为元素)的不同数据组成,其中每个成员可以具有不同的类型。结构体通常用来表示类型不同但是又相关的若干数据。其关键字为struct。

在C语言的实际使用中,我们有各种各样的数据类型,比如char类型、int类型等等,但是如果你要描述一个具有多种类型数据的事物时,那么我们只使用那些单个的数据类型是很困难的。

例如,描述一个学生,我们需要char类型的姓名,需要int类型的年龄,需要float类型的体重和身高。在这种情况下,结构体应运而生,它可以轻松的解决这种问题。

结构体本质上还是一种数据类型,但它可以包括若干个“成员”,每个成员的类型可以相同也可以不同,也可以是基本数据类型或者又是一个构造类型。

1.2 结构体的声明

如何声明一个结构体类型呢?

struct tag
{
   
     member-list;//可定义多种类型变量
}variable-list;//注意此处有分号
//variable-list是变量列表

注意,variable-list是变量列表,变量可以在声明时定义,也可以在用到时定义。结构体的定义和初始化稍后详细再讲。

举例声明一个具体的结构体:例如,声明一个结构体来描述学生。

struct Stu
{
   
     char name[20];//名字
     int age;//年龄
     char sex[5];//性别
     float height;//身高
}; //分号不能丢
声明时也可以不完全声明,比如省略结构体标签:
//匿名结构体类型
struct
{
   
     int a;
     char b;
     float c;
}x;
struct
{
   
     int a;
     char b;
     float c;
}a[20], *p;

//思考在上面代码的基础上,下面的代码是否合法:
p = &x;

//答案是不合法的,因为编译器会把上面的两个声明当成完全不同的两个类型。

当然,这种匿名结构体类型能不用就不用,因为这种结构体只能在它声明时定义变量使用一次,之后再想使用是无法定义变量的,因为没有标签。

1.3 结构体的引用

1.3.1 结构体内引用其他结构体

我们知道,结构体内部成员变量的类型是可以多种多样的,那么我们是否可以在结构体内部再定义结构体变量呢?例如:

struct A
{
   
    int x;
    char y;
};
struct B
{
   
    int a;
    struct A ba;
};

这样的结构体也是完全没问题的,结构体成员变量可以是结构体类型。

1.3.2 结构体自引用

既然结构体内引用其他结构体类型的成员变量可行,那么我们是否也可以在结构体内部再引用该结构体本身的变量呢?例如:

//这样的代码是否可行?
struct Node
{
   
 int data;
 struct Node next;
};

int main()
{
   
    struct Node s;
    printf("%d\n", sizeof(s));
    return 0;
}
答案是否定的,这样的使用将造成错误!试想如果这样定义了,当我们新定义一个该结构体变量:struct Node s;后,计算这个s的大小时会出现什么情况?会出现死递归的情况,一个结构体变量的大小怎么能是无限大呢?因此这种使用是错误的!

那么结构体是否能自引用呢?答案是肯定的,但是不能像上面一样引用

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值