C++中函数参数传递的三种方式:值传递、地址传递、引用传递及const在函数形参中的应用

1 值传递

        调用子函数时把主函数中实参的传递给子函数的形参,在子函数中完成对应的操作。此时,子函数中的所有操作都是对形参来进行的,因此主函数中的实参不受子函数的影响。

且子函数的形参存放在栈区,函数调用完成后由编译器自动释放!

以交换两个数为例:

(1) 子函数

// 值传递
void swapab_value_transmit(int a, int b)
{
	int temp = a;
	a = b;
	b = temp;
}

(2)主函数

void main()
{
	int a = 10;
	int b = 20;

	// 值传递( 不改变实参的值 )
	swapab_value_transmit(a, b);
	cout << "值传递:" << "a=" << a << "	b=" << b << endl;
}

效果:

显然,由于是值传递,子函数并没有完成主函数中参数值的交换!

2 地址传递

         调用子函数时把主函数中实参的地址传递给子函数的形参(此时子函数的形参用指针来接收实参的地址)。因此,此时子函数是直接对实参的地址所指向的内存空间进行操作的,故可以改变的实参的值!

        即使子函数调用结束后形参被释放,但由于形参指针指向主函数实参的地址,故在对形参进行操作时也同时对实参进行了相同的操作。

以交换两个数为例:

(1) 子函数

// 地址传递
void swapab_addr_transmit(int *a, int *b)
{
	int temp = *a;
	*a = *b;
	*b = temp;
}

 (2) 主函数

void main()
{
	int a = 10;
	int b = 20;

	// 地址传递( 直接对地址进行操作,可改变实参的值 )
	swapab_addr_transmit(&a, &b);
	cout << "地址传递:" << "a=" << a << "	b=" << b << endl;
}

效果:

 显然,由于是地址传递,子函数完成了主函数中实参值的交换!

3 引用传递

  • 引用的作用: 给变量取别名
  • 引用的语法:数据类型 &别名 = 原名 (数据类型要与原变量一致
  • 引用的注意事项:必须初始化、初始化后不可更改(不能再做其他变量的别名)
  • 引用作为函数参数优势可以达到与地址传递相同的效果且简化代码和语法

        当引用作为函数参数时, 调用子函数时把主函数中实参名称(原名)所指向的内存取一个别名(子函数的形参),即别名和原名都指向同一段内存空间。因此,在子函数中对形参操作是直接对实参的内存进行操作,从达到了在子函数中操作实参的效果!且该写法简化代码书写!

以交换两个数为例:

(1) 子函数

// 引用传递
// 引用给变量起别名,通过原名和别名都可访问变量的地址
void swapab_cite_transmit(int& a, int& b)
{
	int temp = a;
	a = b;
	b = temp;
}

(2) 主函数

void main()
{
	int a = 10;
	int b = 20;

	// 效果与地址传递相同(直接对实参的地址进行操作),可改变实参的值
	swapab_cite_transmit(a, b);
	cout << "引用传递:" << "a=" << a << "	b=" << b << endl;
}

效果:

 显然,由于是引用传递,子函数完成了主函数中实参值的交换!

4 const在函数形参中的应用

        const 关键字可以定义常量,const修饰的常量在程序中不能被修改,用const定义常量的基本语法为:

const type variable = value;

        在函数形参列表中使用const的主要作用为:const 修饰的变量可以把对应的变量改为只读状态,避免对原数据进行误操作

4.1 值传递形参的应用

作用:防止对传入变量的误操作!

(1) 子函数

void test(const int a)
{
	// a = a + 1;     //会报错,const修饰的变量不能被修改
	cout << "a=" << a << endl;
}

(2)主函数

void main()
{
    int a = 10; 
    test(a);
}

4.2 地址传递形参中的应用

const修饰指针变量的方式主要有:

  • 常量指针: const type * p   (指针p的指向可以修改,指针p的指向的值不能修改)
  • 指针常量: type * const  p  (指针p的指向不可修改,指针p的指向的值可以修改)
  • 即修饰指针又修饰常量:const type * const p  (指针p的指向和指向的值都不可修改)

函数示例:

void test1(const int * a)    // 常量指针,指向的值不能修改
{
	// *a = 2;     //会报错,指向的值不能修改
    int b = 20;    
    a = &b;       //正确,指针的指向可以修改
	cout << "a=" << *a << endl;
}
void test2( int* const a)	// 指针常量,指针指向不能修改
{
	int b = 20;
	//a = &b;		// 错误,指针指向不能修改
	*a = 20;        // 正确,指针的指向的值可以修改
	cout << "子函数 a= " << *a << endl;
}
void test2( const  int* const a)	// 指针常量,指针指向不能修改
{
	int b = 20;
	// a = &b;		// 错误,指针指向不能修改
	//*a = 20;      // 错误,指针的指向的值不能修改
	cout << "子函数 a= " << *a << endl;
}

4.3 引用传递形参中的应用

常量引用语法(允许直接赋予数值):

// 1.可直接赋予数值
const int & name = 10;
// 编译器自动优化为: int temp= 10;  const  const int & name = temp;


// 2.也可赋予变量名
int a = 20;
const int & name = a;

作用主要用于修饰形参防止误操作

void test(const int & a)
{
	//a = 20;            // 错误, const修饰的引用不可修改
	cout << "子函数 a= " << a << endl;
}

因此,常量引用作为函数参数时有两种调用方式:

void main()
{
    int a = 10; 
    test(a);         // 给变量名
	test(20);        // 直接给数值
}

 效果:

猜你喜欢

转载自blog.csdn.net/jac_chao/article/details/124232275