scanf函数如何在C中工作?

为什么在scanf函数中需要&符号(&)。 以下C代码中的输出或错误类型(编译或运行时)是什么?

 #include  void main() { int a; printf("enter integer:"); scanf("%d", a); } 

& in C是一个返回操作数地址的运算符。 可以这样想,如果你只是给scanf变量a而没有& ,它将被传递给它的值,这意味着scanf将无法设置它的值供你看。 通过引用传递它(使用&实际将指针传递给a )允许scanf进行设置,以便调用函数也可以看到更改。

关于具体的错误,你无法真正说出来。 行为未定义。 有时,它可能会默默地继续运行,而您不知道scanf在程序中的某处更改了某些值。 有时它会导致程序立即崩溃,就像在这种情况下:

 #include  int main() { int a; printf("enter integer: "); scanf("%d",a); printf("entered integer: %d\n", a); return 0; } 

编译它显示:

 $ gcc -o test test.c test.c: In function 'main': test.c:6: warning: format '%d' expects type 'int *', but argument 2 has type 'int' 

并执行显示分段错误:

 $ ./test enter integer: 2 Segmentation fault 

在C中,所有函数参数都按值传递; 函数forms参数的任何更改都不会反映在实际参数中。 例如:

 void foo(int bar) { bar = bar + 1; } int main(void) { int x = 0; printf("x before foo = %d\n", x); foo(x); printf("x after foo = %d\n", x); return 0; } 

该计划的输出将是

 x在foo = 0之前
 foo = 0后的x

因为bar接收x (0)的值,而不是x本身的引用。 更改barx没有影响。

在C中,解决这个问题的方法是将指针传递给变量:

 void foo(int *bar) { *bar = *bar + 1; } int main(void) { int x = 0; printf("x before foo = %d\n", x); foo(&x); printf("x after foo = %d\n", x); return 0; } 

现在程序的输出是

 x在foo = 0之前
 foo = 1后的x

这一次,forms参数bar不是int,而是指向 int的指针 ,它接收x地址 (由foo调用中的表达式&x给出),而不是x中包含的值。 表达式*bar表示“获取位置栏中的值指向 ”,因此*bar = *bar + 1对应于x = x + 1

由于scanf()需要写入其参数,因此它希望将这些参数作为指针键入。 “%d”转换说明符期望相应的参数是指向int( int * )的指针,“%u”转换说明符期望指向unsigned int( unsigned * ),“%s”需要指向char的指针( char * ),“%f”需要指向float( float * )等的指针。在您的示例中,由于a是类型int ,因此需要使用表达式&a来获取指针。

请注意,如果a已经是指针类型,则不需要在对scanf()的调用中使用&运算符:

 int main(void) { int a, *pa; // declare pa as a pointer to int ... pa = &a; // assign address of a to pa scanf("%d", pa); // scanf() will write to a through pa ... } 

还要注意,在将数组传递给函数时(例如使用“%s”转换说明符来读取字符串时),您不需要使用&运算符; 数组表达式将隐式转换为指针类型:

 int main(void) { char name[20]; ... scanf("%19s", name); // name implicitly converted from "char [20]" to "char *" ... } 

如果你问这样的问题,我建议你现在就学习“它就是这样”。

您将了解到您需要一个&符号,因为scanf需要一个或多个指针参数。 如果a是int变量,则它不是指针。 &a(“a的地址”)是指针,因此它将与scanf

这是因为在C中,函数参数是按值传递的 。 为了使scanf()函数修改main()函数中的’ a ‘变量,应将’ a ‘的地址赋予scanf() ,因此使用&符号(地址)。

因为scanf需要一个指向该值将进入的变量(即引用)的指针。

您并不总是需要使用& scanf 。 你需要做的是传递指针 。 如果你是C新手,你应该花一些时间阅读comp.lang.c FAQ:

http://c-faq.com/

特别:

  • 为什么调用scanf(“%d”,i)不起作用?
  • 为什么调用scanf(“%s”,s)有效?

scanf的’&’只需要获取变量的地址。 您可以通过使用指针使用scanf而不使用’&’:

 int myInt; int * pointer_to_int; pointer_to_int = &myInt; scanf("%d", pointer_to_int); 

通常,使用’&’通常比创建指针更容易,以避免使用’&’。