在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;
}
程序的输出结果将会是:
foo之前x的值为0
foo之后x的值为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;
}
现在程序的输出结果如下:
foo之前x = 0
foo之后x = 1
这一次,形式参数
bar
不再是一个int,而是一个指向int的
指针,它接收到
x
的
地址(由调用
foo
时的表达式
&x
给出),而不是x中包含的值。表达式
*bar
表示“获取bar
指向的位置上的值”,因此
*bar = *bar + 1
对应于
x = x + 1
。
由于
scanf()
需要写入其参数,因此它希望那些参数被定义为指针。"%d"转换说明符期望相应的参数为一个指向int的指针(
int *
),"%u"转换说明符期望一个指向无符号int的指针(
unsigned *
),"%s"期望一个指向char的指针(
char *
),"%f"期望一个指向float的指针(
float *
)等等。在你的例子中,由于
a
的类型是
int
,所以你需要使用表达式
&a
来获取一个指针。
请注意,如果
a
本身已经是一个指针类型,那么在调用
scanf()
时就不需要使用
&
运算符。
int main(void)
{
int a, *pa;
...
pa = &a;
scanf("%d", pa);
...
}
请注意,当向函数传递数组时(例如使用“%s”转换说明符读取字符串时),您不需要使用
&
运算符;数组表达式将隐式转换为指针类型:
int main(void)
{
char name[20];
...
scanf("%19s", name); // name implicitly converted from "char [20]" to "char *"
...
}
main
函数返回的是int
类型而不是void
类型。 - Alok Singhal