重头开始嵌入式第十六天(结构体,共用体)

目录

结构体

结构体定义

结构体初始化

结构体赋值

结构体调用

结构体大小

在 C 语言中,结构体内存对齐规则主要遵循以下原则:

共用体

共用体定义

共同体赋值,初始化

 共用体大小

结构体与共用体的区别


结构体

在 C 语言中,结构体(struct)是一种用户自定义的数据类型,用于将不同类型的数据组合在一起,形成一个逻辑上相关的整体。
 
 
 

结构体定义

结构体的定义格式如下:

struct 结构体名 {
    数据类型 成员名 1;
    数据类型 成员名 2;
    // 可以有多个成员
  ...
};
 
 
例如:
 

struct Student {
    int id;
    char name[50];
    float score;
};


在定义结构体变量时,可以采用以下方式:

struct Student stu1; 


或者

struct Student stu2 = {101, "Alice", 90.5}; 


要访问结构体成员,可以使用“.”操作符,例如:

stu1.id = 102;
printf("%s\n", stu2.name);


 
结构体在 C 语言中应用广泛,常用于组织和处理复杂的数据结构,如链表、树等。

 
关键知识点展开讲解:


- 结构体成员的数据类型可以是基本数据类型(如 int、float、char 等),也可以是其他自定义的数据类型,包括指针、数组等。
- 结构体可以嵌套,即在一个结构体中包含另一个结构体作为成员。
- 结构体变量在内存中的存储是按照成员的顺序依次排列的,每个成员按照其自身的数据类型所占用的字节数进行存储。

结构体初始化



有两种常见的初始化方式。
 
1. 直接在定义结构体变量时进行初始化:

struct Student {
    int id;
    char name[50];
    float score;
} stu1 = {101, "Alice", 90.5};


 
2. 先定义结构体变量,然后再分别对成员进行赋值:

struct Student stu2;
stu2.id = 102;
strcpy(stu2.name, "Bob");
stu2.score = 85.0;


结构体赋值


可以通过逐个成员赋值,或者将一个结构体变量的值赋给另一个同类型的结构体变量。

struct Student stu3;
stu3 = stu2;  // 结构体变量之间的赋值


结构体调用


 
通过“.”操作符来访问结构体成员。

printf("Student ID: %d\n", stu1.id);
printf("Student Name: %s\n", stu1.name);
printf("Student Score: %.2f\n", stu1.score);


 在 C 语言中,结构体指针用于操作结构体变量。以下是关于结构体指针的一些常见操作:

定义结构体指针:

struct Student {

    int id;

    char name[50];

    float score;

};



struct Student *ptr; // 定义一个指向 struct Student 类型的指针

通过指针访问结构体成员:

有两种方式,使用“->”操作符或者先解引用指针再使用“.”操作符。

ptr = &stu; // 假设 stu 是已定义的 struct Student 类型变量



// 方式一:使用 "->" 操作符

ptr->id = 101;

printf("%s\n", ptr->name);



// 方式二:先解引用再使用 "." 操作符

(*ptr).id = 102;

printf("%f\n", (*ptr).score);

动态分配结构体内存:

ptr = (struct Student *)malloc(sizeof(struct Student));

if (ptr == NULL) {

    printf("Memory allocation failed!\n");

    return 1;

}



ptr->id = 200;

strcpy(ptr->name, "Tom");

ptr->score = 95.5;



free(ptr); // 使用完后释放内存

结构体指针在处理复杂的数据结构、传递结构体参数给函数等场景中非常有用,能够提高程序的灵活性和效率。


结构体大小


结构体的大小等于其所有成员大小之和。但是由于内存对齐的原因,实际占用的内存空间可能会大于各成员大小之和。内存对齐是为了提高 CPU 访问内存的效率。
 
可以使用  sizeof  运算符来获取结构体的大小。
 

printf("Size of Student struct: %zu\n", sizeof(struct Student));


 
需要注意的是,不同的编译器和平台可能会有不同的内存对齐规则,导致结构体大小有所差异。

在 C 语言中,结构体内存对齐规则主要遵循以下原则:

1. 结构体的每个成员按照其自身的数据类型进行对齐。通常,基本数据类型的对齐值等于其自身的大小。例如, char  类型的对齐值为 1 字节, int  类型通常为 4 字节(在 32 位系统中)。
2. 结构体的总大小必须是其最大成员大小的整数倍。
3. 结构体成员的存放起始地址是其对齐值的整数倍。如果当前位置不满足对齐要求,会进行填充空白字节以满足对齐。
例如,对于以下结构体:
struct example {
    char a; // 1 字节
    int b; // 4 字节
    short c; // 2 字节
};
为了满足  int  类型的 4 字节对齐, char  类型的成员  a  之后可能会填充 3 个字节,然后存放  int  类型的成员  b  。接着, short  类型的成员  c  会按照 2 字节对齐存放。
内存对齐的主要目的是提高 CPU 访问内存的效率,尤其是在现代计算机体系结构中。
不同的编译器可能会有略微不同的内存对齐实现方式,但总体原则是相似的。

共用体

在 C 语言中,共用体(Union)是一种特殊的数据类型,它使得多个不同类型的变量共享同一段内存空间。
 

共用体定义


共用体的定义格式如下:

union 共用体名 {
    数据类型 成员名 1;
    数据类型 成员名 2;
    // 可以有多个成员
 ...
};
 
 
例如:
 

union Data {
    int i;
    float f;
    char str[20];
};

共同体赋值,初始化

以下是关于共用体赋值和初始化的示例及相关说明:
 
初始化共用体:
 
可以在定义共用体变量时进行初始化,方式类似于结构体的初始化。

union Data data1 = {.i = 10};  // 初始化共用体的成员 i 为 10


 
或者

union Data data2 = {20.5f};  // 初始化共用体的成员 f 为 20.5


赋值共用体:
 
在共用体中赋值会覆盖之前存储的其他成员的值。

union Data data;
data.i = 5;  // 给成员 i 赋值
data.f = 3.14f;  // 此时成员 i 的值被覆盖,存储了成员 f 的值
 


 
需要注意的是,由于共用体的所有成员共享同一块内存空间,所以在使用共用体时要特别小心,确保对其的操作符合预期,避免因成员值的覆盖而导致数据混乱或错误。


 共用体大小


在共用体中,同一时刻只能存储其中一个成员的值。共用体的大小取决于其最大成员的大小。
 
关键知识点展开讲解:
 
- 由于共用体的所有成员共享同一段内存,所以对一个成员的赋值会覆盖其他成员的值。
- 共用体常用于节省内存空间或者在不同时刻需要使用不同类型的数据的场景。
 
例如,在处理不同格式的数据时,如果在某个时刻只需要使用其中一种格式的数据,就可以使用共用体来节省内存。

结构体与共用体的区别

结构体和共用体主要有以下区别:

1. 内存分配:

- 结构体:结构体的每个成员都有自己独立的内存空间,结构体的总内存大小是所有成员内存大小之和。

- 共用体:共用体的所有成员共享同一块内存空间,内存大小等于其最大成员的内存大小。

2. 存储方式:

- 结构体:可以同时存储所有成员的值。

- 共用体:同一时刻只能存储一个成员的值。

3. 用途:

- 结构体:适用于需要将不同类型但相关的数据组合在一起,并且需要同时访问和处理这些数据的情况。

- 共用体:常用于节省内存或者在不同时刻需要使用不同类型的数据的场景。

4. 数据完整性:

- 结构体:能保证各个成员数据的完整性和独立性。

- 共用体:由于成员值的相互覆盖,可能导致数据的不确定性和不完整性。

总之,结构体强调的是数据的组合和完整性,而共用体更侧重于内存的高效利用和灵活的数据类型切换。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值