1. 探究实参与形参它们相互独立
还记得在函数那一节中讨论过的代码吗?
#include <stdio.h>
void swap(int x, int y)
{
    int temp = x;
    x = y;
    y = temp;
}
int main()
{
    int a, b;
    int temp;
    a = 1;
    b = 2;
    printf("a=%d b=%d\n", a, b);
    //  交换a,b变量
    swap(a, b);
    printf("a=%d b=%d\n", a, b);
    return 0;
}由于主调函数的变量a,b与被调函数的形参x,y它们相互独立。函数swap可以修改变量x,y,但是却无法影响到主调函数中的a,b。
现在利用取地址运算符,分别打印它们的首地址,让我们从内存的角度,来分析一下它们。
#include <stdio.h>
void swap(int x, int y)
{
    //  打印x,y的首地址
    printf("&x= %u\n", &x);
    printf("&y= %u\n", &y);
    int temp = x;
    x = y;
    y = temp;
}
int main()
{
    int a, b;
    int temp;
    a = 1;
    b = 2;
    //  打印a,b的首地址
    printf("&a= %u\n", &a);
    printf("&b= %u\n", &b);
    //  交换a,b变量
    swap(a, b);
    return 0;
}
a在内存中为首地址10484860开始的sizeof(int)字节。
                  b在内存中为首地址10484856开始的sizeof(int)字节。
x在内存中为首地址10484832开始的sizeof(int)字节。
                  y在内存中为首地址10484836开始的sizeof(int)字节。

调用swap函数时,a的值1,传给x。b的值2,传给y。

图中,红色数值为数据对象首地址,黑框内的为变量名和值。 即使x,y已经交换了,但是并未影响a,b。
2. 将指针作为参数传递
                  由于在被调函数内部无法直接修改主调函数的变量。那么我们采用迂回战术,在函数main中取得a、b的指针。将两个指针传递到函数swap。那么,在函数swap内部可以根据这两个信息修改a、b。
                
这下,我们就需要用到指针类型作为参数了。
#include <stdio.h>
void swap(int *x, int *y)
{
    int temp = *x;
    *x = *y;
    *y = temp;
}
int main()
{
    int a, b;
    int temp;
    a = 1;
    b = 2;
    printf("a=%d b=%d\n", a, b);
    //  交换a,b变量
    swap(&a, &b);
    printf("a=%d b=%d\n", a, b);
    return 0;
}
                  现在将x、y改为了int *类型的指针。在主调函数中,对a,b进行取地址获取指针并传入函数swap。在函数swap内部,通过这两个指针交换目标数据对象的值。注意,不是交换指针x,y的值,而是交换目标数据对象a,b的值。所以,需要在指针前使用取值运算符*。
                

图中,红色数值为数据对象首地址,黑框内的为变量名和值。
现在终于能解释为何在使用scanf函数时,需要对变量先取地址再传入参数了。
int n;
scanf("%d", &n);
                  scanf会从读取从键盘的输入,转换后存储到变量n当中。被调函数scanf无法直接修改在主调函数中的变量n。因此,我们将变量n的指针传入scanf函数。通过指针使得被调函数间接地修改主调函数中的变量。
                
 
          