为什么printf()解析变量名来访问存储在其中的值但scanf()不能(在C编程中)?

时间:2013-04-15 20:08:50

标签: c printf scanf

scanf()需要一个指针作为参数,但printf不需要。 printf只需要变量的名称,它似乎在某种程度上获得存储在变量的内存位置的值。 为什么scanf不能通过将变量名称解析到内存位置(与printf相同的方式)并将值存储在内存中而以相同的方式运行?

  1. printf(“%d”,& var)和printf(“%d”,var)之间有什么区别
  2. printf(“%p”,& var)和printf(“%p”,var)之间有什么区别

4 个答案:

答案 0 :(得分:5)

C是一种按值传递的语言。如果你要写:

int x;
scanf("%d", x);

scanf不知道在哪里放置扫描结果 - 您需要将指针传递给存储扫描值的内存位置:

scanf("%d", &x);

您还可以创建一个显式指针变量,如果这有助于您理解它:

int *y = &x;
scanf("%d", y);

相反,printf并不关心值的位置,而是值恰好是什么。所以传递价值:

printf("%d", x);

很好。至于你的具体问题(假设int var;):

  

printf("%d",&var)printf("%d",var)

之间有何区别?

严格地说,第一个导致未定义的行为,第二个打印var的值。在实践中,许多实现将在第一种情况下打印var的地址。

  

printf("%p",&var)printf("%p",var)

之间有何区别?

这种情况正好相反。第一个打印var的地址,第二个导致未定义的行为。在实践中,它可能会打印var的值,但您不应该依赖它。要真正正确,第一个也应该是printf("%p", (void *)&var);,但我从未见过你在那里写的东西不能正常工作的实现。

答案 1 :(得分:0)

在第一种情况下,您要打印var的地址。在第二种情况下,val的内容 &valval的地址 scanf获取地址(指针)以获取值

答案 2 :(得分:0)

您可以通过值将变量传递给printf,这是所有printf需要知道的,它只应该打印变量(或表达式)的值。但这对于scanf是不够的,它需要修改你想要从中读取数据的变量所占用的内存。标准输入。这就是为什么scanf需要变量占用内存的地址 - 没有其他方法可以修改变量。

答案 3 :(得分:0)

因为scanf()需要修改其参数。并且,因为在C中,参数没有“通过引用传递”语义,只传递值(这实际上意味着每个参数的值在传递给函数时被复制),因此,只有指针可以用来让函数修改它们的参数。

  

printf("%d", &var)printf("%d", var)之间的区别是什么?

第一个总是调用未定义的行为,如果varintshortchar则第二个不会。

  

printf("%p", &var)printf("%p", var)之间的区别是什么?

第一个总是调用未定义的行为,如果varvoid *则第二个不会。