将结构体转为字节流的法子

一、 将基础项目转为byte数组存款和储蓄

 1  private byte[] CreateNetDataByteStream(ushort system, ushort host, ushort type, byte[] tx_buf, ushort msg_len, ushort flag)
 2 
 3         {
 4 
 5             if (tx_buf == null)
 6 
 7             {
 8 
 9                 return null;
10 
11             }
12 
13             try
14 
15             {
16 
17                 byte[] data = new byte[msg_len + NetDataHeadLen];
18 
19                 byte[] u16byte = new byte[2];
20 
21                 u16byte = BitConverter.GetBytes(type);
22 
23                 Array.Copy(u16byte, 0, data, 0, 2);
24 
25                 u16byte = BitConverter.GetBytes(flag);
26 
27                 Array.Copy(u16byte, 0, data, 4, 2);
28 
29                 u16byte = BitConverter.GetBytes(msg_len);
30 
31                 Array.Copy(u16byte, 0, data, 2, 2);
32 
33                // u16byte = BitConverter.GetBytes(CommonConstant.MySystemID);
34 
35                 Array.Copy(u16byte, 0, data, 6, 2);
36 
37               //  u16byte = BitConverter.GetBytes((ushort)CommonConstant.MySeatName);
38 
39                 Array.Copy(u16byte, 0, data, 8, 2);
40 
41                 u16byte = BitConverter.GetBytes(system);
42 
43                 Array.Copy(u16byte, 0, data, 15, 2);
44 
45                 u16byte = BitConverter.GetBytes(host);
46 
47                 Array.Copy(u16byte, 0, data, 17, 2);
48 
49                 tx_buf.CopyTo(data, NetDataHeadLen);
50 
51                 return data;
52 
53             }
54 
55             catch
56 
57             {
58                 return null;
59 
60             }
61 
62         }

2.C#中布局体 与 字节流 互相转化

       

方式一
        //将一个结构序列化为字节数组
               private IFormatter formatter = new BinaryFormatter();
        private ValueType deserializeByteArrayToInfoObj(byte[] bytes)
        {
            ValueType vt;
            if (bytes == null || bytes.Length == 0)
            {
                return null;
            }

            try
            {
                MemoryStream stream = new MemoryStream(bytes);
                stream.Position = 0;
                stream.Seek(0, SeekOrigin.Begin);
                vt = (ValueType)formatter.Deserialize(stream);
                stream.Close();
                return vt;
            }
            catch (Exception ex)
            {
                return null;
            }
        }
        //将一个结构序列化为字节数组
        private byte[] serializeInfoObjToByteArray(ValueType infoStruct)
        {
            if (infoStruct == null)
            {
                return null;
            }

            try
            {
                MemoryStream stream = new MemoryStream();
                formatter.Serialize(stream, infoStruct);

                byte[] bytes = new byte[(int)stream.Length];
                stream.Position = 0;
                int count = stream.Read(bytes, 0, (int)stream.Length);
                stream.Close();
                return bytes;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

方式二
   /// <summary>
        /// 将字节数组转换为结构体
        /// </summary>
        /// <param name="bytes"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public object ByteaToStruct(byte[] bytes, Type type)
        {
            //得到结构体大小
            int size = Marshal.SizeOf(type);
            Math.Log(size, 1);

            if (size > bytes.Length)
                return null;
            //分配结构大小的内存空间
            IntPtr structPtr = Marshal.AllocHGlobal(size);
            //将BYTE数组拷贝到分配好的内存空间
            Marshal.Copy(bytes, 0, structPtr, size);
            //将内存空间转换为目标结构
            object obj = Marshal.PtrToStructure(structPtr, type);
            //释放内容空间
            Marshal.FreeHGlobal(structPtr);
            return obj;
        }
        /// <summary>
        /// 将结构转换为字节数组
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public byte[] StructTOBytes(object obj)
        {
            int size = Marshal.SizeOf(obj);
            //创建byte数组
            byte[] bytes = new byte[size];
            IntPtr structPtr = Marshal.AllocHGlobal(size);
            //将结构体拷贝到分配好的内存空间
            Marshal.StructureToPtr(obj, structPtr, false);
            //从内存空间拷贝到byte数组
            Marshal.Copy(structPtr, bytes,0, size);
            //释放内存空间
            Marshal.FreeHGlobal(structPtr);
            return bytes;
        }

3. C# 结构体字节对齐

1 [structLayout(Layoutkind.sequential,charset=charset.ansi)]
2 Struct Mystruct
3 {
4 [MarshalAs(UnmanagedType.ByValArray,sizeConst=8)]
5 Public byte[] serial;
6 Public byte Type;
7 Public uint Sum;
8 }

在上述结构体与字节流转换第二种办法中,获取结构体长度int size =
Marshal.SizeOf(Mystruct);,并不是壹叁,而是1陆。在内部存款和储蓄器特定项目数据结构开端地址平日有早晚的对齐须求,比如3一人机器的int初阶地址必须是四的平头倍,结构经常也这么

内需加上[structLayout(Layoutkind.sequential,charset=charset.ansi,pack=1)]

C# 将结构体转为字节流的方法,

1、 将基础项目转为byte数组存款和储蓄

 1  private byte[] CreateNetDataByteStream(ushort system, ushort host, ushort type, byte[] tx_buf, ushort msg_len, ushort flag)
 2 
 3         {
 4 
 5             if (tx_buf == null)
 6 
 7             {
 8 
 9                 return null;
10 
11             }
12 
13             try
14 
15             {
16 
17                 byte[] data = new byte[msg_len + NetDataHeadLen];
18 
19                 byte[] u16byte = new byte[2];
20 
21                 u16byte = BitConverter.GetBytes(type);
22 
23                 Array.Copy(u16byte, 0, data, 0, 2);
24 
25                 u16byte = BitConverter.GetBytes(flag);
26 
27                 Array.Copy(u16byte, 0, data, 4, 2);
28 
29                 u16byte = BitConverter.GetBytes(msg_len);
30 
31                 Array.Copy(u16byte, 0, data, 2, 2);
32 
33                // u16byte = BitConverter.GetBytes(CommonConstant.MySystemID);
34 
35                 Array.Copy(u16byte, 0, data, 6, 2);
36 
37               //  u16byte = BitConverter.GetBytes((ushort)CommonConstant.MySeatName);
38 
39                 Array.Copy(u16byte, 0, data, 8, 2);
40 
41                 u16byte = BitConverter.GetBytes(system);
42 
43                 Array.Copy(u16byte, 0, data, 15, 2);
44 
45                 u16byte = BitConverter.GetBytes(host);
46 
47                 Array.Copy(u16byte, 0, data, 17, 2);
48 
49                 tx_buf.CopyTo(data, NetDataHeadLen);
50 
51                 return data;
52 
53             }
54 
55             catch
56 
57             {
58                 return null;
59 
60             }
61 
62         }

2.C#中布局体 与 字节流 互相转化

       

方式一
        //将一个结构序列化为字节数组
               private IFormatter formatter = new BinaryFormatter();
        private ValueType deserializeByteArrayToInfoObj(byte[] bytes)
        {
            ValueType vt;
            if (bytes == null || bytes.Length == 0)
            {
                return null;
            }

            try
            {
                MemoryStream stream = new MemoryStream(bytes);
                stream.Position = 0;
                stream.Seek(0, SeekOrigin.Begin);
                vt = (ValueType)formatter.Deserialize(stream);
                stream.Close();
                return vt;
            }
            catch (Exception ex)
            {
                return null;
            }
        }
        //将一个结构序列化为字节数组
        private byte[] serializeInfoObjToByteArray(ValueType infoStruct)
        {
            if (infoStruct == null)
            {
                return null;
            }

            try
            {
                MemoryStream stream = new MemoryStream();
                formatter.Serialize(stream, infoStruct);

                byte[] bytes = new byte[(int)stream.Length];
                stream.Position = 0;
                int count = stream.Read(bytes, 0, (int)stream.Length);
                stream.Close();
                return bytes;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

方式二
   /// <summary>
        /// 将字节数组转换为结构体
        /// </summary>
        /// <param name="bytes"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public object ByteaToStruct(byte[] bytes, Type type)
        {
            //得到结构体大小
            int size = Marshal.SizeOf(type);
            Math.Log(size, 1);

            if (size > bytes.Length)
                return null;
            //分配结构大小的内存空间
            IntPtr structPtr = Marshal.AllocHGlobal(size);
            //将BYTE数组拷贝到分配好的内存空间
            Marshal.Copy(bytes, 0, structPtr, size);
            //将内存空间转换为目标结构
            object obj = Marshal.PtrToStructure(structPtr, type);
            //释放内容空间
            Marshal.FreeHGlobal(structPtr);
            return obj;
        }
        /// <summary>
        /// 将结构转换为字节数组
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public byte[] StructTOBytes(object obj)
        {
            int size = Marshal.SizeOf(obj);
            //创建byte数组
            byte[] bytes = new byte[size];
            IntPtr structPtr = Marshal.AllocHGlobal(size);
            //将结构体拷贝到分配好的内存空间
            Marshal.StructureToPtr(obj, structPtr, false);
            //从内存空间拷贝到byte数组
            Marshal.Copy(structPtr, bytes,0, size);
            //释放内存空间
            Marshal.FreeHGlobal(structPtr);
            return bytes;
        }

将结构体转为字节流的法子。3. C# 结构体字节对齐

1 [structLayout(Layoutkind.sequential,charset=charset.ansi)]
2 Struct Mystruct
3 {
4 [MarshalAs(UnmanagedType.ByValArray,sizeConst=8)]
5 Public byte[] serial;
6 Public byte Type;
7 Public uint Sum;
8 }

在上述结构体与字节流转换第三种艺术中,获取结构体长度int size =
马尔斯hal.SizeOf(Mystruct);,并不是一三,而是16。在内部存款和储蓄器特定项目数据结构初叶地址常常有必然的对齐须求,比如三拾几个人机器的int发轫地址必须是4的平头倍,结构平常也这么

必要加上[美高梅开户网址 ,structLayout(Layoutkind.sequential,charset=charset.ansi,pack=1)]

转自:

一、 将基础项目转为byte数组存款和储蓄

 1  private byte[] CreateNetDataByteStream(ushort system, ushort host, ushort type, byte[] tx_buf, ushort msg_len, ushort flag)
 2 
 3         {
 4 
 5             if (tx_buf == null)
 6 
 7             {
 8 
 9                 return null;
10 
11             }
12 
13             try
14 
15             {
16 
17                 byte[] data = new byte[msg_len + NetDataHeadLen];
18 
19                 byte[] u16byte = new byte[2];
20 
21                 u16byte = BitConverter.GetBytes(type);
22 
23                 Array.Copy(u16byte, 0, data, 0, 2);
24 
25                 u16byte = BitConverter.GetBytes(flag);
26 
27                 Array.Copy(u16byte, 0, data, 4, 2);
28 
29                 u16byte = BitConverter.GetBytes(msg_len);
30 
31                 Array.Copy(u16byte, 0, data, 2, 2);
32 
33                // u16byte = BitConverter.GetBytes(CommonConstant.MySystemID);
34 
35                 Array.Copy(u16byte, 0, data, 6, 2);
36 
37               //  u16byte = BitConverter.GetBytes((ushort)CommonConstant.MySeatName);
38 
39                 Array.Copy(u16byte, 0, data, 8, 2);
40 
41                 u16byte = BitConverter.GetBytes(system);
42 
43                 Array.Copy(u16byte, 0, data, 15, 2);
44 
45                 u16byte = BitConverter.GetBytes(host);
46 
47                 Array.Copy(u16byte, 0, data, 17, 2);
48 
49                 tx_buf.CopyTo(data, NetDataHeadLen);
50 
51                 return data;
52 
53             }
54 
55             catch
56 
57             {
58                 return null;
59 
60             }
61 
62         }

2.C#中布局体 与 字节流 相互转化

       

方式一
        //将一个结构序列化为字节数组
               private IFormatter formatter = new BinaryFormatter();
        private ValueType deserializeByteArrayToInfoObj(byte[] bytes)
        {
            ValueType vt;
            if (bytes == null || bytes.Length == 0)
            {
                return null;
            }

            try
            {
                MemoryStream stream = new MemoryStream(bytes);
                stream.Position = 0;
                stream.Seek(0, SeekOrigin.Begin);
                vt = (ValueType)formatter.Deserialize(stream);
                stream.Close();
                return vt;
            }
            catch (Exception ex)
            {
                return null;
            }
        }
        //将一个结构序列化为字节数组
        private byte[] serializeInfoObjToByteArray(ValueType infoStruct)
        {
            if (infoStruct == null)
            {
                return null;
            }

            try
            {
                MemoryStream stream = new MemoryStream();
                formatter.Serialize(stream, infoStruct);

                byte[] bytes = new byte[(int)stream.Length];
                stream.Position = 0;
                int count = stream.Read(bytes, 0, (int)stream.Length);
                stream.Close();
                return bytes;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

方式二
   /// <summary>
        /// 将字节数组转换为结构体
        /// </summary>
        /// <param name="bytes"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public object ByteaToStruct(byte[] bytes, Type type)
        {
            //得到结构体大小
            int size = Marshal.SizeOf(type);
            Math.Log(size, 1);

            if (size > bytes.Length)
                return null;
            //分配结构大小的内存空间
            IntPtr structPtr = Marshal.AllocHGlobal(size);
            //将BYTE数组拷贝到分配好的内存空间
            Marshal.Copy(bytes, 0, structPtr, size);
            //将内存空间转换为目标结构
            object obj = Marshal.PtrToStructure(structPtr, type);
            //释放内容空间
            Marshal.FreeHGlobal(structPtr);
            return obj;
        }
        /// <summary>
        /// 将结构转换为字节数组
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public byte[] StructTOBytes(object obj)
        {
            int size = Marshal.SizeOf(obj);
            //创建byte数组
            byte[] bytes = new byte[size];
            IntPtr structPtr = Marshal.AllocHGlobal(size);
            //将结构体拷贝到分配好的内存空间
            Marshal.StructureToPtr(obj, structPtr, false);
            //从内存空间拷贝到byte数组
            Marshal.Copy(structPtr, bytes,0, size);
            //释放内存空间
            Marshal.FreeHGlobal(structPtr);
            return bytes;
        }

3. C# 结构体字节对齐

1 [structLayout(Layoutkind.sequential,charset=charset.ansi)]
2 Struct Mystruct
3 {
4 [MarshalAs(UnmanagedType.ByValArray,sizeConst=8)]
5 Public byte[] serial;
6 Public byte Type;
7 Public uint Sum;
8 }

在上述结构体与字节流转换第二种情势中,获取结构体长度int size =
马尔斯hal.SizeOf(Mystruct);,并不是一三,而是16。在内部存款和储蓄器特定项目数据结构开端地址常常有一定的对齐供给,比如三11个人机器的int伊始地址必须是四的平头倍,结构平时也这么

急需丰盛[structLayout(Layoutkind.sequential,charset=charset.ansi,pack=1)]

将结构体转为字节流的章程, 1、
将基础项目转为byte数组存款和储蓄 一 private byte [] CreateNetDataByteStream(
ushort system, ushort host, ushort type, byte [] tx…

1. 结构体(struct)

一.1 结构体的定义

  • 结构体(struct):是由一密密麻麻具有相同档次或分化品类的数码整合的数额集合,叫做结构。
  • 结构体(struct):是一种复合数据类型,结构类型。
  • 注:“结构”是1种构造类型,它是由若干“成员”组成的。
    每2个分子能够是三个主干数据类型可能又是八个构造类型。
    结构正是1种“构造”而成的数据类型,
    那么在印证和平运动用从前必须先定义它,也正是结构它。仿佛在认证和调用函数从前要先定义壹样。

1.二 C语言中的结构体

  • 说明:在C语言中,结构体(struct)是复合数据类型的壹种。同时也是有个别成分的晤面,那几个成分称为结构体的成员,且这个分子能够为分裂的花色,成员壹般用名字访问。结构体能够被声称为变量、指针或数组等,用以达成较复杂的数据结构。
  • 注:在C语言中,结构体不能够包括函数。
  • 概念与申明: (一)示例代码壹:

    1 struct tag 
    2 {
    3     member-list
    4 }variable-list;
    5 注:struct为结构体关键字;
    6    tag为结构体的标志;
    7    member-list为结构体成员变量列表,其必须列出其所有成员;
    8    variable-list为此结构体声明的变量;
    

    (二)示例代码贰:

     1 //此声明声明了拥有3个成员的结构体,分别为整型的a,字符型的b和双精度的c,但没有标明其标签,声明了结构体变量s1
     2 struct 
     3 {
     4     int a;
     5     char b;
     6     double c;
     7 } s1;
     8 
     9 //此声明声明了拥有3个成员的结构体,分别为整型的a,字符型的b和双精度的c,结构体的标签被命名为SIMPLE,用SIMPLE标签的结构体,另外声明了变量t1, t2[20], *t3
    10 struct SIMPLE
    11 {
    12     int a;
    13     char b;
    14     double c;
    15 };
    16 SIMPLE t1, t2[20], *t3; 
    17 
    18 //可以用typedef创建新类型,此声明声明了拥有3个成员的结构体,分别为整型的a,字符型的b和双精度的c,结构体的标签被命名为Simple2,用Simple2作为类型声明新的结构体变量u1, u2[20], *u3
    19 typedef struct
    20 {
    21     int a;
    22     char b;
    23     double c; 
    24 } Simple2;
    25 Simple2 u1, u2[20], *u3;//若去掉typedef则编译报错,error C2371: “Simple2”: 重定义;不同的基类型
    26 
    27 注:在上面的声明中,第一个和第二声明被编译器当作两个完全不同的类型,即使他们的成员列表是一样的,如果令t3=&s1,则是非法的。
    

    注:在相似情状下,tag、member-list、variable-list那三有些足足要出新3个。

一.三 C++中的结构体

  • 说明:在C语言中,结构体不能够包罗函数。在面向对象的先后设计中,对象具备状态(属性)和作为,状态保存在成员变量中,行为经过成员方法(函数)来落到实处。C语言中的结构体只好描述一个对象的状态,无法描述叁个对象的表现。在C++中,考虑到C语言到C++语言过渡的延续性,对结构体进行了扩充,C++的结构体能够分包函数,那样,C++的结构体也具有类的机能,与class差异的是,结构体包蕴的函数私下认可为public,而不是private。
  • 注:在C++中,结构体能够涵盖函数。
  • 概念与评释:

  • (一)示例代码1:

    1 struct tag 
    2 {
    3     member-list
    4 }variable-list;
    5 注:struct为结构体关键字;
    6    tag为结构体的标志;
    7    member-list为结构体成员变量及成员函数列表,其必须列出其所有成员;
    8    variable-list为此结构体声明的变量;
    

    (2)示例代码二:

     1 #include <iostream> 
     2 
     3 using namespace std;
     4 
     5 struct SAMPLE
     6 {
     7     int x;
     8     int y;
     9     int add() {return x+y;}
    10 }s1;
    11 
    12 int main()
    13 {
    14     cout<<"没初始化成员变量的情况下:"<<s1.add()<<endl;
    15     s1.x = 3;
    16     s1.y = 4;
    17     cout<<"初始化成员变量的情况下:"<<s1.add()<<endl;
    18     system("pause");
    19     return 0;
    20 }
    21 =>没初始化成员变量的情况下:0
    22   初始化成员变量的情况下:7
    

    C++中的结构体与类的区分:
    (1)class中私下认可的成员访问权限是private的,而struct中则是public的。
    (二)class继承暗许是private继承,而从struct继承默许是public继承。

一.4 结构体的成效

  • 在实际上项目中,结构体是大方设有的。研究开发职员常使用结构体来封装一些品质来整合新的门类。由于C语言内部程序相比较简单,研发人士平日选拔结构体成立新的“属性”,其目标是简化运算。
  • 结构体在函数中的功能不是方便,最重大的成效正是包装。包装的功利便是能够另行使用。让使用者不必关注这几个是哪些,只要依据定义使用就足以了。

1.5 结构体的轻重与内部存款和储蓄器对齐

  • 默许的对齐格局:各成员变量在寄放的时候依照在布局中冒出的相继依次申请空间,同时遵照上面包车型客车对齐方式调整职责,空缺的字节VC会自动填写。同时VC为了保险协会的轻重缓急为结构的字节边界数(即该组织中占据最大空间的门类所占用的字节数)的倍数,所以在为最后八个分子变量申请空间后,还会依照需求活动填充空缺的字节。

  • 注:VC对变量存款和储蓄的一个尤其处理。为了抓好CPU的存款和储蓄速度,VC对一些变量的序曲地址做了“对齐”处理。在暗许意况下,VC规定各成员变量存放的前奏地址相对于结构的胚胎地址的偏移量必须为该变量的体系所占据的字节数的倍数。

  • (壹)示例代码一:

    1 struct MyStruct
    2 {
    3     double dda1;
    4     char dda;
    5     int type;
    6 };
    7 //错:sizeof(MyStruct)=sizeof(double)+sizeof(char)+sizeof(int)=13。
    8 //对:当在VC中测试上面结构的大小时,你会发现sizeof(MyStruct)为16。
    

    注:为地点的布局分配空间的时候,VC遵照成员变量出现的一一和对齐形式。

  • (一)先为第二个分子dda一分配空间,其开地方址跟结构的序幕地址一样(刚好偏移量0刚好为sizeof(double)的翻番),该成员变量占用sizeof(double)=几个字节;

  • (贰)接下去为第一个分子dda分配空间,那时下三个足以分配的地方对于协会的起头地址的偏移量为八,是sizeof(char)的倍数,所以把dda存放在偏移量为捌的地方满意对齐形式,该成员变量占用sizeof(char)=二个字节;

  • (三)接下去为首个分子type分配空间,那时下二个足以分配的地方对于组织的发端地址的偏移量为九,不是sizeof(int)=四的倍数,为了满足对齐格局对偏移量的牢笼难题,VC自动填充贰个字节(那四个字节没有放怎么事物),那时下三个方可分配的地点对于组织的苗子地址的偏移量为12,刚好是sizeof(int)=4的翻番,所以把type存放在偏移量为1二的位置,该成员变量占用sizeof(int)=几个字节;
  • 那儿整个结构的分子变量已经都分配了半空中,总的占用的上空尺寸为:捌+壹+叁+4=1陆,刚好为结构的字节边界数(即组织中占据最大空间的档次所占用的字节数sizeof(double)=8)的翻番,所以并未有空缺的字节供给填写。所以1切结构的高低为:sizeof(MyStruct)=8+1+三+4=1陆,在这之中有2个字节是VC自动填充的,未有放其他有意义的东西。

  • (二)示例代码二:调换一下上述例子中MyStruct的成员变量的职位

  • 1 struct MyStruct

    2 {
    3     char dda;
    4     double dda1;
    5     int type;
    6 };
    7 //错:sizeof(MyStruct)=sizeof(double)+sizeof(char)+sizeof(int)=13。
    8 //对:当在VC中测试上面结构的大小时,你会发现sizeof(MyStruct)为24。
    

     

  • 注:为地点的布局分配空间的时候,VC依照成员变量出现的依次和对齐情势。

  • (壹)先为第贰个成员dda分配空间,其开地方址跟结构的序曲地址壹样(刚好偏移量0刚好为sizeof(char)的翻番),该成员变量占用sizeof(char)=一个字节;

  • (二)接下去为第一个成员dda1抽成空间,那时下二个方可分配的地址对于组织的开首地址的偏移量为一,不是sizeof(double)=捌的翻番,须要补足四个字节才能使偏移量变为八(满足对齐情势),因而VC自动填充多少个字节,dda1存放在偏移量为捌的地方上,它占用八个字节;

  • (3)接下去为第一个成员type分配空间,那时下贰个足以分配的地址对于协会的发端地址的偏移量为1陆,是sizeof(int)=四的倍数,满意int的对齐格局,所以不供给VC自动填充,type存放在偏移量为1陆的地址上,该成员变量占用sizeof(int)=6个字节;
    那时整个结构的分子变量已经都分配了半空中,总的占用的半空中尺寸为:壹+七+八+四=20,不是构造的节边界数(即协会中占有最大空间的体系所占据的字节数sizeof(double)=8)的翻番,所以须求填写五个字节,以满意结构的高低为sizeof(double)=8的倍数。所以该协会总的大小为:sizeof(MyStruct)为壹+7+八+肆+四=二4。个中总的有7+四=10个字节是VC自动填充的,未有扬弃何有含义的事物。

  • 字节的对齐方式:

  • 在VC中提供了#pragmapack(n)来设定变量以n字节对齐方式。n字节对齐就是说变量存放的初叶地址的偏移量有二种情形:第1,假若n大于等于该变量所占据的字节数,那么偏移量必须满意暗中同意的对齐格局;第三,假若n小于该变量的品种所占有的字节数,那么偏移量为n的翻番,不用满意暗许的对齐方式。结构的总大小也有个约束原则,分上面两种意况:假如n大于全部成员变量类型所占有的字节数,那么结构的总大小必须为占用空间最大的变量占用的空间数的倍数;不然必须为n的翻番。


注:VC对结构的存储的特殊处理确实提高了CPU存储变量的速度,但有时也会带来一些麻烦,我们也可以屏蔽掉变量默认的对齐方式,自己来设定变量的对齐方式。**
  • (一)示例代码:

     1 #pragmapack(push)//保存对齐状态
     2 
     3 
     4 #pragmapack(4)//设定为4字节对齐
     5 
     6 struct test
     7 {
     8     char m1;
     9     double m4;
    10     int m3;
    11 };
    12 
    13 #pragmapack(pop)//恢复对齐状态
    

     

    注:以上结构的大小为16,上面分析其储存情形。

  • (1)首先为m一分配空间,其偏移量为0,知足大家本人设定的对齐方式(四字节对齐),m1占用三个字节;

  • (二)接着开端为m陆分配空间,那时其偏移量为1,要求补足二个字节,那样使偏移量满意为n=四的翻番(因为sizeof(double)大于n),m四占用九个字节;

  • (三)接着为m三分配空间,那时其偏移量为1二,满足为四的翻番,m三占用6个字节;
    那时已经为拥有成员变量分配了空间,共分配了14个字节,满意为n的倍数。假诺把地点的#pragmapack(4)改为#pragma
    pack(捌),那么我们能够收获结构的轻重缓急为2四。

参考文献: 

[1]《C++全方位学习》范磊——第四章 

[2]《C++程序设计教程(第3版)》钱能——第10章  [3]

 百度搜索关键字:结构体、结构体的坚守、结构体的尺寸与内存对齐

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图