C语言函数传参总结


前言

本文介绍C函数传参的问题


一、传值方式调用函数

传值实际就是把变量的值拷贝到函数的形式参数,所以在函数体里修改了形参的值不会改变形参。代码如下:

#include <stdio.h>
#include <stdlib.h>

void Swap(int d1, int d2) 
{
	int temp;
	temp = d1;
	d1 = d2;
	d2 = temp;
}
int main() {
	int d1 = 10;
	int d2 = 20;
	printf("交换前:%d, %d\n", d1, d2); // 10, 20
	Swap(d1, d2);
	printf("交换后:%d, %d\n", d1, d2); // 10, 20
}

上面代码执行后,main函数里面的 d1和d2 的值并没有发交换。函数是局部变量的传递,是发生在栈中,main函数中的d1和d2b被复制到函数的形参中,函数里面修改形参值不会改变main中的实参值。

二、地址方式调用函数

传地址就是把变量的地址传给函数的形参,即函数形参用指针去接收这个地址(指针指向了真是变量的地址), 当形参指向地址上的内容修改时,会影响到实参(相当于实参本身的修改)。代码如下:

#include <stdio.h>
#include <stdlib.h>

void Swap(int *d1, int *d2) 
{
	int temp;
	temp = *d1;
	*d1 = *d2;
	*d2 = *temp;
}
int main() {
	int d1 = 10;
	int d2 = 20;
	printf("交换前:%d, %d\n", d1, d2); // 10, 20
	Swap(&d1, &d2);
	printf("交换后:%d, %d\n", d1, d2); // 20, 10
}

上面代码执行后,main函数里面的 d1和d2 的值发生了变化。这个传地址,其实也是值传递,只是这个值是地址。

三、通过指针作为函数参数

使用malloc函数分配空间,如果不正确传参,可能会发生错误。如下代码:

#include <stdio.h>
#include <stdlib.h>

void Passparam(int* param) // 指针变量也是变量
{
	printf("function &param:%p\n", &param); // &param 指针变量在内存中的地址 00AFF880 与实参的地址是不一样的
	printf("function param:%p\n", param); // 00000000 指针变量的值不变(函数传参时,实参与形参的值时相等的,即拷贝一份,但是他们在内存中存这个指针的地址是不一样的)
	param = (int*)malloc(sizeof(int));
	printf("function malloc param:%p\n", param); // 012D0550 为指针变量申请空间(分配地址)
	*param = 55;
	printf("after param:%d\n", *param); // 55
}

int main() {
	int* param = NULL;
	printf("main param:%p\n", param); // 00000000
	printf("main &param:%p\n", &param); // 00AFF954
	Passparam(param); // 传递值(这个值是一个指针)
	printf("main param:%d\n", *param); // 读取访问权限冲突,param是nullptr
}

上述并没有输出想要的结果,虽然函数体中param申请了空间,得到了地址;但是main函数中的param没有分配到地址,所以指向的值没有发生变化。也就是Passparam函数中的int *param 是main函数中的int *param 副本,它是一个局部变量。修改函数中的值时,main中的值是不会变化的。
Passparam函数中(int *param)是一个值,若想输出正确结构,需要一个指向指针的指针来操作指针的地址

#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>

void Passparam(int** param) // 二级指针变量也是变量
{
	printf("function &param:%p\n", &param); // &param 指针变量在内存中的地址 00AFFA58 与实参的地址是不一样的
	printf("function param:%p\n", param); // 00AFFB2C 指针变量的值不变(函数传参时,实参与形参的值时相等的,即拷贝一份,但是他们在内存中存这个指针的地址是不一样的)
	printf("function *param:%p\n", *param); // 00000000 // 二级指针的解引用是一级指针
	*param = (int*)malloc(sizeof(int));
	printf("function malloc param:%p\n", *param); // 00DB0550 为一级指针变量申请空间(分配地址)
	**param = 55; // 一级指针的解引用赋值
	printf("after param:%d\n", **param); // 55
}

int main() {
	int* param = NULL;
	printf("main before param:%p\n", param); // 00000000
	printf("main &param:%p\n", &param); // 00AFFB2C
	Passparam(&param); // 传递值(这个值是指针的地址)
	printf("main after param:%p\n", param); // 00DB0550 实参申请到了地址
	printf("main param:%d\n", *param); // 55
}

总结

一句话:指针也是变量,当指针变量做为函数参数的时候,函数内部无法修改指针的值(就是地址不能在函数里面改变,就像一个整型变量传进去的时候,里面修改变量值,不影响函数外面变量的值),但是可以修改指针指向的变量和指针的值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值