scanf函数如何在C中工作?

时间:2010-01-14 06:57:16

标签: c scanf

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

#include <stdio.h>

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

7 个答案:

答案 0 :(得分:12)

C中的&是一个返回操作数地址的运算符。可以这样想,如果你只是在没有scanf的情况下给a变量&,它将按值传递给它,这意味着scanf不会能够设置它的值让你看。通过引用传递它(使用&实际传递指向a的指针)允许scanf设置它,以便调用函数也能看到更改。

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

#include <stdio.h>
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

答案 1 :(得分:3)

在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 before foo = 0
x after foo = 0

因为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 before foo = 0
x after foo = 1

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

由于scanf()需要写入其参数,因此需要将这些参数作为指针键入。 “%d”转换说明符期望相应的参数是指向int(int *)的指针,“%u”转换说明符期望指向unsigned int(unsigned *),“%s”的指针期望指向char(char *)的指针,“%f”期望指针浮动(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 *"
  ...
}

答案 2 :(得分:2)

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

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

答案 3 :(得分:2)

这是因为在C中,函数参数按值传递。为了让scanf()函数修改main()函数中的“a”变量,“a”的地址将被赋予{ {1}},因此使用&符号(地址)。

答案 4 :(得分:1)

因为scanf需要指向该值的变量(即引用)的指针。

答案 5 :(得分:1)

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

http://c-faq.com/

具体做法是:

答案 6 :(得分:0)

'&amp;'在scanf中只需要获取变量的地址。您可以使用scanf而不使用'&amp;'使用指针:

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

一般情况下,使用'&amp;'通常比创建指针更容易,以避免使用'&amp;'。