为什么字符可以存储在 int 类型变量和双精度类型变量中并从中打印,但不能从浮点类型变量中存储和打印?



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;
}

您不正确地使用scanfprintf。使用%c说明符scanf您需要(为了符合标准 C)传递指向char的指针。使用%c说明符 在printf中,您需要传递一个int值。当你违反规则时,你的程序就会中断,破碎的东西就会出现故障。

在您的特定情况下可能发生的情况是,在scanf期间,读取的字符偶然留在处理器寄存器中。这可能是处理器寄存器,恰好也用于在函数调用的第二个位置传递整数参数。我们称之为S。当您调用printf时,编译器将i的值放入用于传递浮点参数的寄存器中。我们称之为F。这使其他处理器寄存器保持不变。然后,当printf执行并看到%c时,它从 S 中获取值。这仍然具有来自scanf的值,因此它被打印出来。

当您使用float执行此操作时,由于某种未知原因,S 中的值不会保持不变。在scanfprintf之间,编译器可能使用了S来做其他事情。一个区别是,当您使用float值作为参数时,编译器必须将其转换为double值(根据 C 规则)。在进行这种转换时,它可能使用S作为地址或其他东西。

int的情况下,可能发生的情况是分配给i的内存以前未在进程中使用过,因此它包含零,因为操作系统在将其提供给进程之前会清除内存。然后scanf将一个字节放入i中。您的系统是小端序,这意味着对象的最低寻址字节是值的最不重要字节,因此将字节设置为读取的字符会导致i具有字节的值。

最新更新