解析C语言结构体及位段
一、结构体是C和C++用户自己来定义的一种数据类型。
1、结构体变量的定义方法由三种:
(1)先声明结构体类型再定义结构体变量;
在C语言中,定义结构体变量要在结构体类型名前加关键字struct,而C++也保留了这一用法,例:
struct Student student1, student2;
但C++语言也提出了新的方法,即在定义结构体变量时,不需要加关键词struct。
(2)在声明类型的同时定义结构体变量;例:
struct student
{int num;char name[20];char sex;int age;float score;
}student1,student2;
(3)直接定义结构体变量,这种方法虽然合法,但不建议使用。
还是提倡第一种用法。
2、结构体变量的初始化:在定义结构体变量时进行初始化。例:
struct Student
{int num;char name[20];int age;char sex;float score[6];
}student{ 20, "liming", 20, { 10, 22, 15, 35, 66, 58 } };
3、struct 和 typedef struct.
(1) 在C语言中定义结构体如果使用 typedef struct:
typedef struct Student
{int num;char name[20];int age;char sex;float score[6];
};
在定义结构体变量中就可以直接使用:
int main()
{Student student1;return 0;
}
如果没有 typedef,在定义结构体变量时,类型前面就要加上关键字 struct。而在C++中,定义结构体时可以直接进行定义,不需要关键字 struct。
(2)然而在C++中使用 typedef 会有不同的意义,例:
typedef struct Student
{int num;char name[20];int age;char sex;float score[6];
}student1;
struct Student
{int num;char name[20];int age;char sex;float score[6];
}student2;
其中,student1又是一个结构体类型,student2是一个结构体变量,在对其对象访问时有一定的区别。
4、结构体的内存存储
(1)内存对齐规则:
a)结构体的第一个成员永远都放在结构的0偏移处;
b)从第二个成员开始,都要对齐到某个对齐数的整数倍;(对齐数为结构体成员自身的大小和系统默认对齐数的较小值,Vs中默认的值为8,linux中默认的值为4)
c)结构体的总大小必须是最大对齐数的整数倍。
d)如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数的整数倍。
#include<stdio.h>
#include<iostream>
struct Student//Vs系统的默认对齐数为8,该结构体成员类型最大所占字节为4,所以对齐数为4
{int num; //4个字节 0-3偏移处//从0偏移处开始存放,存放4个字节char name[20]; //20个字节 4-23偏移处//存放了4个字节刚好为结构体对齐数的整数倍,则紧挨着从接下来的4偏移处开始存放20个字节int age; //4个字节 24-27偏移处//存放了24个字节刚好为结构体对齐数的整数倍,则紧挨着从接下来的24偏移处开始存放4个字节char sex; //1个字节 28偏移处//存放了28个字节刚好为结构体对齐数的整数倍,则紧挨着从接下来的28偏移处开始存放1个字节float score[6]; //24个字节 32-55偏移处//存放了29个字节,不是4的整数倍,则要浪费掉3个字节,从接下来的4的倍数的偏移处开始存放,即从32偏移处开始存放24个字节
}student2;//结构体内存存放到了55偏移处,则存放了56个字节,则结构体的大小为56
int main()
{Student student1;printf("%d\n", sizeof(student2));system("pause");return 0;
}
(2)内存对齐的原因:
a)平台原因:不是所有硬件平台都能够访问任意地址上任意数据的;某些硬件平台只能在某些地址处取得某些特定类型的数据,否则抛出硬件异常;
b)性能原因:数据结构应该尽可能地在自然边界上对齐。原因是为了访问未对齐的内存,处理器需要作两次内存访问,二对齐的内存访问仅需一次访问。
#include<stdio.h>
struct Student
{char name;int age;
};
int main()
{Student student;return 0;
}
二、结构体与位段
1、位段:有些信息的存储并不需要占用一个字节,只需要几个或一个比特位,为了节省空间,C语言提供了一种数据结构----位段。其成员类型可为:int、char、signed int、unsigned int 。
2、结构体实现位段:
#include<stdio.h>
#include<iostream>
struct Student
{int a : 5;signed int b : 1;unsigned int c : 3;
};
int main()
{Student student1{ 5, 1, 2 };printf("%d\n", sizeof(student1)); //占4个字节的空间printf("%d\n", sizeof(Student)); //占4个字节的空间system("pause");return 0;
}
3、位段的大小计算
a)1)如果一个位段存储单元能够存储得下位段结构中的所有成员,那么位段结构中的所有成员只能放在一个位段存储单元中,不能放在两个位段存储单元中;如果一个位段存储单元不能容纳下位段结构中的所有成员,那么从剩余的位段从下一个位段存储单元开始存放。(在VC中位段存储单元的大小是4字节);
b)如果一个位段结构中只有一个占有0位的无名位段,则只占1或0字节的空间(C语言中是占0字节,而C++中占1字节);否则其他任何情况下,一个位段结构所占的空间至少是一个位段存储单元的大小。
解析C语言结构体及位段相关推荐
- c语言结构体反射解析,C语言结构体解析
我们知道定义一个数组就等于定义了多个相同类型的变量,它们的类型是一样的.有时有这样的需求,如果我想保存一些信息,但每个信息类型不一定相同,这时该怎么办?我们就可以自己定义一类型,而这个类型,就是结构体 ...
- c语言结构体和联合体,C语言结构体和联合体
1.单链表插入 #include #include #define FALSE 0 #define TRUE 1 typedef struct NODE{ STRUCT NODE *link; int ...
- C语言结构体——位段概念的讲解
前言 之前我对结构体内存分配的方式.对默认对齐数的指令修改做了详细的博客讲解,(C语言结构体详解 (2) 结构体内存对齐,默认对齐数,大家有兴趣的话可以去了解了解这方面的知识. 一. 什么是位段? 位 ...
- C语言结构体中的位段
C语言结构体中的位段 位段的内存分配 位段的成员可以是 int unsigned int signed int 或者是 char (属于整形家族)类型 位段的空间上是按照需要以4个字节( int )或 ...
- 深入解析JNA—模拟C语言结构体
原帖:http://blog.csdn.net/shendl/article/details/3599849 深入解析JNA-模拟C语言结构体 前言 前几天写<JNA--JNI终结者>一文 ...
- 详解C语言自定义类型(结构体,位段,枚举,联合)
C语言中有许多类型,比如整形int,字符型char,双精度浮点型double等等.这些类型可以存放一些值或者字符.但是如果我想要一种类型存放一本书,显然是没有的,那么这时候就需要自定义类型了,也就是结 ...
- 自定义类型:结构体、位段、枚举、联合 ------- C语言
C语言中,7可以存放再整型变量中,'c' 可以存放在字符型变量中,3.14可以存放在浮点型变量中,一个学生有:姓名.年龄.性别.学号等.C语言中是否有这样一个可以存放学生的类型呢?答案是肯定的,这一种 ...
- golang常用库之mapstructure包 | 多json格式情况解析、GO json 如何转化为 map 和 struct、Go语言结构体标签(Struct Tag)
文章目录 golang常用库之mitchellh/mapstructure包 | go将map转换为struct 一.msgpack 二.背景 三.多json格式情况解析使用思路 四.mapstruc ...
- C语言结构体字节对齐规则
C语言结构体字节对齐规则 基本规则 规则1 :结构体(struct)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存放在offset为该数据成员大小的整数倍的地方(比如int在 ...
最新文章
- AJAX技术其实就是多年前我就使用过的XMLHTTP
- ios 设计模式 MVC ,MVVM
- mvp的全称_现役最强外援,总决赛MVP,来到CBA之后赚了多少钱?
- 由于超出容量限制_限制特高压系统中的过电压措施
- docker中启动关闭删除所有的容器命令
- 从一个视图控制器切换到另一个视图控制器的几种方式
- 吴恩达深度学习 ——深层神经网络(选择题)
- Matplotlib:直方图示例(2):正态分布。
- Windows11怎么配置Maven环境变量
- HW2021攻防演练经历碎碎念-见解
- 动画云渲染【渲染101】渲染小提示
- 你不屑于大器晚成,就只能平庸一生
- 恢复win7 exe文件打开方式?
- AMD显卡性能测试软件,谁更适合Win7?AMD与NVIDIA显卡性能对比
- 淘宝标题优化词根优化方法技巧 什么是淘宝标题词根
- 【Git】git did not exit cleanly (exit code 1) 异常处理
- 19.Oracle数据库SQL开发之 笛卡尔积
- C语言 冒泡法排序,选择法排序和插入排序
- python文件名排序按windowsp_在SQLServer中如果实现Windows文件夹中按名称排序?算法是什么怎么Order By...
- 基于Netty的RPC架构实战演练
热门文章
- 剑网3哪5区人哪个服务器最多,剑网3哪个区服人最多?只有选对了游戏区才能体会到多人的乐趣...
- ie调用java闪退_win7系统位数不兼容导致Ie浏览器频繁出现闪退的解决方法
- 由于不能验证所收到的数据是否可信,无法显示您想要查看的页面。建议向此网站的管理员反馈这个问题。
- 12 款做Java后台管理系统的项目,超级无敌好用!
- 吃豆人 html5 倒计时,ChinaJoy开展倒计时,回忆杀吃豆人ip摩擦康迪克水杯溅火花...
- java字符串是日期yyxx_Mysql 优化方案
- 如何在html中引入一个仪表盘,仪表盘.html · 一头大水牛/前端每日总结,积累点滴! - Gitee.com...
- the kth number第几大数问题
- 鞍点计算 C语言 SDUT
- leecode:977. 有序数组的平方