以指针作为引用参数(二)

题目(一):编写一个函数,把一个整数数组中的前n个元素复制到另一个数组的前端。其中一个数组应该为常量参数,另一个数组应为为普通的数组参数。

#include<iostream>
using namespace std;

//传入其中一个数组为常量参数,另一个数组为普通数组
//因为需要改变数组A的内容,所以参数为普通数组,不需要改变数组B的的内容,所以为常量参数(const)
void copy_to_front(int target[], const int source[],size_t m);
int main()
{
	int A[3] = {0};
	int B[3] = { 444,555,666 };
	copy_to_front(A,B, sizeof(B) / sizeof(B[0]));
	for (int i = 0; i < sizeof(A)/sizeof(A[0]); i++)
	{
		cout << A[i] << " ";
	}
	cout << endl;
	system("pause");

	return 0;
}
void copy_to_front(int target[],const int source[],size_t n)
{
	for (int i = 0; i < n; i++)
	{
			target[i] = source[i];
	}
}

分析:可以看到,因为target[]在函数中元素的内容会被修改,所以不能传递常量参数。对于数组source[]数组,只希望读取其元素内容,并不希望它改变,所以最好传递常量参数。

题目(二):在函数中创建动态数组,将数组A和数组B首位相接组成一个新数组

#include<iostream>
using namespace std;

int*& copy_to_front(const int A[],int n,const int B[],int m);
int main()
{
	int A[] = { 1,2,3};
	int B[] = { 444,555,666 };
	int *numbers = copy_to_front(A,sizeof(A)/sizeof(A[0]),B,sizeof(B)/sizeof(B[0]));
	for (size_t i = 0; i < _msize(numbers)/sizeof(numbers[0]);i++)
	{
		cout << numbers[i] << " ";
	}
	cout << endl;
	system("pause");

	return 0;
}
int*& copy_to_front(const int A[],int n,const int B[],int m)
{
	int final = m + n;
	//在这里定义一个指针变量p指向动态数组,可以发现数组中元素个数(final)是由程序调用copy_to_front才确定下来,这也是动态数组牛逼的地方,数组大小在程序运行时确定!
	//我们应该清楚滴知道,返回值最后应该是这个指针p的引用,所以使用int*&表示返回指针的引用!
	//为了简洁,我们当然可以使用typedef int* p_ptr;
	int *p = new int[final];
	for (size_t i = 0; i < final; i++)
	{
		if (i<n)
			p[i] = A[i];
		else
			p[i] = B[i - n];
	}
	//注意最后返回的是指针的引用哦哦哦,所以使用的就是int*& 返回值啦
	return p;
}

分析:可以发现,数组作为函数参数传递的都是常量参数,在函数中动态创建数组,最后返回指向这个动态数组的指针,所以返回的是指针引用!

2018.11.04补充:在这里我们可以看到返回函数中的一个指针变量p,需要注意需要注意的是p的指向是动态数组,动态内存是从堆里分配出来的,所以可以返回其引用。但是需要注意的是不能返回函数中栈的临时变量的引用!

输出: 

分析:显然,可以发现上面这个解法中,我们在main函数中修改numbers指针的指向是通过赋值的方法,并没有将numbers这个指针变量作为参数传递到函数中,而是在调用的函数中新建了一个指针变量p,最后将指针变量p的引用返回给主函数的numbers指针变量。所以,在函数中,能不能返回指针变量取决于这个指针的指向!如果指针指向局部临时变量的时候就不能返回该指针,因为局部变量在函数完成后要销毁局部变量,释放内存。下面看一下直接将numbers指针变量的引用作为函数参数传递,实现在函数内修改指针指向并返回的操作 。这样就和前一篇的开篇提到的:在程序中使指针指向一个新的位置,这是指针作为函数参数传递的唯一情况!(type_name*&)对应起来了。

#include<iostream>
using namespace std;

void copy_to_front(int*& p,const int A[],int n,const int B[],int m);
int main()
{
	int A[] = { 1,2,3};
	int B[] = { 444,555,666 };
	int *numbers;//定义一个指针变量numbers,并将指针的引用传入函数,在函数中改变指针numbers的指向
	copy_to_front(numbers,A,sizeof(A)/sizeof(A[0]),B,sizeof(B)/sizeof(B[0]));
	for (size_t i = 0; i < _msize(numbers)/sizeof(numbrs[0]);i++)
	{
		cout << numbers[i] << " ";
	}
	cout << endl;
	system("pause");

	return 0;
}
void copy_to_front(int*& p,const int A[],int n,const int B[],int m)
{
	int final = m + n;
	//在这里改变传递进来的指针变量的指向!而不是像前面一样新建一个指针变量来指向动态数组
	p = new int[final];
	for (size_t i = 0; i < final; i++)
	{
		if (i<n)
			p[i] = A[i];
		else
			p[i] = B[i - n];
	}
	//注意最后返回的是指针的引用哦哦哦,所以使用的就是int*& 返回值啦
}

提醒:_msize()可以计算动态数组的字节大小.

 输出:

题目(三) :阅读并理解下面的代码

#include<iostream>
#include<cstdlib>
#include<cassert>
using namespace std;

void allocate_doubles(double*& p, size_t& n);
void fill_array(double data[], size_t n);
double average(const double data[], size_t n);
void compare(const double data[], size_t n, double value);

int main()
{
	//这里新建一个double类型的指针,在函数中作为引用参数,在函数内部改变指针的指向!
	double *numbers;
	//这里新建一个size_t类型的变量,在函数中作为引用参数,在函数内部修改变量的值!
	size_t array_size;
	double mean_value;
	cout << "This progarm will compute the average of some numbers.The\n";
	cout << "numbers will be stored in an array of doubles that I allocate.\n";
	allocate_doubles(numbers, array_size);
	//Read the user's input and compute the average

	//需要注意调用上面那个allocate_doubles函数使用的是引用传递,此时numbers指向已经发生改变并且array_size的大小也发生了变化!
	fill_array(numbers, array_size);
	mean_value = average(numbers, array_size);
	//print the output
	cout << "The average is: " << mean_value << endl;
	compare(numbers, array_size, mean_value);
	cout << "This was a mean program.";
	system("pause");
	return EXIT_SUCCESS;
}
void allocate_doubles(double*& p,size_t& n)
{
	cout << "How many doubles should I allocate?" << endl;
	cout << "Please type a positive integer answer: ";
	//函数传递进来的是一个引用,其值在这里得到改变
	cin >> n;
	//函数传递进来的是一个指针引用,其指向在这里发生改变
	p = new double[n];
}
//从键盘中输入得到一个数组
void fill_array(double data[], size_t n)
{
	size_t i;
	cout << "Please type " << n << " double numbers: " << endl;
	for (i = 0; i < n; i++)
		cin >> data[i];
}
//输入一个数组和一个元素,将数组中的每一个和value值比较一遍
void compare(const double data[], size_t n, double value)
{
	size_t i;
	for (i = 0; i < n; ++i)
	{
		cout << data[i];
		if (data[i] < value)
			cout << " is less than ";
		else if (data[i] > value)
			cout << " is more than ";
		else
			cout << " is equal to ";
		cout << value << endl;
	}
}
double average(const double data[], size_t n)
{
	double sum = 0;
	assert(n > 0);
	for (size_t i = 0; i < n; ++i)
	{
		sum += data[i];
	}
	return (sum / n);
}

输出:


参考:《数据结构与面向对象程序设计》(C++版)Michael Main等编著


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值