c语言构造gf(2^8)取逆

我问一下这个主函数里的第一个scanf函数将输入改为先c再b,为什么c会为0,b却没事

#include<stdio.h>
#include<string.h>
 unsigned char add(unsigned char a, unsigned char b) 
 { 
    printf("%x",a);
    return a ^ b; 
 } 
unsigned char mul(unsigned char a, unsigned char b) 
  {
    unsigned char p = 0;
    while (a && b) 
     { 
     if (b & 1)
      p ^= a;
     if (a & 0x80) 
          a = (a << 1) ^ 0x1b; 
     else 
          a <<= 1;
     b >>= 1;
    } 
    return p;
 }
 unsigned char inv(unsigned char a) 
 {
    
    for(unsigned char i=0x00;i<0xFF;i++)
    {
        if(mul(i,a)==0x01)
        {
            return i;
        }
    }
} 
int main()
{
    unsigned char c ;
    unsigned char b ;
    scanf("%x %x",&b,&c);
    printf("%x",c);
    //scanf("%x",&b);
    printf("%x",c);
    printf("%x",b);
    printf("加法是0x%X\n",add(c,b));
    printf("乘法是0x%X\n",mul(c,b));
    printf("取逆是0x%X\n",inv(c));
    printf("取逆是0x%X\n",inv(b));
    return 0;
} 
 

只是调整变量的输入顺序的话,不应该出现这种问题才对,我这里测试是完全没有问题的。建议清理工程后,重新编译运行。
下面是我的测试结果。
(1)先输入b,再输入c

img

(2)先输入c,再输入b

img

基于new bing部分指引作答:
根据您的描述,将主函数中的第一个scanf函数的输入顺序改为先输入c再输入b时,c的值变为了0,而b的值不受影响。可能的原因是在输入c之后,还有一个换行符或其他非十六进制字符残留在输入缓冲区中。

当您输入完c的值时,按下回车键会将回车符('\n')添加到输入缓冲区中。然后,在程序执行第二个scanf函数之前,第一个scanf函数已经读取了c的值,但缓冲区中的回车符仍然存在。

接着程序执行第二个scanf函数时,它会尝试读取下一个字节(对应于输入缓冲区中的回车符)。由于回车符不是有效的十六进制字符,scanf函数无法成功解析它。因此,它会忽略该字符,并继续读取下一个有效的十六进制字符,然后将其存储在变量b中。

这就是为什么c的值变为0,而b的值没有受到影响。如果希望避免这种情况,您可以在读取c后使用额外的getchar()函数来清除输入缓冲区中的回车符,或者使用fflush(stdin)来刷新输入缓冲区。这样可以确保第二个scanf函数在正确的位置读取输入。

然而,请注意,使用fflush(stdin)来刷新输入缓冲区是一种不被推荐的做法。根据C语言标准,只有对输出流的刷新是明确定义的行为,对输入流的刷新操作行为是未定义的。因此,更安全和可靠的方法是使用额外的getchar()函数来清除不需要的字符。

除了%x是16进制以外,跟%d一样,它是按4字节int方式读入的
你定义的b和c都是char型,只占1字节,所以按4字节读入的时候会复写其它变量
具体谁在前谁在后,不同编译器是不一样的
这里c定义在前,所以地址也靠前,那么当先给b赋值,再给c赋值时,
给b赋值的时候其实已经将c设置成0了,但是后给c赋值则不影响b,因为b的地址靠后
而如果反过来,先c后b,那么给b赋值的时候将c赋值成0了
-=-=-=-=-
看一下这个图
1234cb,这是变量c和b占据内存的情况
给c赋值时,234c一起被赋值,给b赋值时,34cb一起被赋值,懂了吗