Skip to content

上一节我们已经学到:函数的参数传递本质传递的是值.

使用函数来交换两变量的值

在main函数中有两个变量a,b.要求你写一个函数来交换这两个变量的值.

首先想到的方法是:

c
#include <cstdio>

void my_swap(int a,int b){
    int t= a;
    a= b;
    b=t;
}

int main(){
    int a=1,b=2;
    my_swap(a,b);
    printf("a=%d,b=%d",a,b);
    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

上面的代码显然是不能成功的,那有什么好的方法呢?

使用指针类型作为参数类型

具体的细节,请看简单指针这一节

c
#include <cstdio>

void my_swap(int *a,int *b){
    int t= *a;
    *a= *b;
    *b=t;
}

int main(){
    int a=1,b=2;
    my_swap(&a,&b);
    printf("a=%d,b=%d",a,b);
    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

为什么使用指针就可以成功呢?因为传递的是变量的地址,虽然my_swap里的参数是局部变量,但里面保存是变量的地址,我们按地址去修改地址指向的变量,所以成功了.

引用型参数

具体细节看引用/别名这一节

c
#include <cstdio>

void my_swap(int &a,int &b){
    int t= a;
    a= b;
    b=t;
}

int main(){
    int a=1,b=2;
    my_swap(a,b);
    printf("a=%d,b=%d",a,b);
    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

为什么可以成功呢?因为函数my_swap的参数类型是别名,相当于原来变量的别名(另一个名字),所以可以修改原来的值.

数组名做为函数的参数

我们已经学过:数组名指向数组起始的地址,那么

  • 如果函数的参数类型是数组,那能不能修改原数组里的值呢?
  • 函数的参数类型为一维数组,怎么书写
  • 函数的参数类型为二维数组,怎么书写

能否修改

c
#include <cstdio>

int a[]= {1,2,3,4};

void change_a(int a[]){
    a[0] = 100;
    a[1] = 100;
    a[2] = 100;
    a[3] = 100;
}

int main(){
    change_a(a);
    int i;
    for (i=0;i<=3;i++){
        printf("a[%d] = %d,",i,a[i]);
    }
    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

上面的代码运行后,可以看到原数组a里的值已经被修改了.所以如果函数的参数类型是数组,能修改原数组里的值

我们注意看函数change_a的形参写法int a[],表明它接收一个int型的一维数组为参数.为什么a[]中括号里不写明数组的长度呢?因为:

  • 函数参数int a[]是局部变量,大小是4Bytes,接收的是一数组的起始地址
  • 在函数内部的下标操作:a[3] = 100,相当于*(a+3) = 100,本质是指针的操作
  • 所以写明长度和不写明长度的效果是一样的,最重要的是知道这个数组是几维的.

二维数组作为参数

c
#include <cstdio>

int a[2][2]= {1,2,3,4};

void change_a(int a[][2]){
    a[0][0] = 100;
    a[0][1] = 100;
    a[1][0] = 100;
    a[1][1] = 100;
}

int main(){
    change_a(a);
    int i,j;
    for (i=0;i<2;i++){
        for (j=0;j<2;j++){
            printf("a[%d][%d] = %d,",i,j,a[i][j]);
        }
        printf("\n");
    }
    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

为什么二维数组作为参数的时候要写明第二个括号里的长度呢?int a[][2].

  • 二维数组的本质就是一维数组,在内存中的存储形式和一维数组一样
  • 只不过我们规定了每多少个元素算一维(一行)
  • a[0][1] = 100这种下标操作相当于*(a+0*2+1)=100指针操作
  • 我们只有知道每一行的长度这个信息,才能进行下标操作.

传递指针

TODO

总结

  • 值传递 (本质上来讲,所有的参数传递都是值传递)
  • 引用传递 参数是类似这种(int &a,int &b)

怎么去记忆?

如果一个函数是void change(int a),那么调用int b= 100;change(b) 相当于

cpp
void change(int a){
    //int a = b; 相当于隐式的调用了这名话
    change(a) // int a = a;
}
1
2
3
4

引用传递

cpp
void change(int& a)
    // int& a = b;
}
1
2
3