我希望用户能够输入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;
}
答案 0 :(得分:0)
opper
是单个char
,是一个字符,但您使用的是%s
,需要char *
一个字符串。您没有收到警告,因为&opper
是char *
。
您的输出类似于“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年,并说这是“一千零二”。