Code-1:
#include<stdio.h>
int main()
{
int i;
scanf("%c", &i);
printf("%c", i);
return 0;
}
代码-2:
#include<stdio.h>
int main()
{
double i;
scanf("%c", &i);
printf("%c", i);
return 0;
}
代码-3:
#include<stdio.h>
int main()
{
float i;
scanf("%c", &i);
printf("%c", i);
return 0;
}
在Code-1和Code-2的情况下,如果我给出"A"或任何字符作为输入,则该字符将打印为输出。 但是在 Code-3 的情况下,如果我给出"A"或任何字符作为输入,则不会给出输出。
这背后的原因是什么?
在此代码中:
#include<stdio.h>
int main()
{
double i;
scanf("%c", &i);
printf("%c", i);
return 0;
}
您不正确地使用scanf
和printf
。使用%c
说明符scanf
,您需要(为了符合标准 C)传递指向char
的指针。使用%c
说明符 在printf
中,您需要传递一个int
值。当你违反规则时,你的程序就会中断,破碎的东西就会出现故障。
在您的特定情况下可能发生的情况是,在scanf
期间,读取的字符偶然留在处理器寄存器中。这可能是处理器寄存器,恰好也用于在函数调用的第二个位置传递整数参数。我们称之为S。当您调用printf
时,编译器将i
的值放入用于传递浮点参数的寄存器中。我们称之为F。这使其他处理器寄存器保持不变。然后,当printf
执行并看到%c
时,它从 S 中获取值。这仍然具有来自scanf
的值,因此它被打印出来。
当您使用float
执行此操作时,由于某种未知原因,S 中的值不会保持不变。在scanf
和printf
之间,编译器可能使用了S来做其他事情。一个区别是,当您使用float
值作为参数时,编译器必须将其转换为double
值(根据 C 规则)。在进行这种转换时,它可能使用S作为地址或其他东西。
在int
的情况下,可能发生的情况是分配给i
的内存以前未在进程中使用过,因此它包含零,因为操作系统在将其提供给进程之前会清除内存。然后scanf
将一个字节放入i
中。您的系统是小端序,这意味着对象的最低寻址字节是值的最不重要字节,因此将字节设置为读取的字符会导致i
具有字节的值。