struct、union、enum and sizeof
struct
1、结构体和数组的差别:能够再结构体里声明数组。结构体变量能够相互赋值。而数组不行。
2、struct与class的差别:class的成员訪问权限默认是private,而struct成员的是public。
3、结构体的定义:
(1)可递归。结构体内部能够使用指针指向自己。比如。链表。
(2)可嵌套。结构体内部能够包括其它的结构体。
4、结构体中的位域。
在存储信息时,不须要占用一个完整的字节,而仅仅须要占几个或一个二进制位。
位域定义与结构定义相仿。其形式为:
struct 位域结构名
{
类型说明符 位域名:位域长度
};
比如:
struct bs
{
int a:8;
int b:2;
int c:6;
}data;分析:data为bs变量,共占两个字节。
当中位域a占8位,位域b占2位,位域c占6位。
对于位域的定义尚有下面几点说明:
1.
因为位域不同意跨两个字节,因此位域的长度不能大于一个字节的长度。也就是说不能超过8位二进位。如一个字节所剩空间不够存放还有一位域时。应从下一单元起存放该位域。
也能够有意使某位域从下一单元開始。
2. 位域能够无位域名。这时它仅仅用来作填充或调整位置。无名的位域是不能使用的。
比如:
struct bs
{
unsigned a:4
unsigned :0 /*空域*/
unsigned b:4 /*从下一单元開始存放*/
unsigned c:4
}
在这个位域定义中,a占第一字节的4位。后4位填0表示不使用。b从第二字节開始。占用4位。c占用4位。
union
结构体和共用体都是由多个不同类型的数据类型成员组成。可是在任一时刻,共用体中仅仅存放了一个被选中的成员。而结构体
中全部成员都纯在。
对于共用体的不同成员赋值,将会对其它成员重写。原来成员的值就不存在了。
(1)结构体占用内存,可能超过各个成员内存量的和,而共用体占用的内存为各个成员中占用最大者内存。
(2)union和struct在内存中的存放顺序是从地地址開始存放的。
大端存储:数据的高字节存放在低地址中。
小端存储:数据的低字节存放在低地址中。
enum
(1)定义
enum 枚举类型名
{
枚举表
}
比如:
enum ColorEnum1
{
红色, //注意,系统会默认给它赋值为0
蓝色, //系统赋值为1
黑色, //系统赋值为2
粉红色 //系统赋值为3
}
enum ColorEnum2
{
红色=1, //用户自己赋值 所以枚举是一组 符号名称/值 配对
蓝色, // 系统赋值为2
黑色=1, //用户自己赋值1
粉红色 //系统赋值为2
}
所以能够看出。系统会自己给没有赋值的常量赋值。但赋值的方式是依照上一个的值+1来进行操作的
sizeof(struct/union/enum)
一般32位机子上各个数据类型所占的存储空间例如以下:
char:8位
short:16位
int:32位
long:32位
float:32位
double:64位
一、struct,结构体。
请牢记下面3条原则:(在没有#pragma pack宏的情况下)
1、数据成员对齐规则:结构体(struct)的数据成员,第一个数据成员放在offset为0的地方,之后的每一个数据成员存储的起始位置要从该成员大小的整数倍開始(比方int在32位机子上为4字节,所以要从4的整数倍地址開始存储)。
2、结构体作为成员:假设一个结构体里同一时候包括结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址開始存储
(如struct a里有struct b,b里有char,int ,double等元素。那么b应该从8(即double类型的大小)的整数倍開始存储)。
3、结构体的总大小:即sizeof的结果。
在按对齐原则计算出来的大小的基础上。必须还得是其内部最大成员的整数倍.
不足的要补齐(如struct里最大为double,如今计算得到的已经是11,则总大小为16)。
样例:
typedef struct bb
{
int id; //[0]....[3] 表示4字节
double weight; //[8].....[15] 原则1
float height; //[16]..[19],总长要为8的整数倍,仅对齐之后总长为[0]~[19]为20,补齐[20]...[23] 原则3
}BB;
typedef struct aa
{
int id; //[0]...[3] 原则1
double score; //[8]....[15]
short grade; //[16],[17]
BB b; //[24]......[47] 原则2(由于BB内部最大成员为double,即8的整数倍開始存储)
char name[2]; //[48][49]
}AA;
int main()
{
cout<<sizeof(AA)<<" "<<sizeof(BB)<<endl;
return 0;
}
输出结果为56 24
编译器中提供了#pragma pack(n)来设定变量以n字节对齐方式。
//n为1、2、4、8、16...
1、n字节对齐就是说变量存放的起始地址的偏移量有两种情况:第一、假设n大于等于该变量所占用的字节数。那么偏移量必须满足默 认的对齐方式,即该变量所占用字节数的整数倍;第二、假设n小于该变量的类型所占用的字节数,那么偏移量为n的倍数,不用满足默认的对齐方式。
2、结构体的总大小也有个约束条件,分以下两种情况:假设n大于全部成员变量类型所占用的字节数,那么结构的总大小必须为占用空间最大的变量占用的空间数的倍数;否则必须为n的倍数。
所以在上面的代码前加一句#pragma pack(1),则代码输出为
bb:(0~3)+(4~11)+(12~15)=16;
aa:(0~1)+(2~5)+(6~13)+(14~15)+(16~31)=32,也就是说,#pragma pack(1)就是没有对齐规则。
再考虑#pragma pack(4),
bb:(0~3)+(4~11)+(12~15)=16;
aa:(0~1)+(4~7)+(8~15)+(16~17)+(20~35)=36
二、union共用体(联合)
在union中,全部的共用体成员共用一个空间。而且同一时间仅仅能储存当中一个成员变量的值。其长度为联合体中元类型最大的变量长度的整数倍。
而且要考虑其它成员变量的对齐。
union foo
{
char s[10];
int i;
}
sizeof(foo) 的内存空间的长度为12,而并非数组的长度10。考虑对齐。必需要是4(int的大小)的整数倍。
若把int改为double,则foo的内存空间为16,是double型的两倍。
union mm{
char a;//元长度1 1
int b[5];//元长度4 20
double c;//元长度8 8
int d[3]; 12
};
考虑到8和12的对齐,所以sizeof(mm)=24。
三、enum
enum仅仅是定义了一个常量集合,里面没有元素。把它当做int型存储,所以sizeof的大小为4 byte。
【大小端】
推断大小端的方法:1、利用指针。2、利用union。
#include <stdlib.h>
#include <stdio.h> int main()
{
int x = 0x10000001;
char *p = (char *)&x; if (*p)
{
printf("little\n");
printf("%d\n", *p);
}
else
{
printf("large\n");
} system("pause");
return 0;
}
#include "stdio.h"
#include<stdlib.h> int main()
{
union w
{
int a; //4 bytes
char b; //1 byte
} c;
c.a = 1;
if (c.b == 1)
printf("It is Little_endian!\n");
else
printf("It is Big_endian!\n"); system("pause");
return 1;
}
以下这段代码输出也耐人寻味。
#include<stdio.h>
#include<stdlib.h> union {
char i[4];
short x;
}s; int main()
{
s.x = 0;
s.i[0] = 256;
s.i[1] = 255;
s.i[2] = 254;
s.i[3] = 253; printf("s.x is %d \n", s.x);
printf("s.i[0] is %d \n", s.i[0]);
printf("s.i[1] is %d \n", s.i[1]);
printf("s.i[2] is %d \n", s.i[2]);
printf("s.i[3] is %d \n", s.i[3]);
system("pause");
}
struct、union、enum and sizeof的更多相关文章
- SQL的inner join、left join、right join、full outer join、union、union all
主题: SQL的inner join.left join.right join.full outer join.union.union all的学习. Table A和Table B表如下所示: 表A ...
- namespace、struct、enum、union、string(day01)
一 C++概述 C++历史背景 )C++的江湖地位 jave C C++ C# python )C++之父:Bjarne Stroustrup(--) ,Cpre,为C语言增加类的机制 ,Bjarne ...
- oracle之集合操作函数---minus、union、intersect
集合操作符专门用于合并多条select语句的结果,包括:UNION,UNION ALL,INTERSECT,MINUS.当使用集合操作函数时,需保证数据集的字段数据类型和数目一致. 使用集合操作符需要 ...
- LINQ标准查询操作符(三)——Aggregate、Average、Distinct、Except、Intersect、Union、Empty、DefaultIfEmpty、Range、Repeat
七.聚合操作符 聚合函数将在序列上执行特定的计算,并返回单个值,如计算给定序列平均值.最大值等.共有7种LINQ聚合查询操作符:Aggregate.Average.Count.LongCount.Ma ...
- Spark RDD/Core 编程 API入门系列之map、filter、textFile、cache、对Job输出结果进行升和降序、union、groupByKey、join、reduce、lookup(一)
1.以本地模式实战map和filter 2.以集群模式实战textFile和cache 3.对Job输出结果进行升和降序 4.union 5.groupByKey 6.join 7.reduce 8. ...
- Linq to SQL -- Union All、Union、Intersect和Top、Bottom和Paging和SqlMethods
Union All/Union/Intersect操作 适用场景:对两个集合的处理,例如追加.合并.取相同项.相交项等等. Concat(连接) 说明:连接不同的集合,不会自动过滤相同项:延迟. 1. ...
- from、where、group、with、having、order、union、limit 的使用
顺序很重要 每次看数据库的一些语法时,都很自然的略过那一大堆的规则,比如说线下面这段select的语法: select [field1,field2...] func_namefrom table1, ...
- Swift中关于集合计算的几种函数记录(intersect、symmetricDifference、union、subtract)
很久之前用过一次,后来就忘了...扎心,现在记录一下 PS:这几种函数其实不限于swift内的,在JavaScript.python.DB等其他语言,应该也有类似用法,这里我只简单讲了在swift内的 ...
- 009-Hadoop Hive sql语法详解4-DQL 操作:数据查询SQL-select、join、union、udtf
一.基本的Select 操作 语法SELECT [ALL | DISTINCT] select_expr, select_expr, ...FROM table_reference[WHERE whe ...
随机推荐
- hdu 2266 dfs
题意:在数字之间添加运算符号,使得结果等于题目中要求的Sample Input123456789 321 1Sample Output181 这题虽然看起来比较简单,但是之前和差的状态不太好表示,因此 ...
- pygame系列_pygame安装
在接下来的blog中,会有一系列的文章来介绍关于pygame的内容,所以把标题设置为pygame系列 在这篇blog中,主要描述一下我们怎样来安装pygame 可能很多人像我一样,发现了pygame是 ...
- SGU 404 Fortune-telling with camomile
404. Fortune-telling with camomile Time limit per test: 0.25 second(s)Memory limit: 65536 kilobytes ...
- ZOJ 2969 Easy Task
E - Easy Task Description Calculating the derivation of a polynomial is an easy task. Given a functi ...
- python知识(3)----正则表达式
python的正则表达式使用起来非常的方便,基本思路就是编译规则,匹配字符串,输出字符串 参考资料 Python中的正则表达式教程
- Linux服务器压测/拷机软件收集
最近公司采购了一批服务器,于是收集了一些拷机软件来压测服务器硬件性能.硬件的稳定相对来说比较重要,7x24小时无间断运行,主要看三个硬件:CPU.内存.硬盘. 下面是收集的一些教程,可能网址已经失效了 ...
- Linux内核hlist数据结构分析
在内核编程中哈希链表hlist使用非常多,比方在openvswitch中流表的存储中就使用了(见[1]).hlist的表头仅有一个指向首节点的指针.而没有指向尾节点的指针,这样在有非常多个b ...
- apache如何支持asp.net
Apache是目前广泛使用的一种网络服务器程序,不仅在UNIX/LINUX平台上被大量使用,而且在Windows平台上也有许多站点放弃了IIS而转向Apache..NET是微软推出的功能强大的开发技术 ...
- [Asp.net MVC]HandleErrorAttribute异常过滤器
摘要 在asp.net mvc中除了使用try...catch/finally来处理异常外,它提供了一种通过在Controller或者Action上添加特性的方式来处理异常. HandleErrorA ...
- CentOS7部署Nginx
CentOS7部署Nginx 1.准备工作 Nginx的安装依赖于以下三个包,意思就是在安装Nginx之前首先必须安装一下的三个包,注意安装顺序如下: 1 SSL功能需要openssl库,直接通过yu ...