指针作为函数参数传递
目录
----------------------------------------记录一下学习过程----------------------------------------------------
--------如有不足,还请斧正-------
1.整形作为函数参数
先来看一下没有用到指针传递的函数:
对于初学者来说
void Funtion_1(int a) {
a = 20;
}
void main() {
int num = 10;
Funtion_1(num);
printf("改变后的值为:%d\n",num);
}
看到该函数,就会想到运行结果为
改变后的值为:20
实际上该函数运行的结果为:
改变后的值为:10
为什么我们明明已经把参数传到Funtion_1中了,还会这样呢?
这里就要引入两个概念:形参和实参,代码void Funtion_1(int a)里面的a是形参,而main函数里面给Funtion_1传递的num则为实参。
该程序运行时,首先会在内存中创建实参num=10,接着把实参传递到Funtion_1(int a)函数中,该传递是复制,即系统会开辟另一个地址给a 。这样就相当于有两个变量一个num ,一个a。在Funtion_1()中,改变的只是a,而对main()中的num没有影响,所以num的值没有改变。举个例子:把地址比作水桶,在main中创建了一个变量,即有个桶叫num,里面放着10L的水,我们将这个桶传给Funtion_1中,在Funtion_1中又新建了一个桶叫a,里面同样放着与num桶相同升数的水,即为10L,这时将桶a中的水更改为20L,a桶目前拥有20L水,但num桶却只有10L水,a桶的改变不会影响到num桶中水的改变,因为这是两个独立的桶 画图表示为:
那我们该怎么改变传进去的变量呢?
以桶为例子,如果我们能让a桶与Num桶合二为一,变成一个桶呢?那么我们改变a,则Num也会随之改变。
void Funtion_2(int *a) {
*a = 20;
}
void main() {
int num = 10;
Funtion_2(&num);
printf("改变后的值为:%d\n",num);
}
运行结果为:
改变后的值为:20
为什么Funtion_2可以改变结果?
Funtion_2中接收的是一个指针变量,main中传递过去的是num的地址,funtion_2中接收到的则为num的地址,num与a都指向同一片空间,即都为同一个桶
由此可见,我们是否能改变数值,关键要看是值传递,还是址传递。值传递为复制个新的变量,新的变量修改后,并不会影响旧的变量;址传递,为把地址传递过去,两个变量共用同一处地址,做到一改全改。
1.1在函数中交换两个值的易发生错误的地方
void swap_1(int p1, int p2) {
int p = p1;
p1 = p2;
p2 = p;
}
void swap_2(int* p1, int* p2) {
int p= *p1;
*p1 = *p2;
*p2 = p;
}
void swap_3(int* p1, int* p2) {
int* p= p1;
p1 = p2;
p2 = p;
}
void main() {
int a, b, c, d;
a = 1;b = 2;
printf("改变前的a=%d,b=%d\n", a, b);
swap_1(&a, &b);
printf("swap_1改变后的a=%d,b=%d\n\n", a, b);
a = 1; b = 2;
printf("改变前的a=%d,b=%d\n", a, b);
swap_2(&a, &b);
printf("swap_2改变后的a=%d,b=%d\n\n", a, b);
a = 1; b = 2;
printf("改变前的a=%d,b=%d\n", a, b);
swap_3(&a, &b);
printf("swap_3改变后的a=%d,b=%d\n\n", a, b);
}
接着看这些代码:
运行的结果为:
改变前的a=1,b=2
swap_1改变后的a=1,b=2改变前的a=1,b=2
swap_2改变后的a=2,b=1改变前的a=1,b=2
swap_3改变后的a=1,b=2
其中
swap_1,与Funtion_1中的错误一样,为值传递,所以不会交换a和b的值
swap_3, 首先将p1的地址赋值给p,接着将p2的地址赋值给p1,最后将p的地址(即最初p1的地址)赋值给p2。整个过程来说,即将a与b的地址互换,这里的地址交换并不会影响到main函数中的两个地址,所以不会交换a与b的值。涉及到的知识点:通过地址去改变值,通过地址的地址去改变地址的值。
我们将swap_3稍加修改
void swap_4(int** p1, int** p2) {
int** p= *p1;
*p1 = *p2;
*p2 = p;
}
int* aa = &a;
int* bb = &b;
swap_3(&aa, &bb);
改变前的a=1,b=2
swap_4改变后的a=1,b=2
--------------------------------------------------------------------------------------------------------------------------
2.数组作为参数传递
数组进行传参时,传递的数组的地址。
一维数组传参的基本形式:
void arr_1(int arr[3]) {
for (int i = 0; i <= 2;i++) {
printf("%d ",arr[i]);
}
}
void arr_2(int arr[]) {
for (int i = 0; i <= 2; i++) {
printf("%d ", arr[i]);
}
}
void arr_3(int *arr) {
for (int i = 0; i <= 2; i++) {
printf("%d ", arr[i]);
}
}
void main() {
int arr[3] = {1,2,3};
printf("调用arr_1:");
arr_1(arr);
printf("\n调用arr_2:");
arr_2(arr);
printf("\n调用arr_3:");
arr_3(arr);
}
重点在于在函数中修改数组的值:
一般情况下,数组名是数组的首元素的地址:
int arr[3]={1,2,3};
printf("arr:%d",arr);
运行结果-> 1
void arr_3(int *arr) {
for (int i = 0; i <= 2; i++) {
printf("%d ", arr[i]);
}
}
void ArrayChange(int *arr,int k) {
for (int i = 0; i <= k - 1;i++) {
//arr[i] = i * 5;
*(arr+i)=i*5;
}
}
void main() {
int arr[3] = {1,2,3};
printf("修改前:\n");
arr_3(arr);
ArrayChange(arr, sizeof(arr) / sizeof(arr[0]));
printf("\n修改后:\n");
arr_3(arr);
}
由于数组传递过来的是数组的首地址,所以ArrayChange中接收到的也为数组的地址,故为址传递,由前面可知我们可以通过地址去修改mian函数中的值。