关于结构体

一、结构体类型声明

C语言有int,char等关键字声明数据类型,同样的,结构体也可以声明一个结构体类型。

1、定义,声明和使用:

(1)第一种

如下:

struct example //定义一个结构体(关键字+结构体名)
{
  int a;
  char b;
};

int main(void)
{
  struct example S;//声明一个结构体类型变量S
  struct example *pS = &S;//声明一个结构体指针变量
  S.a   = 1;//访问结构体变量访问内部成员
  pS->b = 2;//通过结构体指针访问内部成员
//PS:变量使用.访问内部成员,指针用->访问
  return 0;
}

(2)第二种

相对于第一种,稍微有点改变,如下:

struct example //定义一个结构体(关键字+结构体名)
{
  int a;
  char b;
}S ,*p;//这里把定义的变量和指针都放在结构体尾部

int main(void)
{
  //下面直接调用就行了
  S.a   = 1;//访问结构体变量访问内部成员
  pS->b = 2;//通过结构体指针访问内部成员
//PS:变量使用.访问内部成员,指针用->访问
  return 0;
}

(2)第三种

使用typedef关键字声明,也是我做项目最常用的一种,如下:

//定义一个结构体(typedef+结构体类型关键字),这里的example其实可以省略
typedef struct example
{
  int a;
  char b;
}example_s;//意思是把struct example替换成为了example_s

//定义了一个结构体变量S,等价于struct example S
example_s S;

//定义了一个结构体指针变量pS ,等价于struct example *pS
example_s *pS = &S;

int main(void)
{
  //下面直接调用就行了
  S.a   = 1;//访问结构体变量访问内部成员
  pS->b = 2;//通过结构体指针访问内部成员
//PS:变量使用.访问内部成员,指针用->访问
  return 0;
}

二、关于结构体位域

位域的使用,极大方便了一些领域的开发,像单片机内存有限,内部使用的某些标志位只需要一个位,这时候就可以使用位域来节省内存的使用。

1:数据的大小不能超过声明的位宽值

例如:

unsigned char i:1 声明的是1个bit,所能表示的数据范围是0-1
unsigned char j:2 声明的是2个bit,所能表示的数据范围是0-3

并且声明的位数不能超过该数据类型所表示的宽度, 例如:

unsigned char k:9;//unsigned char最大只能是8位

还有一个就是:一个字节剩余的空间无法存放下一位域时,它也会从下一单元开始存放, 例如:

unsigned char i:1//i剩下7个位
unsigned char j:8//j从下一字节单元开始存放

2.无名位域

表示该字节后的n位不可用, 例如:

unsigned char i:1;
unsigned char : 3;//该字节1-3位不可用
unsigned char j:1;//从第4位开始

3.空域

表示该字节后的n位不可用,并且数据从下一字节开始存放, 例如:

unsigned char i:1;
unsigned char  :0;//该字节后7位不可用
unsigned char j:1;//该字节已经为下一字节

三、关于内存对齐

在cpu中,为了加快内存的访问,数据的读取,基本c数据类型并不是随机存放在内存地址中,对于不同的数据类型,有不同的内存对齐要求。

char:起始于任意字节地址:例如0x00000001
short:起始于偶数字节地址:例如0x00000002
int,float:起始于能被4整除的字节地址:例如0x00000004
long,double:起始于能被8整除的字节地址:例如0x00000008

但这跟结构体有什么关系?我们知道,结构体中可以包含多个不同数据类型的成员变量,在编译器给这些变量分配内存的时候,是按照我们在结构体中定义变量的顺序来分配的,由于内存对齐的原因,有些变量的字节我们并未使用到,会造成内存的浪费,这时候就可以通过调换成员变量的顺序来达到节省内存空间的目的。一般在嵌入式开发需要用到,像MCU,内存比较有限,不过现在的MCU内存都够用,基本上不用考虑太多这方面的东西。
有兴趣可以看下大牛写的这篇文章:

原文: http://www.catb.org/esr/structure-packing.
作者:Eric S. Raymond
中文版本: https://github.com/ludx/The-Lost-Art-of-C-Structure-Packing.

上一篇:vite.config.ts


下一篇:【Example】C++ 模板概念讲解及编译避坑