为什么在scanf
函数中需要&符号(&)。以下C代码中的输出或错误类型(编译或运行时)是什么?
#include <stdio.h>
void main() {
int a;
printf("enter integer:");
scanf("%d", a);
}
答案 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
本身的引用。更改bar
对x
无效。
在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:
具体做法是:
答案 6 :(得分:0)
'&amp;'在scanf
中只需要获取变量的地址。您可以使用scanf
而不使用'&amp;'使用指针:
int myInt;
int * pointer_to_int;
pointer_to_int = &myInt;
scanf("%d", pointer_to_int);
一般情况下,使用'&amp;'通常比创建指针更容易,以避免使用'&amp;'。