前言
今天要和大家分享的是在函数调用时,形参和实参,传值和传址的区别,还还有在实参为数组的时候,应该怎么去处理!
一、实参和形参是什么?
实参:在函数调用时,传入函数的值叫做实参。
形参:形参出现在 函数定义 中,在整个函数体内都可以使用, 离开该函数则不能使用。
最重要的是:当实参传递给形参的时候,形参只是实参的一份临时拷贝,通过改变形参不能使实参发生改变!!!
二、函数调用时的处理
1.传值
看到传值,那么就是调用函数时的实参是具体的值。
下面我们举例说明:
#include<stdio.h> int add(int x,int y) { int z=0; z=x+y; return z; } int main() { int n=10,m=20; int sum=add(n,m); printf("%d",sum); }
这里就是传值的方式,将n和m的值传给了x和y。
2.传址
看到传址,那么就是调用函数时的实参是变量的地址。
下面我们通过实例来看:
#include<stdio.h> int swap(int *px,int *py) { int z=*px; *px = *py; *py = z; } int main() { int a=10,b=20; swap(&a,&b); printf("%d %d",a,b); }
那么我们可以看出,此函数的作用是交换两个实参的值,更概括的说,就是需要改变实参的值。
我们通过传递a和b的地址,分别给形参中的指针变量int *px=&a,int *py=&b,来通过解引用交换两个变量的值!
指针变量可以通过解引用*px,*py,来通过地址访问到a和b的值,交换*px,*py的值,即交换a,b的值。
那为什么不像第一种那样传值交换呢?
使用的不是同一空间的时候,改变形参不会使实参发生改变。
所以需要将num1和num2的地址传过去,使他们内存空间是一样的,所以改变形参的时候,才会改变实参。
所以,只有调用函数时,函数要改变实参的值的时候,才需要传址过去。
二、传参时,实参为数组arr[ ]的情况
当实参需要把整个数组传给形参时,因为形参是实参的一份临时拷贝,如果数组较大,会占据大量空间资源。所以当我们传数组的时候,只需将数组名(链接中更详细)传到形参即可,通过数组的首元素找到剩下的数组元素。
下面我们具体看一个实例:(二分查找)
//数组传参实际上传递的是数组首元素的地址 //而不是整个数组 //所以在函数内部计算一个函数参数部分的数组的元素个数是不靠谱的 int binary_search(int arr[], int k)//形参arr看上去是数组,本质是指针变量 { //int arr[]相当于int *p. int sz = sizeof(arr) / sizeof(arr[0]);//err int left = 0; int right = sz - 1; while (left <= right) { int mid = left + (right - left) / 2; if (arr[mid] < k) { left = mid + 1; } else if (arr[mid] > k) { right = mid - 1; } else { return mid;//找到了返回下标 } } return -1;//找不到 } int main() { int arr[] = { 1,2,3,4,5,6,7,8,9,10 }; // 数组下标 0 1 2 3 4 5 6 7 8 9 int k = 7; //找到了,返回下标 //找不到,返回-1 int ret = binary_search(arr, k); if (ret == -1) { printf("找不到\n"); } else { printf("找到了,下标是:%d\n", ret); } return 0; }
总结
1.当实参传递给形参的时候,形参只是实参的一份临时拷贝,通过改变形参不能使实参发生改变!!!
2.当需要传参时,我们要考虑是否要改变实参,若要改变实参,则需要将实参的地址传给形参,通过解引用来改变!!
3. 当我们传数组的时候,只需将数组名(链接中更详细)传到形参即可,通过数组的首元素找到剩下的数组元素。
此时形参中int arr[ ]不是整型数组,而是一个指针变量!!