题目(一):编写一个函数,把一个整数数组中的前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等编著