| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 数据结构与算法 -> C语言学习之路————结构体1.0 -> 正文阅读 |
|
[数据结构与算法]C语言学习之路————结构体1.0 |
1.结构体的基本知识 结构是一些值的集合,这些值被称为成员变量,结构体的每个成员可以是不同类型的 2.结构体的声明 ? struct tag(标签,也叫结构体名)--->此出没tag叫匿名结构体类型,要注意的是,匿名结构体要及时在结构体类型后定义变量 { ? ? //member list(成员列) exp:char a; ? ? ? ? ?char str[]; };//variable list(变量列)exp:s1,s2;// 首先要提到的是这个锋号,如果没有要定义的变量,要在}后面添加锋号;而定义在结构体后面的变量一般是全局变量,如果是 int main() { struct tag s3; return 0; }//这样的变量称它为局部结构体变量(s3) 匿名结构体类型要注意的是当创建一个匿名结构体之后,再以相同的成员作为结构体类型定义一个结构体类型指针,是不可行的,在编译器中会认为他们是不同的的结构体类型,即使他们的结构体成员一样 exp: struct { char a; char str[]; }s1; struct { char a; char str[]; }* ps1; int main() { struct tag *ps1=&s1;//wraning return 0; }//值得注意的是这个没命名的结构体类型,只对他开始定义过的变量有效,也仅限在这,别的地方无法定义新的变量 3.结构体自引用 在结构体类型成员中有个结构体 这时我们要注意,直接将结构体类型对应变量,写入是不对的,我们要指向这个结构体的指针放入, 结构体中经常会使用typedef将结构体类型名,改成其他的简单的名字exp: typedef stuct (tag){ tags* next//error struct tag* next;//right? }tags;如果没有tag,是个匿名结构体类型这里的成员列里不能出现结构体的自引用, 在为改名之前就自应用,程序不会识别这个新的类型名 4.结构体变量初始化 struct body{ double weight; int height; }t; struct stu{ char name[]; struct body t; short age; }p; int main() { struct stu p={“wangming”,{60.0,175},23}; struct stu* pp=&p; printf("%s",p.name);//点这个字符是用来访问结构体成员的, printf("%s",pp->name)//这个是指针访问结构体成员的 return0; } 5.结构体内存对齐(求结构体的大小) 规则;第一个成员在于结构体变量偏移量为零的地址处//偏移量是指在结构体在内存中放置的第一个位置空间(偏移量为0)算起,每向下一个字节,偏移量加1, ? ? ? ? 其他成员要对齐某个数字(对齐数)的整数倍的地址处(对齐数:编译器中默认的对齐数和成员大小的较小值) ? ? ? ? 结构体的大小为最大对齐数的整数倍 ? ? ? ? 如果结构体内嵌套结构体,还是先算出这该嵌套结构体的大小,在与默认对齐数比较 exp: struct stu { char a;//sizeof=1对齐数为1 char a1;//sizeof=1对齐数为1 int b;//sizeof=4对齐数为4? ? ,前面的两个char相继占据了偏移量为1和0的两块空间(任何数都是一的倍数)而第三个成员要放在对齐数的倍数处,也就是偏移量为对齐数的倍数处,偏移量为四的位置刚好是第三个成员对齐数4的倍数,就在这里开始存放第三个成员(在第二个成员地基础上向后偏移了两字节,而这跳过的两字节空间将会被浪费掉)4+4=8,8也正好是最大对齐数4的倍数,所以该结构体的大小为8 }s1;//vs里的默认对齐数为8 int main() { ? printf("%d",sizeof(s1));//8 ? return 0; } 我们在放置成员的时候,讲究是将小的数据集中放置,可以减少空间的浪费 注意:在gcc环境下,没有默认对齐数 结构体内存对齐的原因:1.不是所有硬件平台都能访问任意地址上的任意数据的,只能在某些地址的取特定数据,2.内存对齐可以减少访问一个数据的次数即减少运算时间,exp:char a;int b;如果不按照内存对齐来存储,这个结构体会在内存中站5个字节,而在32位机器上每次读取4个字节,而b就会分两次读取,而内存对齐后这里的结构体大为8,a存完后会浪费三个字节的空间,再存储b,先一次读a,再一次都b,总共才需要两次,很好的节省了时间,说白了,内存对齐是用空间来换取时间 6.修改默认对齐数 我们可以用#pragma这个预处理命令,改变默认对齐数 #pragma pack(size_t为要设置的默认对齐数数字,而什么都不给,就是取消默认对齐数) 这里涉及到的size_toffsetof(structName,memberName);这样一个函数可以实现算出,结构体成员再内存中的偏移量,他的头文件是<stddef.h>,这是一个宏的概念 ? ? ? ?? |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/26 5:22:00- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |