scanf()能否将非零输入变为零

scanf()能否将非零输入变为零,c,scanf,C,Scanf,在下面的代码中,main()中的scanf()将其中一个输入数字从非零数字转换为零,如while循环中的调试printf()所示。我已经在几个编译器上测试过它,但结果都是一样的。请帮助我,告诉我为什么会这样。多谢各位 #include <stdio.h> unsigned srl (unsigned x, int k) { /* perform shift arithmetically */ printf("x = %u, (int) x= %d\n", x, (

在下面的代码中,main()中的scanf()将其中一个输入数字从非零数字转换为零,如while循环中的调试printf()所示。我已经在几个编译器上测试过它,但结果都是一样的。请帮助我,告诉我为什么会这样。多谢各位

 #include <stdio.h>

unsigned srl (unsigned x, int k)
{
    /* perform shift arithmetically */
    printf("x = %u, (int) x= %d\n", x, (int) x);
    unsigned xsra = (int) x >> k;
    printf("\nxsra before was: %u\n", xsra);
    unsigned test = 0xffffffff;
    test <<= ((sizeof (int) << 3) - k); // get e.g., 0xfff00...
    printf("test after shift is: %x, xsra & test = %x\n", test, xsra & test);
    if (xsra & test == 0) // if xsrl is positve
        return xsra;
    else
        xsra ^= test;    // turn 1s into 0s

    return xsra;
}

int sra (int x, int k) 
{
    /* perform shift logically */
    int xsrl = (unsigned) x >> k;
    unsigned test = 0xffffffff;
    test << ((sizeof (int) << 3) - k + 1); // get e.g., 0xffff00...
    if (xsrl & test == 0) // if xsrl is positve
        return xsrl;
    else 
                            xsrl |= test;

        return xsrl;
}

int main(void)
{
    int a;
    unsigned b;
    unsigned short n;

    puts("Enter an integer and a positive integer (q or negative second number to quit): ");
    while(scanf("%d%u", &a, &b) == 2 && b > 0)
    {
        printf("Enter the number of shifts (between 0 and %d): ", (sizeof (int) << 3) - 1);
        scanf("%d", &n);
        if (n < 0 || n >= ((sizeof (int)) << 3))
        {
            printf("The number of shifts should be between 0 and %d.\n", ((sizeof (int)) << 3) - 1);
            break;
        }
        printf("\nBefore shifting, int a = %d, unsigned b = %u\n", a, b);
        a = sra(a, n);
        b = srl(b, n);
        printf("\nAfter shifting, int a = %d, unsigned b = %u\n", a, b);
        puts("\nEnter an integer and a positive integer (q or negative second number to quit): ");
    }
    puts("Done!");

    return 0;
}
#包括
无符号srl(无符号x,整数k)
{
/*以算术方式执行移位*/
printf(“x=%u,(int)x=%d\n”,x,(int)x);
无符号xsra=(int)x>>k;
printf(“\nxsra之前是:%u\n”,xsra);
无符号测试=0xFFFFFF;

测试问题在于
n
是一个
unsigned short
,它的大小小于正常的
int
。当您调用
scanf(“%d”、&n);
时,它会将值读入
n
,如果
b
的内存位置正好在
n
之后,它可能会覆盖现有的
b

您只需将有问题的行更改为:

scanf("%hu", &n);

h
无符号短int
的修饰符,from.

无符号短int
的说明符应该是
%hu
,而不是
%u
。如果您让我知道哪一个变为0,那么我就不必自己编译整件事了。。。(事实上,在重新加载并看到艾美的评论后,我可以推测可能是
n
)另外,OP,
n
永远不能是负数,因为它是
无符号的
。他实际上是在用
%d
,而不是
%u
,来表示
n
,尽管仍然不正确。谢谢你,阿梅库和拉斯塔杰迪。你的评论非常贴切,非常有用。这确实是一个典型的溢出。这是你为什么总是应该这样做的另一个例子使用
-Wall
-Wextra
进行编译。谢谢你,lyang。你的答案非常有用。没错,由于输入格式说明符不正确,所以出现了溢出。再次感谢你,RastaJedi。我假设-Wall和-Wextra选项是默认选项,但实际上并非每个编译器都默认