按位存储
2015-08-08 15:13
281 查看
在编程中遇到处理位的运算时,一般用结构体定义位长度;比如在发送邮件程序中,数据必须由24位(3个字节)转化为4个字节(每个字节6位),这样才能被邮件服务器识别。
需要注意的是:
(1)数据在计算机中存储方式,比如:
数值: 0x99
存储:1001 1001
但是位段在内存中的存储是从右向左,看下面例程:
邮件发送代码的转换如下:
结果:
(2)《C和指针》指出:
注重可移植性的程序应该避免使用位段。由于下面这些与实现有关的依赖性、位段在不同的系统中可能有不同的结果。
1、int位段被当作有符号数还是无符号数。
2、位段中位的最大数目。许多编译器把位段成员的长度限制在一个整形值的长度之内,所以一个能够运行于32位整数的机器上的位段声明可能在16位整数的机器上无法运行。(注:现在也有64位机器)
3、位段中的成员在内存中是从左向右分配的还是从右向左分配的。
4、当一个声明指定了两个位段,第2个位段比较大,无法容纳于第1个位段剩余的位时,编译器有可能把第2个位段放在内存的下一个字,也可能直接放在第1个位段后面,从而在两个内存位置的边界上形成重叠。
由上面的论述可见,位段在内存中的表示没有统一的标准,各家编译器厂商实现的方式可能不一样。注意内存大小端表示的不同
需要注意的是:
(1)数据在计算机中存储方式,比如:
数值: 0x99
存储:1001 1001
但是位段在内存中的存储是从右向左,看下面例程:
#include <stdio.h> #include <stdlib.h> union share { char val; struct STR1 { unsigned a : 3; unsigned b : 2; unsigned c : 3; }str1; struct STR2 { unsigned b1 : 5; unsigned b2 : 2; }str2; }; //0x99 // 1001 1001 int main(void) { union share m_struct; m_struct.val = 0x99; // 1001 1001 printf("sec1: %d\n", m_struct.str1.a); //001 printf("sec2: %d\n", m_struct.str1.b); //11 printf("sec3: %d\n", m_struct.str1.c); //100 printf("b1: %d\n", m_struct.str2.b1); //11001 printf("b2: %d\n", m_struct.str2.b2); /00 }程序运行结果:
sec1: 1 sec2: 3 sec3: 4 b1: 25 b2: 0
邮件发送代码的转换如下:
typedef struct Base64Cov { unsigned int sect1 : 6; unsigned int sect2 : 6; unsigned int sect3 : 6; unsigned int sect4 : 6; }BASE64COV_S; int main(void) { int a = 0x030201; //10; BASE64COV_S* pst; pst = (BASE64COV_S*)&a; // 0000 0011 0000 0010 0000 0001 printf("%d\n", pst -> sect1); printf("%d\n", pst -> sect2); printf("%d\n", pst -> sect3); printf("%d\n", pst -> sect4); }
结果:
1 8 48 0
(2)《C和指针》指出:
注重可移植性的程序应该避免使用位段。由于下面这些与实现有关的依赖性、位段在不同的系统中可能有不同的结果。
1、int位段被当作有符号数还是无符号数。
2、位段中位的最大数目。许多编译器把位段成员的长度限制在一个整形值的长度之内,所以一个能够运行于32位整数的机器上的位段声明可能在16位整数的机器上无法运行。(注:现在也有64位机器)
3、位段中的成员在内存中是从左向右分配的还是从右向左分配的。
4、当一个声明指定了两个位段,第2个位段比较大,无法容纳于第1个位段剩余的位时,编译器有可能把第2个位段放在内存的下一个字,也可能直接放在第1个位段后面,从而在两个内存位置的边界上形成重叠。
由上面的论述可见,位段在内存中的表示没有统一的标准,各家编译器厂商实现的方式可能不一样。注意内存大小端表示的不同
相关文章推荐
- Valid Palindrome
- 存储着色器
- 并发:Callabel 接口
- 手机开发之H5+规范的原生UI警示框
- UITextField
- dubbo总结(7)dubbo注册中心集群
- 利用HttpClient抓取话费详单等信息
- leetcode--Word Break II
- Inversion(hdu 4911)
- 周赛 大数
- 模拟 codeforces567B Berland National Library
- Hibernate中get和load方法的区别
- Android学习笔记之常用控件
- codeforces Round #Pi (div.2) 567ABCD
- 模拟电子开关
- 从底层角度看ASP.NET-A low-level Look at the ASP.NET...
- [Wireshark]_003_电子邮件抓包分析
- 黑马程序员——Java基础语法---数组
- Watering Grass
- Maven配置总结