c++函数参数的传递方式

1 值传递

(1) 普通变量作为函数参数传递

值传递(单向传递):实参传递给形参 而形参的值无法传递给实参

int max(int a,int b)
{
	return a>b?a:b;
}
int swap(int a,int b)
{
	 int tmp=a;
	 a=b;
	 b=tmp;
	 return 0;
}
int main()
{
	int a=1,b=2;
	int m=max(a,b);
	swap(a,b);
	printf("%d %d",a,b);
	return 0;
}

该程序求最大值结果没问题,但交换两数有问题。
形参(函数定义处)为普通形式
实参(函数调用处)为普通形式
函数调用时,发生 形参=实参 的赋值

值传递本质是因为形参和实参存储在不同的内存地址中

(2). 变量地址作为函数参数传递

实参为变量地址,形参为指针变量
函数调用时,发生 形参=实参 的赋值,即让指针指向变量

//int* p=&a;

int main()
{
 int a=1,b=2;
 swap(&a,&b);
 printf("%d %d",a,b);
 
 int *p,*q;
 p=&a;
 q=&b;
 swap(p,q);//此时p,q 指代的也是地址,无需加&
 printf("%d %d",*p,*q);
 return 0;
}
int swap(int*a,int*b)
{
 int tmp=*a;
 *a=*b;
 *b=tmp;
 return 0;
}

本例中的两种形式

形参实参
指针地址
指针指针

以下为本例中的两种形式的函数片段

实参

 swap(&a,&b);

实参

 int *p,*q;
 p=&a;
 q=&b;
 swap(p,q);

形参

 int swap(int*a,int*b)

注意:此时仍为值传递,只是传递的值是实参的地址。

除了形参和实参的形式,在使用变量地址作为函数参数传递时,

  • 如果被调用函数中改变的指针内容要回传给主调函数,
    那么,要在函数定义时,对指针指向的内容进行修改,如本例中swap()函数体内
 int tmp=*a;
 *a=*b;
 *b=tmp;

操作的是p,q所指向的地址内存储的变量,而不是操作的p,q

  • 当在函数体内对指针地址进行修改,而函数没有返回值,如
    p++
    p=(int *)malloc(sizeof(iint));
    等,
    则不会返回给主调函数。

(3) 一维数组名作为函数参数传递

(1)用数组名作为实参,实际上是传递的数组的起始地址

  • 实参
int a[10];
select(a,10);

对于实参: 因为数组的名字本身就是起始地址,所以不用再在数组名字前加 取地址符号&

  • 形参

当用数组名作为实参时

对于形参:一维数组退化为指针变量

int select(int a[],n); //int a[] 表示数组的名字,[]只表示是数组类型,无其他含义。
int select(int *a,n);

(2)数组作为参数传递的组合

实参形参
数组名数组名
数组名指针
指针指针
指针数组

2. 引用作为函数参数传递

(1)特点

  • 引用是变量的别名,
  • 引用不是一种数据类型。
  • 引用与原始变量使用同一个内存地址
    这也就与 值传递 区别开来。
  • c++拥有此特性,而c中没有,是c++有别于c的性质之一,
    也就是说,c只能通过值传递的方式进行参数的运算处理,

(2)使用方式

int a;
int &b=a;//① 
printf("%p %p",&b,&a);0028FF18 0028FF18

此段代码,声明b是a的引用。

  • 此时,操作b也就相当于操作a。操作a也意味着操作b(传递性)
  • 一旦声明了引用b,就不能让b再作为另外变量的引用。(唯一性)
  • 取引用的地址 &b 等同于取所引用的变量的地址&a
int *p=&a;//②

注意:②的&是地址符,有别于①&表示的引用符号

(3)引用作为函数的参数进行传递

int main()
{
 int a=1,b=2;
 swap(a,b);
 printf("%d %d",a,b);
 return 0;
}
int swap(&a1,&b1)
{
 int tmp=a1;
 a1=b1;
 b1=tmp;
 return 0;
}

形参为变量的引用 ——&狗

狗 为指向整型的指针变量,则形参为 int* &a

#include <stdio.h>
#include <malloc.h>

typedef char Element;
typedef struct
{
	Element data;
	struct LNode* next;
}LNode;

//初始化头节点
int initList(LNode *&A)
{
	//1 分配空间
	A=(LNode*)malloc(sizeof(LNode));//申请A的头结点空间
	//2 指针指向NULL
	A->next=NULL;//初始时头结点后面指向NULL
	return 0;
}
int main()
{
	LNode *L=NULL;
	initList(L);
	return 0;
}

3 总结

在c语言中,三种内容传递方式

将修改后的内容传给调用者时,有三种方式,
1 一种是设定返回值 return——但只能返回一个变量。当然可以通过数组或者结构体存储多个变量的组合
2一种是使用 值传递的指针方式 (上述方式2 )—— 形参为指针类型,实参为变量地址的方式
3 定义全局变量,在某处修改该变量值,则全局有效

在c++中,4种内容传递方式

当子函数中涉及对输入的形参进行修改的语句,并需要将修改后的内容返回给调用者,则使用
1 值传递的指针方式
2 引用 方式传递,
3 定义全局变量,在某处修改该变量值,则全局有效
4 return+值传递

而后者更节省内存,因为引用和所引用的变量为同一内存地址。*

4 参考文献

《c语言程序设计》谭浩强
《c++程序设计》 谭浩强

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值