如何正确实现数组的函数传参(值传递/用指针进行地址传递)(C++实现)

 

目录

数组传参的传递方式有两种:

 值传递

值传递的例外:

原因:

数组传参时发生了“降维”,实际上传入的是该数组首元素的指针

地址传递

C++中主要有两种能实现地址传递的方法:


实现一些功能时,我们经常要把数组传进函数中进行操作。

数组传参的传递方式有两种:

  1. 值传递

  2. 地址传递

 值传递

值传递的例外:

        通常,对一般变量的值传递,函数会拷贝一个与实参的值相同的临时变量来使用,因此,在函数内部改变该变量并不会真正改变原变量的实际值。

        但是,对数组来说,通过值传递的函数,也能改变原数组的实际值。

// 值传递
void test(int arr[]);

原因:

数组传参时发生了“降维”,实际上传入的是该数组首元素的指针

         ->避免拷贝完整数组带来的低效率


参数传参仍然为值传递,只不过拷贝的是数组首元素地址的临时指针


因此,对于这种 数组通过“值传递”传参的函数,函数内部对数组元素的改变是真实存在的


另外:参数中的[]内可以省略数组具体大小的原因是,实际传参为数组首元素的指针,与数组实际大小并无关,因此此处[]内写了跟没写没有区别,只要不要写<=0的数即可


而且,数组传参本来传的就是数组名,即数组首元素的地址,因此该函数形参也应为指针类型

#include
using namespace std;

void test(int arr[])
{
	arr[0] = 1;

	cout << &arr << endl;  // 值传递后拷贝的临时指针
}

int main()
{
	int arr[5] = { 0 };

	cout << &arr << endl;  // 指向原数组首元素地址的指针的地址
	cout << arr[0] << endl;

	test(arr);
	cout << arr[0] << endl;

	system("pause");
	return 0;
}

 如何正确实现数组的函数传参(值传递/用指针进行地址传递)(C++实现)_第1张图片

 输出结果证明:

原来指向数组首元素的指针,与函数调用中指向同一个数组首元素的指针 并非同一个指针,它们的地址并不一样!

通过值传递的方式把数组传进函数,在函数的内部也的确可以改变数组的元素

 

地址传递

C++中主要有两种能实现地址传递的方法:

  1. 指针 
  2. 引用

此处记录了使用 指针 来传递数组进函数的一些方法,与不使用指针的方法进行对比。(包括一维数组的两种值传递、两种地址传递,二维数组的一种值传递、一种地址传递)

尤其需要注意函数形参的语法格式

  • 指针 * 到底从属于形参的变量类型还是数组元素类型?
  • 指针 * 既可指向一个元素的地址,也可指向一个数组的地址(本质为指向该数组头元素的地址)
#include
using namespace std;


// 一维数组的传参
void test01(int arr[])  // 值传递,传入的是一个int 类型的数组
{
	cout << "test01" << endl;
	for (int i = 0; i < 10; i++)
	{
		arr[i] = i;
	}
}

void test02(int* arr[])  // 值传递,传入的是一个int* 类型的数组
{
	cout << "test02" << endl;
	for (int i = 0; i < 10; i++)
	{
		cout << arr[i] << " ";  // arr[i] 为指针类型,此时空指针均指向0,不可解引用
	}
	cout << endl << endl;
}

void test03(int *arr)  // 地址传递,传入数组时,int* 指向int类型数组的第一个元素的地址
{
	cout << "test03" << endl;
	for (int i = 0; i < 10; i++)
	{
		arr[i] = i;
	}
}

void test04(int* *arr)  // 地址传递,参数为指向指针的指针
// 可传入指针数组,此时int** 为一个指向int*类型数组头元素的指针
{
	cout << "test04" << endl;
	for (int i = 0; i < 10; i++)
	{
		cout << arr[i] << " ";  // arr[i] 为指针类型,此时空指针均指向0,不可解引用
	}
	cout << endl << endl;
}

// 二维数组的传参
void test11(int arr[][5])  // 值传递,数组第二维不能为空,必须用数字初始化! 
{
	cout << "test05" << endl;
	for (int i = 0; i < 10; i++)
	{
		for (int j = 0; j < 5; j++)
		{
			arr[i][j] = i * 5 + j;
		}
	}
}

void test12(int (*arr)[5])  // 地址传递,参数为一个指向int 类型数组的指针;
// 若传入二维数组,则指针指向第一维数组的第一个元素(第一个第二维的数组)
// 因此[]为数组第二维,必须初始化
{
	cout << "test06" << endl;
	for (int i = 0; i < 10; i++)
	{
		for (int j = 0; j < 5; j++)
		{
			arr[i][j] = (10 - i) * 5 - j - 1;
		}
	}
}

// 打印数组的函数
void print_linear_arr(int arr[])
{
	for (int i = 0; i < 10; i++)
	{
		cout << arr[i] << " ";
	}
	cout << endl << endl;
}

void print_two_dimensional_arr(int (*arr)[5])
{
	for (int i = 0; i < 10; i++)
	{
		for (int j = 0; j < 5; j++)
		{
			cout << arr[i][j] << "\t";
		}
		cout << endl;
	}
	cout << endl;
}

int main()
{
	int arr1[10] = { 0 };
	int* arr2[10] = { 0 };  // 指针数组 (数组元素初始化为空指针)
	int arr3[10][5] = { 0 };

	// 一维数组的传参
	test01(arr1);
	print_linear_arr(arr1);

	test02(arr2);  

	test03(arr1);  // 参数为值传递,传入的是一个int* 类型的数组!非地址传递
	print_linear_arr(arr1);

	test04(arr2);

	// 二维数组的传参
	test11(arr3);
	print_two_dimensional_arr(arr3);

	test12(arr3);
	print_two_dimensional_arr(arr3);

	system("pause");
	return 0;
}

程序执行结果: 

如何正确实现数组的函数传参(值传递/用指针进行地址传递)(C++实现)_第2张图片

你可能感兴趣的:(C++大神成长日记,c++)