位运算的一个巧妙运用

for(x=0;x<DEVISIONS;x++)
for(y=0;y<DEVISIONS;y++)
 hwndChild[x][y]=CreateWindow(szChildClass,NULL,
   WS_CHILDWINDOW | WS_VISIBLE,
   0,0,0,0,
   hwnd,
(HMENU) (y << 8 | x),
   (HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE),
   NULL);

  上面代码对于一般入门者或者是很少接触过位运算的同志,感觉这句代码(上面蓝色标记部分)真的很难理解,甚至看着头痛!这是啥子呀?抓脑门……

其实如果分析开来并不难懂:这里本来参数是“菜单”,但是对于子窗口来说,该参数称为“子窗口ID”,是一个用来唯一标识子窗口的数值。

MSDN中有说明:

hMenu [in]

     Handle to a menu, or specifies a child-window identifier depending on the window style. For an overlapped or pop-up window,hMenu identifies the menu to be used with the window; it can be NULL if the class menu is to be used.For a child window,hMenu specifies the child-window identifier,an integer value used by a dialog box control to notify its parent about events. The application determines the child-window identifier; it must be unique for all child windows with the same parent window.

既是说明子窗口ID是一个int类型咯…

这个ID是用户自己定义滴,但是注意,不要撞车喔,要不然会很悲剧!

那就说明它是4个字节32位咯…(VC++6.0)

好,回归正题:

在上面的蓝色标识代码中,其实就是用来定义ID滴(有人吐槽:定义一个ID而已,有必要弄出那么多个鸡巴符号么?额~~)。

当然,人家有道理的。为了防止撞车,所以才巧妙的运用了位运算的知识

(y<<8 | x)其实就是把x和y一起合成子窗口ID的,怎么合成?

1.y<<8其实就是把低八位向左移,然后低八位都补0。

假如int y = 1;那么二进制就是 0000 0000 0000 0000 0000 0000 0000 0001;(额……不用算了,就31个0,其实可以省略的,不过为了突出32位,哎…);

那么y<<8 就是                         0000 0000 0000 0000 0000 00010000 0000

2.再看 (y<<8 ) | x,

假如 int x = 2;那么二进制就是0000 0000 0000 0000 0000 0000 0000 0010;

那么现在就简单啦:

用y<<8的结果和上面的进行或运算得:0000 0000 0000 0000 0000 0001 0000 0010;

(运算规则请看前面章节,有详解)。

那么这样,就完成了把x和y的组合了,y存在9~16位,x存在1~8位(也不知道是从哪边开始算,我就大概从右算起吧…哎,学艺不精啊)而且只要x和y的范围不超过…255吧应该,都不会出现子窗口ID撞车的现象。

而且以后需要x和y的值时,还可以通过位运算得出:

x=idfocus&0xFF;
y=idfocus>>8;

这个简单了吧?就是上面的逆运算而已。说明一下0xFF是16进制的(感觉在说废话),也就是(省略24个0)1111 1111

x=idfocus&0xFF;就是取低八位数据赋值给x。其它高位的都是0了。

y=idfocus>>8;就是把9位以后的右移八位,高八位都补0哈。然后赋值给y了。如果是上面的数据,那么结果就是从

0000 0000 0000 0000 0000 0001 0000 0010到

0000 0000 0000 0000 0000 0000 0000 0001

 

总结一下:通过巧妙的位运算可以高效率的解决一些问题,可以把若干个数据保存到各个位上面组合,以后可以通过简单的位运算取出!(又是废话……别砸~)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值