欢迎光临
我们一直在努力

【2个月 C 语言从入门到精通:零基础系统教程】第十四讲:⾃定义类型:结构体

文章目录

    • 📖 前言
  • 1. 结构体类型的声明与定义
    • 1.1 结构体基本概念与声明语法
    • 1.2 结构体变量的创建和初始化
      • 1.2.1 按照结构体成员定义的顺序初始化(最常用)
      • 1.2.2 按照指定顺序初始化(C99标准支持)
    • 1.3 结构体的特殊声明(匿名结构体)
    • 1.4 结构的自引用(链表节点的实现)
      • 1.4.1 错误的示范
      • 1.4.2 正确的自引用(包含自身类型指针)
      • 1.4.3 结合 typedef 重命名的典型陷阱与解决方案
  • 2. 结构体内存对齐
    • 2.1 结构体内存对齐规则
      • 核心对齐规则
      • 详细代码示例与内存计算过程
        • 练习1:对比 S1 与 S2(成员顺序影响大小)
        • 练习2:带有 double 的 S3 与结构体嵌套 S4
    • 2.2 为什么存在内存对齐?
    • 2.3 修改默认对齐数 (#pragma pack)
      • 详细代码示例:
    • 2.4 结构体传参
      • 详细代码示例:
    • 3.1 什么是位段(定义与语法)
      • 代码示例与经典面试题
    • 3.2 位段的内存分配
      • 详细代码示例与内存解析
    • 3.3 位段的跨平台问题(重点规避)
    • 3.4 位段的应用(网络协议实践)
    • 3.5 位段使用的注意事项(& 地址符限制)
    • 🎯 总结
      • 一、结构体基础
      • 二、内存对齐机制
      • 三、传参优化
      • 四、位段技术
      • 关键要点回顾

📖 前言

在C语言编程中,结构体(Struct)是一种非常重要的复合数据类型,它允许我们将不同类型的数据组合成一个整体。无论是开发操作系统、数据库系统,还是进行嵌入式开发,结构体都扮演着至关重要的角色。然而,结构体的使用并非简单的成员组合,其中涉及内存对齐、传参效率、位段优化等深层次概念,这些正是许多C语言学习者和开发者容易忽视或理解不透彻的地方。

本文将从结构体的基础声明开始,逐步深入到内存对齐原理、传参优化策略,最后探讨位段这一特殊用法。通过详细的代码示例和内存布局分析,帮助读者全面掌握结构体的核心知识点,理解底层内存机制,并学会在实际项目中合理运用结构体优化程序性能。

无论你是C语言初学者,还是有一定经验的开发者,相信本文都能为你提供有价值的参考和启发。


1. 结构体类型的声明与定义

1.1 结构体基本概念与声明语法

结构体(Struct)是一些值的集合,这些值被称为成员变量。结构体的每个成员可以是不同类型的变量(如整型、字符、数组,甚至其他结构体)。

基本声明语法格式:

struct tag // 结构体标签(Tag)
{


memberlist; // 成员变量列表
} variablelist; // 变量列表(可在此处直接创建变量,也可省略)

⚠️ 关键注意点: member-list 右大括号 } 后面的分号绝对不能丢,否则编译器会报错。

示例(描述一个学生):

struct Stu
{


char name[20]; // 名字
int age; // 年龄
char sex[5]; // 性别
char id[20]; // 学号
}; // 这里的分号至关重要

1.2 结构体变量的创建和初始化

结构体类型相当于\”图纸\”,真正使用需要创建变量并赋值。C语言提供了两种主流的初始化方式。

1.2.1 按照结构体成员定义的顺序初始化(最常用)

直接在大括号 {} 中按成员定义的顺序填入初值。要注意数据类型要匹配,字符数组需要给字符串字面量。

#include <stdio.h>

// 假设上方已定义 struct Stu
int main()
{


// 顺序初始化:按 name -> age -> sex -> id 的顺序给值
struct Stu s1 = {

\”张三\”, 20, \”男\”, \”20230818001\” };

printf(\”name: %s\\n\”, s1.name);
printf(\”age : %d\\n\”, s1.age);
printf(\”sex : %s\\n\”, s1.sex);
printf(\”id : %s\\n\”, s1.id);

return 0;
}

1.2.2 按照指定顺序初始化(C99标准支持)

利用 .成员名 = 值 的语法,可以打乱顺序进行初始化。未被指定的成员会自动被初始化为0(或空指针、空字符)。

int main()
{


// 指定初始化:不仅打乱了顺序,还省略了部分字段
struct Stu s2 = {

.age = 18, .name = \”李四\”, .id = \”20230818002\” };
// 此时 s2.sex 未被赋值,由于是全局/局部静态或本地初始化,会被自动初始化为空字符串 \”\\0\”

printf(\”name: %s\\n\”, s2.name); // 输出: 李四
printf(\”age : %d\\n\”, s2.age); // 输出: 18
printf(\”sex : %s\\n\”, s2.sex); // 输出: (空)
printf(\”id : %s\\n\”, s2.id); // 输出: 20230818002

return 0;
}

1.3 结构体的特殊声明(匿名结构体)

如果我们在声明结构体时省略了结构体标签(tag),这就是匿名结构体。

示例定义:

// 匿名结构体类型 x
struct
{


int a;
char b;
float c;
} x;

// 另一个看起来一模一样的匿名结构体类型,创建了数组 a 和指针 p
struct

赞(0)
未经允许不得转载:171主机测评 » 【2个月 C 语言从入门到精通:零基础系统教程】第十四讲:⾃定义类型:结构体
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址