您现在的位置是:首页 > 名人名句

C#自定义数据类型-结构体详解

作者:胡椒时间:2024-05-07 10:59:24分类:名人名句

简介  文章浏览阅读821次,点赞45次,收藏18次。介绍结构体类型,结构体变量的创建和初始化,结构中存在的内存对齐

点击全文阅读

目录

 1、结构体的声明

2、结构体变量的定义

3、结构体变量的初始化

4、结构体成员的访问

直接访问

间接访问

5、匿名结构体

6、结构的自引用

7、结构体内存对齐

练习1

练习2 

 练习3

8、为什么存在内存对齐


我们知道C语言内置类型及数组只能存放某一种数据,但在构造数据类型中,可以包含多个不同数据类型的数据组合,那么今天就来学习构造数据类型之一结构体struct。

重点:了解结构体中变量内存对齐及计算结构体大小shishi

 1、结构体的声明

struct person//struct为结构体关键字 person为结构体名{char name[12]; // 结构体所含数据元素称为成员变量int age;char sex;}; // 注意不能少了分号

2、结构体变量的定义

#include<stdio.h>struct person{char name[12];int age;char sex;}p1,per[3]; // 定义变量p1,数组perint main(){struct person p2, p3;//定义不同的变量struct person* p4;return 0;}

3、结构体变量的初始化

#include<stdio.h>struct person{char name[12];int age;char sex;}p2,per[3] = { { "lisi",19,'w' },{"wangwu",21,'w'},{"laoliu",18,'w'} };//上述定义了per数组并初始化(注意格式)struct family{int number;struct person p2;//结构体嵌套}fam1 = {3,"wangwu",21,'w'};//结构体嵌套的定义及按照顺序初始化int main(){struct person p1 = {"zhangsan",20,'w'};//指定内容初始化return 0;}

4、结构体成员的访问

直接访问

 结构体成员的直接访问是通过点操作符(.)访问的

结构体变量.成员名

#include<stdio.h>struct person{char name[12];int age;char sex;}p1;int main(){struct person p1 = {.age=21,.name="zhangsan",.sex='w'};printf("%d %s %c", p1.age, p1.name, p1.sex);return 0;}
间接访问

结构体指针->成员变量

当我们得到的不是结构体变量,而得到的是指向结构体的指针

#include<stdio.h>struct person{char name[10];int age;};int main(){struct person p1 = {21,"zhangsan"};struct person* ptr = &p1;//结构体指针ptr->age = 30;printf("%d %s", ptr->age, ptr->name);return 0;}


5、匿名结构体

struct //缺了结构体名为匿名结构体{char name[10];int age;}per1;struct //匿名结构体{char name[10];int age;}per2;

编译器会把如上两个声明当作完全不同的两个类型,所以,匿名结构体只能用一次。

6、结构的自引用

结构体包含一个类型为该结构体的成员时,就使用自引用。

struct Node{int data;struct Node * next;};

7、结构体内存对齐

计算结构体大小就得学会内存对齐这一热门考点。(重点!牢记对齐规则)

结构体对齐规则

1. 结构体的第⼀个成员对齐到和结构体变量起始位置偏移量为0的地址处

2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。 对齐数 = 编译器默认的⼀个对齐数 与 该成员变量大小的较小值VS 中默认的值为 8 ,Linux中 gcc 没有默认对齐数,对齐数就是成员自身的大小

3. 结构体总大小为最大对齐数的整数倍。

4. 如果嵌套了结构体的情况,嵌套的结构体成员对齐到自己的成员中最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体中成员的对齐数)的整数倍。

现在我们对结构体对齐规则已经了解,那么做几道题巩固知识点吧。

练习1
// 练习1struct S1{ char c1; char c2; int i;};printf("%d\n", sizeof(struct S1));//8

练习2 
struct S2{ double d; char c; int i;};printf("%d\n", sizeof(struct S2));//16

 练习3
struct S3{ char c1; struct S s2; double d;};printf("%d\n", sizeof(struct S3));//32

 

8、为什么存在内存对齐

部分的参考资料都是这样说的:
1. 平台原因 (移植原因):
不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
2. 性能原因:
数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要⼀次访问。假设⼀个处理器总是从内存中取8个字节,则地址必须是8的倍数。如果我们能保证将所有的double类型的数据的地址都对齐成8的倍数,那么就可以用一个内存操作来读或者写值了。否则,我们可能需要执行两次内存访问,因为对象可能被分放在两个8字节内存块中。
总体来说:结构体的内存对齐是拿空间来换取时间的做法。
那在设计结构体的时候,我们既要满足对齐,又要节省空间,如何做到:
让占用空间小的成员尽量集中在⼀起 

本篇学习到这里,此时对结构体的内存对齐及结构体大小是不是已经非常熟悉了。

喜欢作品就留下小红心与收藏再走吧 ,能得到你们的支持是我创作的不竭动力。

关注我,以后与你们分享更多知识。

点击全文阅读

郑重声明:

本站所有活动均为互联网所得,如有侵权请联系本站删除处理

我来说两句