【C语言】自定义类型1:结构体

good

文章目录

回顾结构体

(1)声明与创建

cpp 复制代码
struct Stu
{
    int age;
    char name[20];
}s1;//第一种方式
struct Stu s2 = {12, "liming" };//第2种方式

(2)初始化

​ 1,一般结构体

cpp 复制代码
struct Stu
{
    int age;
    char name[20];
}s1={ 14, "lisi"};//第一种方式
struct Stu s2 = {12, "liming" };//第2种方式
struct Stu s2 = {.name="zhangsan", .age=19 };//第3种方式:指定顺序

​ 2.嵌套结构体和结构体数组

cpp 复制代码
struct Score
{
    int math;
    int chinese;
}
struct Stu
{
    int age;
    char name[20];
    struct Score;
};

struct Stu n1={18,"lcj", {150,150}};
struct Stu n[2]={   {18,"lcj", {150,150}} ,{16,"ch",{140,149}}  };

(3)对应的操作符

​ 1.点:结构体变量可以用

​ 2.箭头:结构体指针可以用

(4)结构体传参

  • 尽量传指针

结构体新知识

(1)匿名结构体

  • 结构体声明的时候没有名字,只能通过前面说的第一种方式创建,也只能够实现一次创建
cpp 复制代码
struct
{
    int age;
    char name[20];
}s;

(2)结构体如何包含同种结构体

  • 不能通过直接包含同种结构体的方式
  • 应该包含同种结构体的指针

(3)结构体的对齐规则

  • 作用:提高内存访问效率,减少CPU访问内存的次数。
  1. 官方解释

  2. 我的理解:( 8是默认对齐数,'min(8字节,成员的字节大小)' 称为 每个成员的对齐数)

    1. 存放内存从0开始算,大小是字节,总内存(字节大小)是数字+1
    2. 第一个结构体成员放到0,后面的成员都要放到" 自己的对齐数 的倍数"的位置
      1. 比如,(第一个以外)int a只能存放在4,8,12这些位置
    3. 总大小必须为最大对齐数的倍数
      1. 比如,结构体中有char ,int,short,那么总大小必须是4字节的倍数
  3. 具体实例

      1. int n从0到3,char a从4到5,
      2. 最大对齐数是4,结构体总长度是4的倍数,因为要大于5,所以是8

(4)修改默认对齐数

  • #pragma pack(n) ------设置默认对⻬数为n
  • 示例:
      • char a从0到1,
      • int n的对齐数是min(2字节,成员的字节大小)=2,所以int n从2到5
      • 结构体总长度是2的倍数,所以是6

(5)结构体实现位段

1.是什么

  • 为了节省空间,结构体的一种特殊的创建方式
  • 能够修改结构体成员内存中占几个比特

2.条件

  • 只有int, unsigned int,signed int 和char可以实现
  • 想设置的比特数 得小于原比特数
    • 比如int4字节,32bit,设置的位段得小于32

3.形式

  • 创建结构体的时候,成员后面加上冒号和想设置的字节数

  • 示例:

    cpp 复制代码
    #include<stdio.h>
    struct S
    {
        char a : 3;
        char b : 3;
        char c : 5;
        char d : 6;
    };
    int main()
    {
        struct S s;
        s.a = 11;
        s.b = 5;
        s.c = 10;
        s.d = 8;
    
        printf("%zu\n", sizeof(s));//得到的结果是3
    
    	return 0;
    }

4.实现

  • vs中的实现:
    • 逐个字节(8bit)来分
    • 从一个字节的从右向左来放成员
    • 给同一个成员分配的bit都在同一字节
  • 示例:
    • 先分配1个字节00000000(8个bit)
      • 然后从右往左给a 3个bit,因为a的2进制是1011,只能放后3个
      • 放a后:00000011
      • 再从右向左给b 3 个bit,b的二进制为101,都放进去
      • 放b后:00101011
      • 内存:一个字节,8 bit,2个16进制位,0010变成2, 1011变成b
    • 现在第一个字节只剩下2个bit,而c需要5个bit,不够,再分配一个字节
      • 放c之前00101011 00000000
      • 从右往左给c 5个bit,c的二进制为1010,都放进去
      • 放c后:00101011 00001010
      • 内存:前方有2b,后面第二个字节,8 bit,2个16进制位,0000还是0, 1010变成a
    • 现在第二个字节只剩下3个bit,而d需要5个bit,不够,再分配一个字节
      • 放d之前00101011 00001010 00000000
      • 从右往左给s 6个bit,d的二进制为100,都放进去
      • 放d后:00101011 00001010 00000100
      • 内存:前方有2b 0a,后面第三个字节,8 bit,2个16进制位,0000还是0, 0100变成8

5.缺点

  • 不可移植
    • 从左往右放 还是从右往左放不确定
    • 大小端问题
    • 不同编译器布局不同
  • 不能取地址(地址是字节的编号,bit太小)
  • 调试困难
  • 不能传参,改变了类型的字节数,相当于改变了类型
  • 还是会浪费空间

字节,8 bit,2个16进制位,0000还是0, 0100变成8

相关推荐
We་ct11 分钟前
LeetCode 5. 最长回文子串:DP + 中心扩展
前端·javascript·算法·leetcode·typescript
JAVA面经实录9173 小时前
Java企业级工程化·终极完整版背诵手册(无遗漏、全覆盖、面试+落地通用)
java·开发语言·面试
王老师青少年编程4 小时前
csp信奥赛C++高频考点专项训练之贪心算法 --【哈夫曼贪心】:合并果子
c++·算法·贪心·csp·信奥赛·哈夫曼贪心·合并果子
周杰伦fans4 小时前
AutoCAD .NET 二次开发:深入理解 EntityJig 的工作原理与正确实现
开发语言·.net
叼烟扛炮5 小时前
C++第二讲:类和对象(上)
数据结构·c++·算法·类和对象·struct·实例化
天疆说5 小时前
【哈密顿力学】深入解读航天器交会最优控制中的Hamilton函数
人工智能·算法·机器学习
wuweijianlove6 小时前
关于算法设计中的代价函数优化与约束求解的技术7
算法
leoufung6 小时前
LeetCode 149: Max Points on a Line - 解题思路详解
算法·leetcode·职场和发展
样例过了就是过了6 小时前
LeetCode热题100 最长公共子序列
c++·算法·leetcode·动态规划
HXDGCL6 小时前
矩形环形导轨:自动化循环线的核心运动单元解析
运维·算法·自动化