用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_ALTDOWNManipulates the ALT key flag, which indicated if the ALT key is pressed.
KF_DLGMODEManipulates the dialog mode flag, which indicates whether a dialog box is active.
KF_EXTENDEDManipulates the extended key flag.
KF_MENUMODEManipulates the menu mode flag, which indicates whether a menu is active.
KF_REPEATManipulates the repeat count.
KF_UPManipulates the transition state flag.

转载于:https://www.cnblogs.com/songr/p/5018170.html

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值