做的网站怎么申请软件著作权,今天山东一例发生在哪里,南京市秦淮区建设局网站,类似pinterest的网站目录
1.结构体大小的计算
补充#xff08;位段#xff09;
2.枚举的大小#xff08;4个字节#xff09;
3.联合大小的计算 1.结构体大小的计算
#xff08;1#xff09;结构体内存对齐的规则 1. 第一个成员在与结构体变量偏移量为 0 的地址处。 2. 其他成员变量要对…目录
1.结构体大小的计算
补充位段
2.枚举的大小4个字节
3.联合大小的计算 1.结构体大小的计算
1结构体内存对齐的规则 1. 第一个成员在与结构体变量偏移量为 0 的地址处。 2. 其他成员变量要对齐到某个数字对齐数的整数倍的地址处。 对齐数 编译器默认的对齐数 与 该成员大小的 两者之间的较小值 。VS 中默认的值为 8 gcc没有默认对齐数那么对齐数就是该成员的大小 3. 结构体总大小为最大对齐数每个成员变量都有一个对齐数的整数倍。 4. 如果嵌套了结构体的情况嵌套的结构体对齐到自己的最大对齐数的整数倍处结构体的整体大小就是所有最大对齐数含嵌套结构体的对齐数的整数倍。 例如
struct S1
{char c1;//大小为1,默认对齐数为8,取其小就是1,所以其对齐数是1int a;//大小为4,默认对齐数为8,取其小为4,所以其对齐数就是4char c2;
}int main()
{struct S1 s1{0};printf(%d\n,sizeof(s1));
}其内存分配如图所示 其中的成员占了9个内存单元但是结构体的内存大小是其最大对齐数的整数倍这里的最大对齐数是4所以在9以上的最小的4的倍数是12 再来一例与上面同理直接看图
struct S2
{char c1;char c2;int a;
}int main()
{struct S2 s2{0};printf(%d\n,sizeof(s2));
} 成员的内存总共为8个内存单元刚好也是4的倍数 可以看到两个结构体的成员是相同的但是后者占用内存比前者少所以总结起来 将占用内存小的成员写在前面 这样能更加高效的利用空间 2 那么既然有空间的浪费为什么不紧密的存放每一个成员呢内存对齐的意义 1. 平台原因 ( 移植原因 ) 不是所有的硬件平台都能访问任意地址上的任意数据的某些硬件平台只能在某些地址处取某些特定类型的数据否则抛出硬件异常。2. 性能原因 数据结构 ( 尤其是栈 ) 应该尽可能地在自然边界上对齐。 原因在于为了访问未对齐的内存处理器需要作两次内存访问而对齐的内存访问仅需要一次访问。总体来说 结构体的内存对齐是拿空间 来换取 时间 的做法。 3修改默认对齐数 结构在对齐方式不合适的时候可以自己更改默认对齐数。 #pragma 这个预处理指令可以改变默认对齐数例如 #pragma pack(1)设置默认对齐数为1这样每一个结构体成员都是紧密排列的了 #pragma pack(1)//设置默认对齐数为1
struct S2
{char c1;int i;char c2;
};
#pragma pack()//取消设置的默认对齐数还原为默认 补充位段 位段的内存分配 1.位段的成员可以是intunsignedint signedint或者是char(属于整形家族)类型 2.位段的空间上是按照需要以4个字节(int)或者1个字节(char)的方式来开辟的 3.位段涉及很多不确定因素位段是不跨平台的注重可移植的程序应该避免使用位段 struct S
{int a;int b;int c;int d;
};
按照上面的结构体的计算规则那么这个结构体的大小为16
对于位段是8个字节
struct S
{int a:2;//冒号后的数字表示a只需要2个比特位int b:5;int c:10;int d:30;
}
//总共需要47个比特位那么6个字节足够(6*8)48,计算的结果却为8个字节 注意位段是按整型大小的字节进行开辟的 注意
struct S
{int a:2;int b:5;int c:10;int d:33;//不能超过32个比特报错d的位域大小无效
}本来int类型需要占用32位空间现在只需要占用2个比特位的空间位段的使用节省了空间大小 举例
struct S
{char a:3;char b:4;char c:5;char d:4;
}int main()
{struct S s{0};s.a10;//二进制序列1010s.b20;s.c3;s.d4;return 0;} 首先struct S s{0};所以先给s分配8个比特位 如上图所示a只有3个比特位但是s.a10//二进制序列为1010所以内存中只能存3个比特位即1010中的010 s.b20//二进制序列10100占5个比特但是b只有4个比特所以只能传“0100” s.c3//二进制序列011占3个比特但是c有5个比特,前面补0即“00011” s.d4//二进制序列为100但是d占4个比特前面补0即“0100” 所以总体写下来如图所示 阅读内存时内存是16进制数字则四个2进制位为一个16进制从左往右依次读 0010 0010 0000 0011 0000 0100 2 2 0 3 0 4 位段的跨平台问题 1. int 位段被当成有符号数还是无符号数是不确定的。 2. 位段中最大位的数目不能确定。 16 位机器最大 16 32 位机器最大 32 写成 27 在 16 位机器会出问题。 3. 位段中的成员在内存中从左向右分配还是从右向左分配标准尚未定义。 4. 当一个结构包含两个位段第二个位段成员比较大无法容纳于第一个位段剩余的位时是舍弃剩余的位还是利用这是不确定的 总结
跟结构相比位段可以达到同样的效果可以很好的节省空间但是有跨平台的问题存在
应用用位段封装网络上传输的数据包等 2.枚举的大小4个字节
enum Color//颜色
{RED1,GREEN2,BLUE4
};
enum Color clr GREEN;//只能拿枚举常量给枚举变量赋值才不会出现类型的差异。
clr 5;
enum Sex
{MALE,FEMALE,SECRET
}int main()
{enum Sex sMALE;printf(%d\n,sizeof(s));return 0;
}
结果为4 3.联合大小的计算
1计算规则 联合的大小至少是最大成员的大小。 当最大成员大小不是最大对齐数的整数倍的时候就要对齐到最大对齐数的整数倍 union Un
{int a;//成员大小为4,默认对齐数为8,对齐数为4char arr[5]; //成员大小char是1,默认对齐数是8,得到对齐数是1,不要拿数组的大小进行计算
}int main()
{union Un u;printf(%d\n,sizeof(u));return 0;
} 如果联合体如下图所示 那么其占用内存总大小为5个内存单元但是联合的大小 至少是最大成员的大小。 当最大成员大小不是最大对齐数的整数倍的时候就要对齐到最大对齐数的整数倍 5最大成员大小不是最大对齐数4的整数倍所以应该按下图进行内存分配 如图浪费了3个内存单元使得总内存为8个字节为最大字节数4的整数倍