在c中使用位和字节

在c中使用位和字节,c,byte,masking,bits,C,Byte,Masking,Bits,我已经检查了已经发布的问题,无法找到问题的解决方案 我正在制作一个控制台程序,它输入两个变量:1是一个字节,另一个是我只需要使用掩蔽和if语句就可以从该字节获得的位数 int E1 () { unsigned char a, b, c; printf("Number (byte):"); scanf("%d", &a); a= (unsigned char)a; printf("\n Bit you want to output (between

我已经检查了已经发布的问题,无法找到问题的解决方案

我正在制作一个控制台程序,它输入两个变量:1是一个字节,另一个是我只需要使用掩蔽和if语句就可以从该字节获得的位数

int E1 () {
    unsigned char a, b, c;

    printf("Number (byte):");
    scanf("%d", &a);
    a= (unsigned char)a;
    printf("\n Bit you want to output (between 0 and 7) :");
    scanf("%d", &b);
    b=(unsigned char)pow((float)2.0,b);
    printf("Mask is: %d", b);
    c= a & b; //<-- This returns 0
    if (c>0) {
    printf("\n\nThe bit is: 1");
    }
    else {
        printf("\n\nThe bit is: 0");
    }
    return 0;
}
inte1(){
无符号字符a、b、c;
printf(“数字(字节):”;
scanf(“%d”和“&a”);
a=(无符号字符)a;
printf(“\n要输出的位(介于0和7之间):”;
scanf(“%d”和“b”);
b=(无符号字符)pow((浮点)2.0,b);
printf(“掩码为:%d”,b);
c=a&b;//0){
printf(“\n\n位为:1”);
}
否则{
printf(“\n\n位为:0”);
}
返回0;
}
我问过我的老师,他说应该可以。我试过了,但没用。他使用的是Visual Studio Express,这是一个可以从Microsoft网站获得的免费版本,我使用的是Code::Blocks(以防这会对结果产生影响)。我在我认为问题所在的地方添加了一条注释,但不确定


谁能帮我一下吗。提前感谢。

使用
1使用
1一些测试告诉我这部分是错误的:

scanf("%d", &a);
这实际上是未定义的行为:它可能有效,也可能无效,但你不能真正依赖任何东西。这是因为,
a
只是一个1字节的字符,而
%d
需要一个4字节的整数,这意味着
scanf
写入四个字节的内存,而不是一个字节

这有一个不幸的副作用,即第二次调用(对
scanf(“%d”和&b)
)可能会使用存储程序中某些其他变量的内存,在本例中是
a
。这将被覆盖并设置为0,导致表达式
0&b
,其计算结果当然为
0

解决此问题的正确方法是使用
%hhd
而不是
%d
,这使得
scanf
期望使用
char
而不是
int
,并且只写入1字节内存


关于代码的旁注

  • a=(无符号字符)a是无用的,因为
    a
    已经是
    unsigned char
    类型

  • 正如他在回答中指出的,你应该使用
    b=(1一些测试告诉我这部分是错误的:

    scanf("%d", &a);
    
    这实际上是未定义的行为:它可能工作,也可能不工作,但你不能真正依赖任何东西。这是因为,
    a
    只是一个1字节的字符,而
    %d
    需要一个4字节的整数,这意味着
    scanf
    会写入四个字节的内存,而不是一个字节

    这有一个不幸的副作用,即第二次调用(对
    scanf(“%d”和&b)
    )可能会使用存储程序中某些其他变量的内存,在本例中为
    a
    。这会被覆盖并设置为0,导致表达式
    0&b
    ,其计算结果当然是
    0

    解决此问题的正确方法是使用
    %hhd
    而不是
    %d
    ,这使得
    scanf
    期望使用
    char
    而不是
    int
    ,并且只写入1字节内存


    关于代码的旁注

    • a=(unsigned char)a;
      没有用处,因为
      a
      已经是
      unsigned char
      类型

    • 正如他在回答中指出的,你应该使用
      b=(1)好的,我已经尝试了您建议的更改,这次我尝试了运行调试器。显然,正如您所说:它占用的字节比应该的多。第一次运行scanf时,它将值200保存在变量“a”中。第二次它将第二个值3保存在另一个变量“b”中,但它将变量“a”覆盖为0(注意:我在scanf函数中使用“%hhd”)。有人知道如何阻止它这样做吗?可能是因为我使用的是x64操作系统?您使用的是
      scanf(“%hhd”,&b)
      还有吗?那么它不应该真的覆盖任何内容。如果您的代码是定义良好的行为,那么您使用的是64位操作系统这一事实应该不会有太大影响。这里有一个固定版本的代码,我很确定它应该可以正常工作(至少对我来说是这样):复制您的代码并编译。尝试使用数字200和第3位(应为“1”)并输出“0”。您使用的是x32操作系统还是x64操作系统?您使用的是Windows吗?因为如果您使用。解决此问题的最简单方法是使用较大的数据类型,如
      int
      ,而不是
      无符号字符
      ,然后使用scanf(“%d”和(&a)
      应该也能正常工作。好吧,我已经尝试了您建议的更改,这次我尝试了运行调试器。显然,正如您所说:它占用的字节比应该的多。第一次运行scanf时,它将值200保存在变量“a”中。第二次它将第二个值3保存在另一个变量“b”中,但它的overr将变量“a”设置为0(注意:我在scanf函数中使用“%hhd”)。有人知道如何阻止它这样做吗?可能是因为我使用的是x64操作系统?您使用的是
      scanf(“%hhd”,&b)
      还有吗?那么它不应该真的覆盖任何内容。如果您的代码是定义良好的行为,那么您使用的是64位操作系统这一事实应该不会有太大影响。这里有一个固定版本的代码,我很确定它应该可以正常工作(至少对我来说是这样):复制您的代码并编译。尝试使用数字200和第3位(应为“1”)并输出“0”。您使用的是x32操作系统还是x64操作系统?您使用的是Windows吗?因为如果您使用。解决此问题的最简单方法是使用较大的数据类型,如
      int
      ,而不是
      无符号字符
      ,然后使用scanf(“%d”和&a)
    也应该可以正常工作。
    scanf("%d", &a);
    
    printf("The bit is: %d", 1 & a>>b);