为什么我的程序不会存储第一个用户指定的输入?

时间:2017-01-26 01:34:36

标签: c

我希望用户能够输入3个输入。第一个和第三个是数字,第二个是+的符号。将存储第2和第3个值,但不会存储第1个值。任何想法?

#include <stdio.h>

int main()
{

    int min12;
    char opper;
    int x=0;
    int min13;

    printf("enter the integer number %d\n", x);
    scanf( "%d %s %d", &min12, &opper, &min13);
    printf("%d %s %d", min12, &opper, min13);

    return 0;
}

1 个答案:

答案 0 :(得分:0)

opper是单个char,是一个字符,但您使用的是%s,需要char *一个字符串。您没有收到警告,因为&opperchar *

您的输出类似于“0 + 5”,因为scanf在尝试写入&opper时会覆盖内存。 &opper指向一个字符,+是一个字符,那么问题是什么?

问题是C字符串由空字节终止。字符串总是需要一个额外的字节。所以它试图存储+\0,两个字节。 opper只有一个字节的存储空间,因此它会覆盖恰好是min12的下一个内存块。

你可以通过打印他们的指针来看到这一点。

printf("opper: %p\n", &opper);
printf("min12: %p\n", &min12);

opper: 0x7fff5315f4b7
min12: 0x7fff5315f4b8

min12紧跟在记忆中opper之后。因此scanf将一个数字写入min12,然后将一个字符写入opper,字符串的空字节溢出到min12,导致其第一个字节为0

相反,请将%c用于单个字符。您确实将opper的地址传递给scanf,因为它需要写入该内存,但是您将其按值传递到printf,因为printf只需读取一个字节。

scanf( "%d %c %d", &min12, &opper, &min13);
printf("%d %c %d", min12, opper, min13);

因为min12是4或8个字节,所以你可以通过将第一个字节归零来说明数字的存储方式,从而得到一些奇怪的效果。

enter the integer number 0
2147483647 + 5
2147483392 + 5

2147483647是0x7FFFFFFF,这是您可以安全地存储在32位有符号整数中的最大数字。 2147483392是0x7FFFFF00,显示被归零的字节。

但是等等,是不是min12的第一个字节为零?是。不应该是16777215吗?至0x00FFFFFF?不,不在我的机器上。这说明my x86 processor is little-endian,意味着最低有效字节位于最低内存插槽。基本上,数字会根据您的期望向后存储。这就像写2001年,并说这是“一千零二”。