【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

相关推荐
jaysee-sjc4 小时前
十七、Java 高级技术入门全解:JUnit、反射、注解、动态代理
java·开发语言·算法·junit·intellij-idea
yongui478344 小时前
MATLAB模糊控制的粒子群算法(Fuzzy-PSO)实现
数据结构·算法·matlab
sali-tec4 小时前
C# 基于OpenCv的视觉工作流-章49-人脸检测
图像处理·人工智能·opencv·算法·计算机视觉
不爱吃炸鸡柳4 小时前
4道经典算法题代码详解:从两数之和到链表两两交换
算法·链表·哈希算法
cmpxr_4 小时前
【C】隐式类型转换
c语言·c++·算法
泛凡(Linyongui)4 小时前
PY32F002B实践之三--宠物腹背理疗仪项目功能代码分析说明
c语言·keil·32位单片机·腹背理疗仪项目实践·普苒py32
W23035765734 小时前
【C++ 高性能日志系统实战】第三篇:异步日志系统的实现与优化
网络·数据结构·算法·日志
Dxy12393102164 小时前
Python使用SymSpell详解:打造极速拼写检查引擎
开发语言·python