手机站
网通分站
电信主站
密 码:
用户名:
当前位置 : 主页>程序设计>C/C++>列表

C语言之C语言的底层操作 (1)

来源:互联网 作者:west263.com 时间:2008-02-23
西部数码-全国虚拟主机10强!40余项虚拟主机管理功能,全国领先!双线多线虚拟主机南北访问畅通无阻!免费赠送企业邮局,.CN域名,自助建站480元起,免费试用7天,满意再付款! P4主机租用799元/月.月付免压金!
问题:位段结构

  struct RPR_ATD_TLV_HEADER
  {
  ULONG res1:6;
  ULONG type:10;
  ULONG res1:6;
  ULONG length:10;
  };

  位段结构是一种特别的结构, 在需按位访问一个字节或字的多个位时, 位结构比按位运算符更加方便。

  位结构定义的一般形式为:

  struct位结构名{

   数据类型 变量名: 整型常数;

   数据类型 变量名: 整型常数;

  } 位结构变量;

  其中: 整型常数必须是非负的整数, 范围是0~15, 表示二进制位的个数, 即表示有多少位。

  变量名是选择项, 能够不命名, 这样规定是为了排列需要。

  例如: 下面定义了一个位结构。

  struct{
   unsigned incon: 8; /*incon占用低字节的0~7共8位*/
   unsigned txcolor: 4;/*txcolor占用高字节的0~3位共4位*/
   unsigned bgcolor: 3;/*bgcolor占用高字节的4~6位共3位*/
   unsigned blink: 1; /*blink占用高字节的第7位*/
  }ch;   

  位结构成员的访问和结构成员的访问相同。

  例如: 访问上例位结构中的bgcolor成员可写成:

  ch.bgcolor

  位结构成员能够和其他结构成员一起使用。 按位访问和配置,方便&节省

  例如:

  struct info{
   char name[8];
   int age;
   struct addr address;
   float pay;
   unsigned state: 1;
   unsigned pay: 1;
  }workers;'

  上例的结构定义了关于一个工从的信息。其中有两个位结构成员, 每个位结构成员只有一位, 因此只占一个字节但保存了两个信息, 该字节中第一位表示工人的状态, 第二位表示工资是否已发放。由此可见使用位结构能够节省存贮空间。

  注意不要超过值限制

  问题:字节对齐

  我在使用VC编程的过程中,有一次调用DLL中定义的结构时,发觉结构都乱掉了,完全不能读取正确的值,后来发现这是因为DLL和调用程式使用的字节对齐选项不同,那么我想问一下,字节对齐究竟是怎么一回事?

  答案和分析:

  关于字节对齐:

  1、 当不同的结构使用不同的字节对齐定义时,可能导致他们之间交互变得很困难。

  2、 在跨CPU进行通信时,能够使用字节对齐来确保唯一性,诸如通讯协议、写驱动程式时候寄存器的结构等。

  三种对齐方式:

  1、 自然对齐方式(Natural Alignment):和该数据类型的大小相等。

  2、 指定对齐方式 :

  #pragma pack(8) //指定Align为 8;

  #pragma pack() //恢复到原先值

  3、 实际对齐方式:

  Actual Align = min ( Order Align, Natual Align )

  对于复杂数据类型(比如结构等):实际对齐方式是其成员最大的实际对齐方式:

  Actual Align = max( Actual align1,2,3,…)

  编译器的填充规律:

  1、 成员为成员Actual Align的整数倍,在前面加Padding。

  成员Actual Align = min( 结构Actual Align,设定对齐方式)

  2、 结构为结构Actual Align的整数倍,在后面加Padding.

  例子分析:

  #pragma pack(8) //指定Align为 8

  struct STest1
  {
  char ch1;
  long lo1;
  char ch2;
  } test1;
  #pragma pack()   

  现在  

  Align of STest1 = 4 , sizeof STest1 = 12 ( 4 * 3 )
  test1在内存中的排列如下( FF 为 padding ):
  00 -- -- -- 04 -- -- -- 08 -- -- -- 12 -- -- --
  01 FF FF FF 01 01 01 01 01 FF FF FF
  ch1 -- lo1 -- ch2
  #pragma pack(2) //指定Align为 2
  struct STest2
  {
  char ch3;
  STest1 test;
  } test2;
  #pragma pack()
  现在 Align of STest1 = 2, Align of STest2 = 2 , sizeof STest2 = 14 ( 7 * 2 )

  test2在内存中的排列如下:  

  00 -- -- -- 04 -- -- -- 08 -- -- -- 12 -- -- --
  02 FF 01 FF FF FF 01 01 01 01 01 FF FF FF
  ch3 ch1 -- lo1 -- ch2

  注意事项:

  1、 这样一来,编译器无法为特定平台做优化,假如效率很重要,就尽量不要使用#pragma pack,假如必须使用,也最好仅在需要的地方进行配置。

  2、 需要加pack的地方一定要在定义结构的头文档中加,不要依赖命令行选项,因为假如很多人使用该头文档,并不是每个人都知道应该pack。这特别表现在为别人研发库文档时,假如一个库函数使用了struct作为其参数,当调用者和库文档研发者使用不同的pack时,就会造成错误,而且该类错误很不好查。

  3、 在VC及BC提供的头文档中,除了能正好对齐在四字节上的结构外,都加了pack,否则我们编的Windows程式哪一个也不会正常运行。

  4、 在 #pragma pack(n) 后一定不要include其他头文档,若包含的头文档中改变了align值,将产生非预期结果。

  5、 不要多人同时定义一个数据结构。这样能够确保一致的pack值。



文章整理:西部数码--专业提供域名注册虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

热点关注
IDC资讯 虚拟主机 域名注册 托管租用 vps主机 智能建站
网站运营 建站经验 策划盈利 搜索优化 网站推广 免费资源
网站联盟 联盟新闻 联盟介绍 联盟点评 网赚技巧
行业资讯 业界动态 搜索引擎 网络游戏 门户动态 电子商务 广告传媒
网络编程 Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术 Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷 Internet Explorer
网页制作 FrontPages Dreamweaver Javascript css photoshop fireworks Flash
程序设计 Java技术 C/C++ VB delphi
网络知识 网络协议 网络安全 网络管理 组网方案 Cisco技术
操作系统 Win2000 WinXP Win2003 Mac OS Linux FreeBSD
返回首页 |关于我们 | 联系我们 | 付款方式 | 创业联盟 | 价格总览 | 资讯中心 | 友情链接 | 网站地图 | 招贤纳士 | RSS