结构体相关知识

引言

  在用C语言解决问题的过程中,我们常会遇到如何用一个变量去表示它的性质、内容等,例如,在表示学生时,我们常会对其的姓名、年龄、成绩等进行规定,于是我们规定,在C语言中,用struct类型去表示“学生”,即结构体。

结构体声明

声明

struct tag
{
    member-list;
}variable-list;

  举例:一个学生,包含年龄、姓名、学号(成员变量)等内容,可以将其如下所示定义

struct Stu
{
    char name[20];
    int age;
    char id[20];
};

创建与初始化

  如图,即是一个结构体的创建和初始化

struct Stu s={"18","张三","20231131051"};

  此外,也可以打乱顺序初始化,如

struct Stu s={.age=18,.name="张三",.id="20231131051"};

结构体成员变量的访问

  在上述示例中,对结构体s中的成员变量进行访问有两种方式,分别如下所示

1.
s.age
s.name
s.id
//以上是C语言结构体对成员变量的直接访问
2.
定义一个指针,struct Stu *p=&s;
此时访问方式为p->age

  注意,此时的p是结构体指针,类型为struct Stu *

结构特殊声明

  在实际应用,我们常会遇到结构体对象名称不明确的情况,这种时候,我们可以对结构体进行匿名声明

struct 
{
    int a;
    int b;
    int c;
}s;

  注意,在对结构体进行匿名声明的时候,编译器会认为此匿名变量与另一个匿名变量不是同一数据类型,要再次使用的话,需要用typedef来重新命名

结构体自引用

  类似于数据结构中的链表,我们可以使用结构体来模拟实现,如下 

struct Stu
{
    int data;
    struct Stu* next;
}

  结构体内存对齐

对齐规则

1.第一个成员对齐到和结构体变量起始位置偏移量为0的地址处

2.其他成员变量对齐到对齐数的整数倍的地址处(对齐数:编译器默认的一个对齐数与该成员变量大小的较小值)

3.结构体大小为最大对齐数的整数倍

4.若嵌套结构体,则结构体成员对齐到自己的成员中最大对齐数的整数倍处,结构体整体大小就是所有最大对齐数的整数倍。

修改默认对齐数

  可以使用#pragma这个预处理指令来改变编译器的默认对齐数,如#pragma pack(1)将默认对齐数修改为1

结构体传参

在将结构体作为参数传递给一个函数时,我们会有两种传参模式,即传值和传址

void print1(struct S s);
//
VOID PRINT2(struct S* p); 

  事实上,在结构体传参的时候,我们首选传址的方式,因为函数传参时,传参数会压栈,会造成额外的系统开销,故不采用。

位段

介绍

  位段与结构体类似,主要有两点不同:1.位段的成员必须是int、unsigned int、signed int三种(C99中除外);2.位段的成员名后有一个冒号和一个数字,数字代表其占几个比特位。

struct A
{
    int _a:2;
    int _b:5;
    int _c:10;
    int _d:30;
};

  上述位段的大小为8个字节,计算过程:首先,由于是int型,分配四个字节,可存32位,a,b,c存完之后再分配四个字节,总共八字节。

  注意点:位段不可跨平台使用,因此不适用于可移植代码。

应用

  网际协议中IP数据报,多个属性可用几个比特位描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值