计算机程序设计c++ 5-2:参数的传递方式

本文详细讲解C++中值传递、引用传递和指针传递的区别,包括原理、优点、实例和适用场景。了解何时选择哪种方式,以及数组和结构体传递的特殊处理方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参数的传递方式

C++中参数有三种传递方式:

  • 值传递
  • 引用传递
  • 指针传递

值传递

调用时,将实参的值传递给对应的形参,这就是值传递。

由于形参有自己独立的存储空间,又作为函数的局部变量使
用,因此在函数中对形参值的任何修改都不会改变实参变量的值

好处:
减少函数之间的数据依赖,增强了函数自身的独立性

注意:函数的形参声明为简单类型或结构类型变量,实参与形参将采用值方式传递

例子: 验证在值传递下,不改变实参的值

void swap(int a, int b)
{
	int temp;
	temp = a;
	a = b;
	b = temp;
}

int main()
{
	int a = 1, b = 2;
	cout << "Before exchange:a= " << a << ", b= " << b << endl;
	swap(a, b);
	cout << "After exchange:a= " << a << ",b= " << b << endl;
	return 0;
}

// Before exchange  a = 1, b = 2;
// After exchange a = 1, b =2;
// 没有发生改变

调用前实参a,b有自己的存储空间,并有初值
调用函数时,为形参x,y分配存储空间,并接收实参的值
在这里插入图片描述

引用传递

引用
引用是一种特殊的变量,它被认为是一个变量的别名
引用定义的格式如下:
<数据类型> &<引用名>=<目标变量名>;
其中:&为引用(变量)的标志符号,<引用名>是一个标识符。
<数据类型>为<目标变量>的类型。
例如:int a, &b=a;
该例说明了a是一个整型变量,b是一个引用整型变量a的引用,即b是a变量的一个别名。这时,使用a与使用b是等价的

对引用的说明:

  • 定义一个引用,其实是为目标变量起一个别名。引用并不分配独立的内存空间,它与目标变量共用其内存空间
  • 定义一个引用(变量)时,如果该引用不是用作函数的参数或返回值,则必须提供该引用的初值(即必须提供引用的目标变量名)
  • 使用引用与使用目标变量效果是相同的
int main()
{
int a=2,&b=a;
cout<<&a<<“ ”<<&b<<endl;//输出变量的地址
cout<<a<<“ ”<<b<<endl; //输出变量的值
return 0;
}

// 0xxxx  0xxx
// 2 2

在这里插入图片描述
引用传递

  • 为实现引用传递,这时函数的形参应定义为引用类型变量,而对应的实参应为变量名,该变量将作为引用的目标变量名
  • 函数调用时,作为形参的引用变量并不分配新的内存空间,它将作为实参变量的别名与其共用内存
  • 使用引用参数可以直接操作实参变量,从而能够实现通过修改形参的值而达到修改对应实参值的目的
  • 通过设置多个引用参数,可以从函数中带回多个结果值

注意:引用作为函数形参,其引用的目标变量默认为调用该函数时对应的实参变量名,所以,在定义函数时,对于引用类型参数不必提供引用的初值

void swap(int &a, int &b)
{
	int temp;
	temp = a;
	a = b;
	b = temp;
}

int main()
{
	int a = 1, b = 2;
	cout << "Before exchange:a= " << a << ", b= " << b << endl;
	swap(a, b);
	cout << "After exchange:a= " << a << ",b= " << b << endl;
	return 0;
}

// Before exchange  a = 1, b = 2;
// After exchange a = 2, b =1;
// 发生改变

什么时候需要引用

  • 流操作符>、赋值操作符=的返回值、拷贝构造函数的参数、赋值操作符=的参数、其它情况都推荐使用引用

为形参指定默认参数值

C++语言允许在函数定义时为形参指定默认参数值。这样,在
函数调用时,如果没有提供实参,则形参自动使用其默认值
如: void f(int x=0,int y=0); //形参的默认值为0
下面的函数调用语句都是合法的:

f();	//未提供实参值,形参x,y使用默认值0
f(2,4); //形参x,y将使用实参的值2和4
f(1); 	//形参x接收1,而y使用0

可以对部分形参定义默认值。这时默认值应出现在从右到左的连续若干个形参中
当函数有多个形参,如果其中一个定义有默认值,后面的(右侧)形参也必须定义默认值

例如

void f(int i,int j=2,int k=3);	// 函数原型正确
void f(int i,int j,int k=3); 	// 函数原型正确
void f(int i=1,int j,int k=3);	//函数原型错误
void f(int i=1,int j,int k);	//函数原型错误			

注意:指定参数的默认值可以在函数定义中进行,也可以在函数原型中进行。通常写在函数名在程序中第一次出现的位置

数组名传递

数组名作为函数参数

  • 数组元素作实参,对应的形参为变量,一次传递一个元素,采用值传递
  • 数组名作实参,对应的形参为一个数组,一次传递整个数组
  • 数组作参数,其参数传递可理解为形参数组与实参数组共、用同一数组空间(即共用实参数组空间)。因此,在函数中,使用形参数组就是在使用实参数组,改变形参数组元素的值就是在改变实参数组元素的值,这一点与引用传递非常相似
一维数组的传递

一维数组作形参的声明格式:
<类型> <数组名>[]

  • 其中,[]中可以省略数组的长度值。(可认为形参数组与实
    参数组长度相同)
  • 对应的实参应为同类型的一维数组名。(仅用数组名)

注意
为了使函数知道需要处理的数组元素的个数,通常给函数
再传递一个表示元素个数的整型数

例如:
一维数组名作为函数的参数。编写函数,计算一个整型数组中从第m个元素(m从0开始)开始的n个元素之和。

  • 函数设计:
    • 函数原型:int fun(int b[],int m,int n);
  • 功能:计算数组b中从第m个元素开始的n个元素之和。
  • 主函数设计:
    • 定义并初始化一个整型数组a。
    • 测试1:fun(a,0,10);//求从第0个元素开始的10个元素之和
    • 测试2:fun(a,3,5); //求从第3个元素开始的5个元素之和
// 函数代码
int fun(int b[], int m, int n)
{
	int i, s=0;
	for(i=m; i<m+n; i++)
	{
		s += b[i];
	}
	return s;
}

// 主函数
int main()
{
	int x, a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
	x = fun(a, 0, 10);
	cout << x << endl;  // 45
	x = fun(a, 3, 5);
	cout << x << endl; // 3+4+5+6+7=25
	return 0;
}

例如:
编写一个函数sort, 对n个元素的一维整型数组b进行从小到大排序。

函数定义如下:
void sort(int b[],int n) ;//b为一维数组,n为元素的个数
{
//选用一种排序方法对n个元素的b数组排
//对b数组排序,实际就是对实参数组排序
// 选择排序
int i=0, j=0, k;
for(i=0; i<n-1; i++)
{
	k = i;
	for(j=i+1; j<n; j++)
	{
		if(b[j] < b[i])
		{
			k = j;
		}
		if (k != i)
		{
			int tmp;
			tmp = b[i];
			b[i] = b[k];
			b[k] = temp;
		}
	}
}
}

// 主函数中的函数调用语句:
sort(a,10);
//调用sort函数,对10个元素的整型数组a进行排序
//函数调用后,并输出排序结果,即输出a数组中各个元素值
二维数组的传递

二维数组作形参的声明格式:
<类型> <数组名>[][<列数>]

  • 其中:<列数>为常数,不能省略,行数可缺省
  • 调用时的实参应为同类型的二维数组名

注意:
用作实参的二维数组,其列数必须与形参中的<列数>相同

例如:
二维数组名作参数,编写一个函数,将N阶方阵转置(N<10)

  • 函数设计:
    void transmat(int a[][10],int n); //对a数组中前n行n列矩阵元素转置
  • 主函数设计:
    • 定义一个10行10列的大数组x,元素类型为整型;键盘输入一个整数n(n<10);键盘输入一个nXn的方阵数据并存放到x数组的前n行n列元素中。
    • 函数调用语句为:transmat(x,n);
    • 按n行n列输出转置矩阵
// fun 
void transmat(int a[][10], int n)
{
	int t;
	for(int i=0; i<n-1; i++)
	{
		for(int j=i; j<n; j++)
		{
			t = a[i][j];
			a[i][j] = a[j][i];
			a[j][i] = t;
		}
	}
}


// main fun
int main()
{
	int x[10][10];
	cout << "intput n(n<10):";
	cin >> n;
	cout << "输入" << n << "行"<<n<<"列元素:"<<endl;
	for(int i=0; i<n; i++)
	{
		for(int j=0; j<n; j++)
		{
			cin >> x[i][j];
		}
	}
	transmat(x, n);
	cout<<"转置矩阵结果如下:"<<endl;
	for(int i=0;i<n;i++) 
	{
		for(int j=0;j<n;j++)
			cout<<x[i][j]<<" ";
		cout<<endl;
	}
	return 0;
}

结构体的传递

  • 实参为结构体类型变量
  • 形参为同类型的结构变量
  • 传递方式为值传递
    • 在函数调用时,系统首先为形参变量(即结构变量)分配存储空间,接着将 实参变量(结构变量)各成员值传递给形参变量的各个成员。对形参成员的修改不会影响实参成员值的变化。

例如:
编写函数,输出结构体变量的成员

struct student
{ int stno;
char name[20];
int age;
};

void print(student s)
{
	cout<<s.stno<<endl;
	cout<<s.name<<endl;
	cout<<s.age<<endl;
}

int mian()
{
	students stu = {1000, "zhangsan", 14};
	print(stu);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

uncle_ll

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

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

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

打赏作者

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

抵扣说明:

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

余额充值