0

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

头文件

#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 编译并运行执行上述代码。

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

程序输入:

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

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

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

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

4

1 回答 1

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 | 0相当于简单地RegB
  • 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是有符号整数常量,如果实现的ints 是 32 位宽,则左移 31 位会产生超出范围的结果。就标准而言,结果行为是未定义的。最好通过使用无符号常量来避免这个问题,即1U.

于 2017-05-16T15:47:12.137 回答