找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

4959

积分

0

好友

695

主题
发表于 3 天前 | 查看: 16| 回复: 0

结构体是C语言中组织和管理相关数据的核心工具,尤其在嵌入式开发中,它对于定义硬件寄存器、封装协议帧或构建复杂数据结构至关重要。本文将系统性地讲解结构体的定义、使用技巧及其在嵌入式场景下的常见应用。

定义结构体变量

定义一个结构体,本质上是创建了一种新的复合数据类型。例如,我们可以定义一个表示人员信息的结构体:

struct string
{
    char name[8];
    int age;
    char sex[2];
    char depart[20];
    float wage1, wage2, wage3, wage4, wage5;
}person;

这段代码定义了一个名为 string 的结构体类型,并同时声明了一个该类型的变量 person

另一种常见的做法是将类型定义和变量声明分开,这样可以提高代码的清晰度和复用性:

struct string
{
    char name[8];
    int age;
    char sex[2];
    char depart[20];
    float wage1, wage2, wage3, wage4, wage5;
};
struct string person; // 使用已定义的结构体类型来声明变量 person

如果需要声明多个同类型的变量,可以一次性完成:

struct string Liming, Liuqi, ...;

在某些情况下,特别是当结构体仅在一个局部范围内(如某个函数内部)使用时,可以省略结构体名,定义所谓的“无名结构体”:

struct
{
    char name[8];
    int age;
    char sex[2];
    char depart[20];
    float wage1, wage2, wage3, wage4, wage5;
} Liming, Liuqi;

此时,变量 LimingLiuqi 的类型就是这个无名结构体,无法在其他地方复用此类型声明新的变量。

结构体成员的获取与赋值

定义了结构体变量后,如何访问其内部的成员呢?访问方式遵循以下格式:

结构变量.成员名

我们可以将 结构变量.成员名 视为一个整体,其使用方式与普通变量无异。下面通过一个简单的例子来演示:

#include <stdio.h>
int main()
{
    struct
    {
        char *name;  //姓名
        int age;     //年龄
        char group;  //所在小组
    } stu1;
    //给结构体成员赋值
    stu1.name = “Tom”;
    stu1.age = 18;
    stu1.group = ‘A’;
    //读取结构体成员的值
    printf(“%s的年龄是%d,在%c组\n”, stu1.name, stu1.age, stu1.group);
    return 0;
}

对于C语言初学者而言,熟练运用指针是进阶的关键,这在处理结构体时同样重要。

结构体数组

当需要管理一组具有相同结构的数据时,结构体数组便派上了用场。例如,要存储一个班级40名学生的信息,可以这样定义:

struct
{
    char name[8];
    char sex[2];
    int age;
    char addr[40];
}student[40];

访问结构体数组成员,需要先指定数组元素,再访问其成员:

结构数组元素.成员名

例如:

student[0].name
student[30].age

结构体指针

使用指针操作结构体可以提升效率,尤其是在传递大型结构体给函数时。结构体指针的定义方式是在结构体变量名前加 * 操作符:

struct string
{
    char name[8];
    char sex[2];
    int age;
    char addr[40];
}*student;

结构体指针访问成员时,使用 -> 操作符,这与普通结构体变量使用 . 操作符不同:

结构体指针名->结构体成员

例如,为上面定义的 student 指针所指向的结构体成员赋值:

strcpy(student->name, “acket”); // student->name 等价于 (*student).name
student->age = 18;

关键点:在通过指针访问结构体之前,必须确保指针指向有效的内存区域。通常需要为结构体指针动态分配内存:

student = (struct string*)malloc(size of (struct string));
// size of (struct string) 用于自动获取该结构体类型占用的字节长度

malloc() 函数会分配一块大小为结构体长度的内存,并将其起始地址作为结构体指针返回。在嵌入式系统中,动态内存分配需谨慎使用,有时会采用静态或栈上分配来保证确定性。

位结构(位域)

位结构是一种特殊形式的结构体,用于精确控制每个成员占用的内存位数,常用于访问硬件寄存器或进行紧凑的数据打包。其定义形式如下:

struct 位结构名
{
    数据类型 变量名: 整型常数;
    数据类型 变量名: 整型常数;
}位结构变量;

其中,数据类型必须是 intunsignedsigned),但当成员长度为1时,会被默认为 unsigned。整型常数表示该成员占用的二进制位数,范围是0~15。

看一个具体的例子,这个位结构描述了一个可能用于显示控制的字节:

struct
{
    unsigned incon: 8;    /* incon 占用低字节的0~7共8位 */
    unsigned txcolor: 4;  /* txcolor 占用高字节的0~3位共4位 */
    unsigned bgcolor: 3;  /* bgcolor 占用高字节的4~6位共3位 */
    unsigned blink: 1;    /* blink 占用高字节的第7位 */
}ch;

访问位结构成员的方式与普通结构体相同:

ch.bgcolor

位结构在嵌入式系统编程中非常实用。例如,可以定义一个包含状态标志的结构体:

struct info
{
    char name[8];
    int age;
    struct address addr;
    unsigned char state:1;  // 状态标志,1位
    unsigned char payyyy:1; // 工资发放标志,1位
}people;

这里,statepayyyy 各用1位来表示布尔状态,极大地节省了存储空间。

使用 typedef 定义结构体

typedef 关键字可以为现有的类型(包括结构体)创建一个新的别名,这能简化代码书写,增强可读性。

typedef struct person
{
    int age ;
    char *name;
    char *sex;
}student;
student stu1; // 现在可以使用别名 `student` 来定义结构体变量了

在上面的例子中,typedefstruct person 创建了别名 student。之后,就可以像使用内置类型一样使用 student 来声明变量,无需再写 struct 关键字。

总结

结构体是C语言构建复杂数据模型的基石。从基础的定义与访问,到数组、指针的高效操作,再到位域的精打细算和 typedef 带来的代码优雅,掌握这些知识点对于进行嵌入式开发至关重要。希望本文的梳理能帮助你更扎实地理解并运用结构体,写出更清晰、更高效的C语言代码。如果想进一步探讨或查看更多技术干货,欢迎访问云栈社区




上一篇:嵌入式C语言结构体详解:定义、内存对齐与位域实战
下一篇:C语言不完全类型:隐藏结构体细节,实现模块化封装
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-4-5 18:44 , Processed in 0.543817 second(s), 42 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表