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
本身的引用。 更改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在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:
特别:
- 为什么调用scanf(“%d”,i)不起作用?
- 为什么调用scanf(“%s”,s)有效?
scanf
的’&’只需要获取变量的地址。 您可以通过使用指针使用scanf
而不使用’&’:
int myInt; int * pointer_to_int; pointer_to_int = &myInt; scanf("%d", pointer_to_int);
通常,使用’&’通常比创建指针更容易,以避免使用’&’。