用union 和 struct 位域操作

很久没有用C 语言中的 union 和 struct 位域操作了。

最近用了一下(当然,我承认是从stackoverflow 上抄的)

需求是这样的,已知一个 LPARAM 整数 3866625 ,求他的第30位的值是多少。

解法也挺简单

int a = 3866625;
a = a>>30 & 0x0001; //注意是右移动30,而不是29,因为第一位是0 ,我一开始就移动的29 结果算错!

但是我偶然在stack over flow 上看到了 另外一种方案

union KeyState
{
    LPARAM lparam;

    struct
    {
        unsigned nRepeatCount : 16;
        unsigned nScanCode : 8;
        unsigned nExtended : 1;
        unsigned nReserved : 4;
        unsigned nContext : 1;
        unsigned nPrev : 1;
        unsigned nTrans : 1;
    };
};

KeyState ks;
ks.lparam = 3866625;
ks.nPrev;  //这就是第30位

然后查了一下union,union的特点是,共享内存,且首地址相同。长度以最大的成员长度计算。

接着是struct 的位域操作符。

struct

{

unsigned a: 1;

unsigned b:2;

}

表示 a 成员占1个字节,b成员占2个字节。

把2者结合起来的效果是

当访问 union 的 nPrev  字段时,其实 是访问的是 :16+8+1+4+1 个位之后的位。且长度为1的值。比较起 位运算,虽然长了一点,但是非常容易理解了

更棒的是,可以任意访问其他的位了了。

这个位运算主要用计算 键盘扫描消息用。

Keystroke Message Flags

The lParam parameter of a keystroke message contains additional information about the keystroke that generated the message. This information includes the repeat count, the scan code, the extended-key flag, the context code, the previous key-state flag, and the transition-state flag. The following illustration shows the locations of these flags and values in the lParam parameter.

An application can use the following values to manipulate the keystroke flags.

KF_ALTDOWN Manipulates the ALT key flag, which indicated if the ALT key is pressed.
KF_DLGMODE Manipulates the dialog mode flag, which indicates whether a dialog box is active.
KF_EXTENDED Manipulates the extended key flag.
KF_MENUMODE Manipulates the menu mode flag, which indicates whether a menu is active.
KF_REPEAT Manipulates the repeat count.
KF_UP Manipulates the transition state flag.
时间: 2025-01-18 14:01:34

用union 和 struct 位域操作的相关文章

【转】c语言位域操作—_结构体内冒号:的使用

原文链接:http://blog.chinaunix.net/uid-22145625-id-1789513.html 这是C语言位域问题 有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位.例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可.为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”.所谓“位域”是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数.每个域有一个域名,允许在程序中按域名进行操作.这样就可以

C语言中struct位域的定义和使用

位域的定义和使用 有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位.例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可.为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”.所谓“位域”是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数.每个域有一个域名,允许在程序中按域名进行操作. 这样就可以把几 个不同的对象用一个字节的二进制位域来表示. 一.位域的定义和位域变量的说明位域定义与结构定义相仿,其形式为:  s

位域操作

看runtime源码时,看到如下声明变量的,变量后分号前加冒号和数字": 数字"即为位域操作. uintptr_t indexed : 1; 1个字节包含8位,有些变量保存的数据不需要占用这么长的空间(比如bool类型,只有两个状态true和false, 1位就可以搞定,剩下的7位就浪费了),这就催生了“位域”结构,位域将1个字节划分成不同的区域,每个区域都有个位域名(可以理解为变量名,上边的代码中位域名为indexed),程序员可以代码通过位域名访问其中的数据. 一. 声明 类型说明

C位域操作

位域的概念 1个字节包含8位,有些变量保存的数据不需要占用这么长的空间(比如bool类型,只有两个状态true和false, 1位就可以搞定,剩下的7位就浪费了),这就催生了“位域”结构,位域将1个字节划分成不同的区域,每个区域都有个位域名,程序员可以代码通过位域名访问其中的数据. 位域的声明 类型 位域名:位域长度; 位域结构体,我理解是一种特殊的结构体,其成员变量都是位域,声明如下 struct 位域结构名 { 类型说明符 位域名:位域长度; ... 类型说明符 位域名:位域长度; }; 基

笔试题之union与struct

union与struct之间的区别,说起来简单,struct内各变量是拥有独立的内存,union里面各变量共享内存,修改一个变量的值也既修改了另一个值. 然而,今天中兴笔试遇到这样一个问题 union { struct { int a; int b; } e; int i; int j; } u; u.i=1; u.j=2; u.e.a=u.i*u.j; u.e.b=u.i*u.j; printf(“%d",u.e.a); printf("%d",u.e.b): 结果是4和1

C语言中位域操作

C语言中位域定义: 以结构体中定义申明变量的形式: 类型说明符 位域名:位域宽度 struct bit{ int a:4; // 申明位域变量a,占用4个bit位宽度 int b:4; // 申明位域变量b,占用4个bit位宽度 int c:4; // 申明位域变量c,占用4个bit位宽度 }; 在gcc编译器中对结构体进行了默认的对齐操作,以下的所有的现象都是基于gcc的编译条 件:1):申明的两个相连的位域变量占位一般都是紧密连接的,例如上面的a和b,或者是b和 c:a占用起始字节的低4位,

C\C++ 位域操作

几篇较全面的位域相关的文章: http://www.uplook.cn/blog/9/93362/ C/C++位域(Bit-fields)之我见 C中的位域与大小端问题 内存对齐全攻略–涉及位域的内存对齐原则 本文主要对位域相关知识进行了一下梳理,参考如下: C语言中的位域 史上最全的C位域总结2 C结构体之位域(位段) C/C++中以一定区域内的位(bit)为单位来表示的数据成为位域,位域必须指明具体的数目. 位域的作用主要是节省内存资源,使数据结构更紧凑. 1. 一个位域必须存储在同一个字节

struct位域

1 总结下 结构体位域的使用 比如  则 struct _COM2 { u8 Len : 1;//低位 u8 EoN : 2; u8 Stop:1; u8 Bps:4;//高位 } union COM { u18 data; struct _COM2 COM2; }; 测试可用: #include "stdio.h" struct _yyy { int qq8:4; int qq7:4; int qq6:4; int qq5:4; int qq4:4; int qq3:4; int q

C语言union关键字,union和struct区别

union 关键字的用法与struct 的用法非常类似. union 维护足够的空间来置放多个数据成员中的“一种”,而不是为每一个数据成员配置空间,在union 中所有的数据成员共用一个空间,同一时间只能储存其中一个数据成员,所有的数据成员具有相同的起始地址.例子如下: union StateMachine { char character; int number; char *str; double exp; }; 一个union 只配置一个足够大的空间以来容纳最大长度的数据成员,以上例而言,