上一节我们已经学到:函数的参数传递本质传递的是值.
使用函数来交换两变量的值
在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
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
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
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
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
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
2
3
4
引用传递
cpp
void change(int& a)
// int& a = b;
}
1
2
3
2
3