函数的形参(普通形参、指针形参、引用形参)

本文详细解析了编程中普通形参、指针形参和引用形参的工作原理,强调了它们如何影响实参,并指出在修改实参值方面的区别。通过实例说明,帮助读者掌握形参与实参在内存管理上的差异和使用技巧。

以一些代码段为例:

1、普通形参

int n=10;
add1(n);

void add1(int v1) 
{ 
	v1+=1;//对实参无影响 
}

这是最普通的形参方式,形参仅仅为实参的一个副本,对形参的任何操作不会修改实参的值。例中对v1的操作只是修改了实参的一个副本。实参不变

2、指针形参

int *p=&n;

add2 (p) ;//p为指向n的指针
//或者直接
add2(&n)

void add2(int *p) 
{ 
	*p+=1;//实参才会变 
	p+=1;//对实参无影响 
	(*p)++;//实参才会变
}

使用指针做为函数的形参,只有对指针所指对象进行的操作才会改变实参的值。要实现改变实参,还有一种更安全更自然的方法——引用形参。

在执行 add2(&n) 时,系统在内存分配表里增加了一行add2中的p,其地址为新地址,值为&n。操作*p,即是在操作n了。有点类似引用,*p即为n的一个别名

3、引用形参

int a=1,b=2;
swap(a,b);

void swap(int &a,int &b) 
{ 	int temp=a; 
	a=b; //会改变实参的值 
	b=temp; //会改变实参的值 
}

引用形参直接关联到其所绑定的对象,而非这些对象的副本。 所以这种方法可以修改实参的值,而且更加直观。

函数的形参和实参具有以下特点:

1.形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只有在函数内部有效。函数调用结束返回主调函数后则不能再使用该形参变量。

2.实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须具有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使实参获得确定值。

3.实参和形参在数量上,类型上,顺序上应严格一致,否则会发生类型不匹配”的错误。

4.函数调用中发生的数据传送是单向的。即只能把实参的值传送给形参而不能把形参的值反向地传送给实参。 因此在函数调用过程中,形参的值发生改变,而实参中的值不会变化。故需要手动修改才可。

在C语言中,只有指针可以作为函数形参,C语言本身没有引用的概念,引用C++引入的特性。 ### 指针作为函数形参 指针作为函数参数,用于保存函数调用期间传递的参数的地址,这也称为按引用调用。通过引用调用函数时,对引用变量所做的任何更改都会影响原始变量。 #### 使用方法 以下是一个使用指针交换两个数字的示例代码: ```c #include <stdio.h> // 定义一个交换函数形参为两个整型指针 void swap(int *a, int *b); int main() { int m = 10, n = 20; printf("m = %d\n", m); printf("n = %d\n\n", n); // 传递m和n的地址给swap函数 swap(&m, &n); printf("After Swapping:\n\n"); printf("m = %d\n", m); printf("n = %d", n); return 0; } /* 指针 'a' 和 'b' 保存并指向 'm' 和 'n' 的地址 */ void swap(int *a, int *b) { int temp; // 交换指针所指向的值 temp = *a; *a = *b; *b = temp; } ``` 在这个示例中,`swap` 函数接受两个整型指针作为形参。在 `main` 函数中,通过 `&m` 和 `&n` 传递 `m` 和 `n` 的地址给 `swap` 函数。在 `swap` 函数内部,通过解引用操作 `*a` 和 `*b` 来访问和修改 `m` 和 `n` 的值。 #### 特点 - **按引用调用**:对指针所指向的变量进行修改会影响到原始变量,因为指针保存的是原始变量的地址。 - **可以修改实参的值**:如上述示例中,`swap` 函数成功交换了 `m` 和 `n` 的值。 - **传递效率高**:对于大型数据结构,传递指针比传递整个数据结构更高效,因为只需要传递地址,而不是复制整个数据。 ### void* 指针作为函数形参 `void*` 指针作为函数形参时,表示可以接受任意类型的参数,但是函数内在使用时要先强制转换,否则无法使用,不能对 `void*` 类型的指针进行解引用。 #### 使用方法 ```c #include <stdio.h> // 函数接受一个void*类型的指针 void print_int(void *ptr) { // 先将void*指针强制转换为int*指针 int *int_ptr = (int *)ptr; // 解引用int*指针并打印值 printf("The value is: %d\n", *int_ptr); } int main() { int num = 42; // 传递num的地址给print_int函数 print_int(&num); return 0; } ``` 在这个示例中,`print_int` 函数接受一个 `void*` 类型的指针作为形参。在函数内部,先将 `void*` 指针强制转换为 `int*` 指针,然后再进行解引用操作。 #### 特点 - **通用性强**:可以接受任意类型的指针,提高了函数的通用性。 - **使用时需要强制转换**:在函数内部使用 `void*` 指针时,需要将其强制转换为具体的指针类型,才能进行解引用等操作。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猿知

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值