Warning: file_get_contents(https://whois.pconline.com.cn/jsLabel.jsp?ip=127.0.0.1) [function.file-get-contents]: failed to open stream: HTTP request failed! HTTP/1.1 503 Service Temporarily Unavailable in D:\wwwroot\huidong\wwwroot\function.inc.php on line 884
作为一个函数的实现者,如何解析经过或运算的参数原来的值? - huidong

huidong

首页 | 会员登录 | 关于争取 2022 寒假做出汇东网 Ver3.0.0 !
搜索文章


明确或运算和与运算的含义:


或运算:一个位为1,就为1


    00010100

|   00011101

——————

    00011101



与运算:每个位都为1,才为1

    00010100

& 00011101

——————

    00010100



如此一来,我们就可以对经过或运算的值进行判断了,如:

#include <stdio.h>

#define SY_MOVE 0x1
#define SY_SIZE 0x2
#define SY_CLOSE 0x4
#define SY_START 0x8

void setstyle(int style)
{

}

int main()
{
    setstyle(SY_MOVE | SY_CLOSE);
    
    setstyle(SY_SIZE | SY_MOVE);
    
    setstyle(SY_CLOSE | SY_START);
    
    setstyle(SY_SIZE | SY_MOVE | SY_CLOSE);
    
    getch();

    return 0;
}


现在我们要判断setstyle中传入的参数的值都有哪些,可以进行与运算,如:

#include <stdio.h>

#define SY_MOVE 0x1
#define SY_SIZE 0x2
#define SY_CLOSE 0x4
#define SY_START 0x8

void setstyle(int style)
{
    if (style & SY_MOVE)
    {
        printf("SY_MOVE ");
    }
    
    if (style & SY_SIZE)
    {
        printf("SY_SIZE ");
    }
    
    if (style & SY_CLOSE)
    {
        printf("SY_CLOSE ");
    }
    
    if (style & SY_START)
    {
        printf("SY_START ");
    }
    
    
    printf("\n");
}

int main()
{
    setstyle(SY_MOVE | SY_CLOSE);
    
    setstyle(SY_SIZE | SY_MOVE);
    
    setstyle(SY_CLOSE | SY_START);
    
    setstyle(SY_SIZE | SY_MOVE | SY_CLOSE);
    
    getch();

    return 0;
}

也就是说,想要知道哪个样式开启了,就和哪个样式相与即可,因为:


如果传入SY_MOVE | SY_CLOSE

宏定义解释之后那就是 1 | 4

转换成二进制就是 00000001 | 00000100

进行运算就是:


  00000001

| 00000100

——————

  00000101


又因为SY_MOVE表示1,SY_CLOSE表示4,所以第一位和第三位为1表示SY_MOVE属性和SY_CLOSE属性同时开启。

这个判断就可以交给与运算来做。

现在我们知道传入的参数是00000101,所以将其和SY_MOVE进行与运算,即可知SY_MOVE属性是否开启,请看:


00000101 & 00000001


    00000101

& 00000001

——————

    00000001



因为只有第一位都开启,所以与运算的结果为1,即真,这时我们便知道SY_MOVE属性是开启的。

接下来还有三个属性需要判断:SY_SIZE(对应2),SY_CLOSE(对应4), SY_START(对应8)


依次进行判断:





SY_SIZE 00000010

参数 00000101

00000101 & 00000010


    00000101

& 00000010

——————

    00000000


结果为假,SY_SIZE属性未开启




SY_CLOSE 00000100

参数 00000101

00000101 & 00000100


    00000101

& 00000100

——————

    00000100


结果为真,SY_CLOSE属性开启




SY_CLOSE 00000100

参数 00000101

00000101 & 00000100


    00000101

& 00000100

——————

    00000100


结果为真,SY_CLOSE属性开启




SY_START 00001000

参数 00000101

00000101 & 00001000


    00000101

& 00001000

——————

    00000000


结果为假,SY_START属性未开启




综上所述,即可判断一个属性是否开启了。


但是属性的宏定义也是有要求的。


一个属性只能对应一个位的开启,否则程序会误以为其它位也开启了,所以每个宏的值都必须从上一个值继续乘以2(初始值不能为0),如1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768……


如果不这样做的话,程序会误判别的属性也开启了,例如:

#define SY_MOVE 0x2
#define SY_SIZE 0x3


setstyle(SY_SIZE);


此时我只设置了SY_SIZE属性,传入的参数就是0x3,即00000011

但是程序在判断的时候:


if(style & SY_MOVE)

{

    // ...

}


此时参数style为00000011,和SY_MOVE属性相与,会得到:


SY_MOVE = 0x2 = 00000010


00000011 & 00000010


    00000011

& 00000010

——————

    00000010


会得到真,因为参数的第二位开启了。


所以,一个属性只能对应一个位的开启。



总结:

想要知道哪个样式开启了,就和哪个样式相与即可

一个属性只能对应一个位的开启


图片.png




返回首页


Copyright (C) 2018-2024 huidong