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的更多相关文章

  1. 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 ...

  2. namespace、struct、enum、union、string(day01)

    一 C++概述 C++历史背景 )C++的江湖地位 jave C C++ C# python )C++之父:Bjarne Stroustrup(--) ,Cpre,为C语言增加类的机制 ,Bjarne ...

  3. oracle之集合操作函数---minus、union、intersect

    集合操作符专门用于合并多条select语句的结果,包括:UNION,UNION ALL,INTERSECT,MINUS.当使用集合操作函数时,需保证数据集的字段数据类型和数目一致. 使用集合操作符需要 ...

  4. LINQ标准查询操作符(三)——Aggregate、Average、Distinct、Except、Intersect、Union、Empty、DefaultIfEmpty、Range、Repeat

    七.聚合操作符 聚合函数将在序列上执行特定的计算,并返回单个值,如计算给定序列平均值.最大值等.共有7种LINQ聚合查询操作符:Aggregate.Average.Count.LongCount.Ma ...

  5. 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. ...

  6. Linq to SQL -- Union All、Union、Intersect和Top、Bottom和Paging和SqlMethods

    Union All/Union/Intersect操作 适用场景:对两个集合的处理,例如追加.合并.取相同项.相交项等等. Concat(连接) 说明:连接不同的集合,不会自动过滤相同项:延迟. 1. ...

  7. from、where、group、with、having、order、union、limit 的使用

    顺序很重要 每次看数据库的一些语法时,都很自然的略过那一大堆的规则,比如说线下面这段select的语法: select [field1,field2...] func_namefrom table1, ...

  8. Swift中关于集合计算的几种函数记录(intersect、symmetricDifference、union、subtract)

    很久之前用过一次,后来就忘了...扎心,现在记录一下 PS:这几种函数其实不限于swift内的,在JavaScript.python.DB等其他语言,应该也有类似用法,这里我只简单讲了在swift内的 ...

  9. 009-Hadoop Hive sql语法详解4-DQL 操作:数据查询SQL-select、join、union、udtf

    一.基本的Select 操作 语法SELECT [ALL | DISTINCT] select_expr, select_expr, ...FROM table_reference[WHERE whe ...

随机推荐

  1. 鸟哥的私房菜:Bash shell(三)-命令别名与历史指令

    一  命令别名设定: alias, unalias 命令别名是一个很有趣的东西,特别是你的惯用指令特别长的时候!还有, 增设预设的属性在一些惯用的指令上面,可以预防一些不小心误杀档案的情况发生的时候! ...

  2. dll文件反编译,c#、vb动态库反编译

    最近开发遇到一个项目,对方提供一个c#编写的动态库,图片处理需要调用该动态库方法,发现一张图片处理起来需要5s时间,对方无法提供有效解决手段,抱着试一试的想法反编译的对方的动态库,发现其中问题. 一下 ...

  3. 【51nod-1239&1244】欧拉函数之和&莫比乌斯函数之和 杜教筛

    题目链接: 1239:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1239 1244:http://www.51nod. ...

  4. js的继承实现方式

    1. 使用call或者apply来实现js对象继承 function Animal(age){ this.age = age; this.say = function(){ console.log(' ...

  5. 【JavaScript代码实现二】通用的事件侦听器函数

    // event(事件)工具集,来源:github.com/markyun markyun.Event = { // 页面加载完成后 readyEvent : function(fn) { if (f ...

  6. Codeforces Round #353 (Div. 2) A. Infinite Sequence 水题

    A. Infinite Sequence 题目连接: http://www.codeforces.com/contest/675/problem/A Description Vasya likes e ...

  7. Vue集成腾讯地图和几何库

    关于Vue中如何引入腾讯地图,百度搜索中的结果已经非常明确: /** * 腾讯地图. * @param key * @returns {Promise<any>} * @construct ...

  8. 使用依赖关系注入在 ASP.NET Core 中编写干净代码

    ASP.NET Core 1.0 是 ASP.NET 的完全重新编写,这个新框架的主要目标之一就是更多的模块化设计.即,应用应该能够仅利用其所需的框架部分,方法是框架在它们请求时提供依赖关系.此外,使 ...

  9. Eclipse——浏览功能

    一,打开变量声明 或选择opendeclaration就能够查看变量的定义 二.打开类型层次结构(open type hierarchy) 或者点击F4 watermark/2/text/aHR0cD ...

  10. git 分支管理策略 与 物理实现 --author by阮一峰 & 小鱼

    -------------------------下面是阮一峰博士的git branch 逻辑结构图示---------------------------------------------- 如果 ...