按位AND操作程序执行问题

时间:2017-05-16 14:52:21

标签: c bitwise-and bit-banding

下面是一个程序,我试图重置一个十六进制数字的特定位。位位置,要复位的位数和十六进制值都是用户输入。

头文件

#pragma once

int bit0(int i,unsigned int RegA,unsigned int RegB,int s[]);

C档

#include "stdafx.h"
#include "stdio.h"
#include "conio.h"
#include "iostream"
#include "targetver.h"
#include "bit.h"

int bit0(int i,unsigned int RegA,unsigned int RegB,int s[])
{
    unsigned int j=0;
    unsigned int K=0;
    unsigned int L=0;

    printf("\nThe bit is at s[0] is %x\n", s[0]);   

    for (j=0; j<i; j++)
    {
        K = (1 << s[j]);
        L = ~K;
        RegB = RegA & ~L;
        printf("\nThe bit is %x\n", RegB);

        if (RegB | 0)
        {
            RegB = RegB & ~ (1 << s[j]);
        }
        else
        {
            RegB;
        }
    }

    printf("\nThe new reset bit is %x\n", RegB);

    _getch();
    return 0;
}

主文件

#include "stdafx.h"
#include "stdio.h"
#include "conio.h"
#include "iostream"
#include "targetver.h"
#include "bit.h"

int main()
{
    int i=0;
    int j=0;
    int s[35]={0};
    unsigned int RegA = 0;
    unsigned int RegB = 0;

    printf("Enter the hexa decimal value to be reset ");
    scanf_s("%x", &RegA);
    printf("Entered hexa decimal value is %x ", RegA);

    printf("\nHow many decimal places needs to be reset (0-31) ?");
    scanf_s("%d", &i);

    printf("Enter the decimal places that needs to be reset ");

    for (j=0; j<i; j++)
    {
        scanf_s("%d", &s[j]);
    }

    ///// check the entered hex value on those decimals places as bit 0 or bit 1

    bit0(i,RegA,RegB,s);

    _getch();
    return 0;
} 

我正在编译并运行使用Visual Studio执行上面的代码。

问题出在RegB = RegA & ~L;行的C文件中。 AND操作似乎没有发生,因为我将{0}作为RegB值。

节目输入:

输入要重置的十六进制值:0100 1111

输入的十六进制值为:0100 1111

需要重置多少位小数(0-31):1

输入需要重置的小数位:1

1 个答案:

答案 0 :(得分:0)

当然 你得到0,但这是因为你写的&操作是(全部)正在执行。这是您的代码的相关部分:

    K = (1 << s[j]);
    L = ~K;
    RegB = RegA & ~L;
    printf("\nThe bit is %x\n", RegB);

    if (RegB | 0)
    {
        RegB = RegB & ~ (1 << s[j]);
    }
    else
    {
        RegB;
    }

在我们继续之前,有很多机会可以简化:

  • 变量L让我感到困惑;我只想看~K
  • RegB | 0RegB
  • 等效
  • else阻止无效
  • if块可以安全无条件地执行,因为如果在给定条件为假时执行它,则不会发生任何变化。
  • 虽然您已设置K = (1 << s[j])但之后没有更改它,但您稍后会使用表达式(1 << s[j])重复自己,而不只是说K
  • printf()可能有一些调试工具,但它稍微模糊了计算的细节

这个等效代码更容易推理:

    K = (1 << s[j]);
    RegB = RegA & K;
    RegB = RegB & ~K;

此时问题应该非常明确:无论RegA的值是多少,只要s[j]介于0和30之间, * 你通过首先屏蔽RegB个位中的某些位来计算RegA,然后屏蔽剩余的位。当然,结果总是为0。

* 因为1签名的整数常量,如果实现的int是32位宽,则左 - 移动31个位置会产生超出范围的结果。就标准而言,产生的行为是不确定的。最好通过使用无符号常量来避免此问题,即1U