【嵌入式——C语言】结构体

【嵌入式——C语言】结构体

  • 概念
  • 定义
  • 初始化及使用
  • 结构体数组
  • 结构体指针
  • 结构体内存分配
  • 位段

概念

结构体是一种构造类型的数据结构,是一种或多种基本类型或构造类型的数据的集合。

定义

  • tag 是结构体标签;
  • member-list 是标准的变量定义,比如 int i; 或者 float f;,或者其他有效的变量定义;
  • variable-list 结构体变量,定义在结构的末尾,最后一个分号之前,可以指定一个或多个结构变量;
  • 在一般情况下,tag、member-list、variable-list 这 3 部分至少要出现 2 个。
struct tag {
    member-list
    member-list
    member-list  
    ...
} variable-list ;

struct Books
{
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
} book;

这个结构体并没有标明其标签,以后只可以使用s1这个变量,不能再定义其他变量了,代码如下:

struct
{
    int a;
    char b;
    double c;
} s1;

结构体的标签被命名为SIMPLE,没有声明变量,代码如下:

struct SIMPLE
{
    int a;
    char b;
    double c;
};

也可以用typedef创建新类型,代码如下:

typedef struct sim
{
    int a;
    char b;
    double c;
} Simple2;

可以用Simple2作为类型声明新的结构体变量 Simple2 u1, u2[20], *u3;

初始化及使用

废话不多说,直接上代码

struct stu {
    int num;
    char name[20];
    char sex;
    char* addr;
};
struct stu boy;
struct stu lucy = {101, "lucy", 'f'};

必须按照顺序进行初始化,中间字段不可以不赋值,后面的字段可以不初始化。
注意:struct stu lucy = {101, , ‘f’};这种写法是错误的

boy.num = 100;
strcpy(boy.name, "bob");
boy.sex= 'a';
boy.addr="address";

相同类型的结构体可以相互赋值,如boy = lucy;

结构体数组

由若干个相同类型的结构体变量构成的集合。

struct 结构体类型名 数组名[元素个数] 

struct stu edu[3];
edu[0].num=100;

结构体指针

即结构体的地址,定义一个变量来存放这个地址,这个变量就是结构体指针变量。

struct 结构体类型名 *结构体指针变量名

struct stu{
 int num;
 char name[20];
};

struct stu *p;

struct stu boy;
p=&boy;

(*p).num = 100; 或者p->num = 100; 或者boy.num = 100;

结构体内存分配

结构体变量大小,是所有成员大小之和,但是在实际结构体变量分配内存的时候是规则的,实际会多分配一些内存。
规则1

  • 以多少个字节为单位开辟内存空间;
  • 给结构体变量分配内存的时候,会去结构体变量中找基本类型的成员,哪个基本类型的成员占字节数多,就以它为单位开辟内存;
  • 成员中只有char型数据,以1字节为单位开辟内存;
  • 成员中出现了short int类型数据,没有更大字节数的基本类型数据,就以2字节为单位开辟内存;
  • 出现了int 、float没有更大字节的基本类型数据的时候以4字节为单位开辟内存;
  • 出现了double类型的数据:在vc6.0和Visual Studio中,以8字节为单位开辟内存、在Linux环境gcc里,以4字节为单位开辟内存、无论哪种环境 double型变量,占8字节;
  • 如果在结构体中出现了数组,数组可以看成多个变量的集合,如果出现指针的话,没有占字节数更大的类型的,就以4字节为单位开辟内存;
  • 在内存中存储结构体成员的时候,按定义的结构体成员的顺序存储。

规则2

  • 字节对齐;
  • char 1字节对齐,即存放char型的变量,内存单元的编号是1的倍数即可;
  • short int 2字节对齐,即存放short int型的变量,起始内存单元的编号是2的倍数即可;
  • int 4字节对齐,即存放int型的变量,起始内存单元的编号是4的倍数即可;
  • long int 在32位平台下,4字节对齐,即存放long int型的变量,起始内存的编号是4的倍数即可;
  • float 4字节对齐,即存放float型的变量,起始内存单元的编号是4的倍数即可;
  • double:vc6.0和Visual Studio环境下,8字节对齐,即存放double型变量的起始地址,必须是8的倍数,double变量占8字节,gcc环境下 4字节对齐 即存放double型变量的起始地址,必须是4的倍数,double变量占8字节;
  • 当结构体成员中出现数组的时候,可以看成多个变量;
  • 开辟内存的时候,从上向下一次按成员在结构体中的位置开辟空间。

字节对齐的目的:用空间来换时间,提高CPU读取数据的效率。

指定对其原则

1.#pragma pack(value)

  • value只能是1 2 4 8
  • 指定对其值与数据类型对其值相比取较小值;
  • #pragma pack(2)

2.以多少个字节为单位开辟内存
结构体成员中,占字节数最大的类型长度和value比较,取较小值为单位开辟内存。

位段

在结构体中,以位为单位的成员,称之为位段(位域)。

struct stu {
unsigned int a:2;
unsigned int b:4;
unsigned int i;
} data;

不能对位段成员取地址,因为这个位段成员可能不够一个字节。

你可能感兴趣的:(c语言,开发语言,嵌入式硬件,物联网,iot)