//由于数组的元素个数默认情况下是不作为实参内容传入调用函数的,本程序用来讨论有此带来的
//相关问题,以及解决问题方法,即给调用函数传递数组的元素个数的几种有效方法并实现它
#include
#include
using namespace std;
void PutArray1(int *p,int length)
{
for(int ix=0;ixcout<cout<
}
void PutArray2(int p[],int length)
{
for(int ix=0;ixcout<cout<
}
void PutArray3(int p[10])
{
for(int ix=0;ix<9;ix++)
cout<
cout<
}
void PutArray4(int (&p)[10])//注意对int数组的引用是int (&a)[10],而不是int & a[10],否则有编译错误
{
for(int ix=0;ix<9;ix++)
cout<
cout<
}
void PutArray5(vectorverc)
{
vector::iterator begin_iter=verc.begin();
vector::iterator end_iter=verc.end();
int size=verc.size ();
cout<<"使用两个迭代器来输出int向量"<<"\n"<for( vector::iterator iter=begin_iter ;iter!=end_iter;iter++)
cout<<*iter<<"\t";
cout<cout<<"使用向量参数传进来的元素规模输出int向量\n"<for(int ix=0;ixcout<cout<}
void main()
{
int a[10]={0,1} ,b[8]={0,1};
vector verc1(a,a+10);
vector verc2(b,b+8);
cout<<"数组a[10]调用函数PutArray1的结果为:\n"<PutArray1(a,10);
cout<<"数组a[10]调用函数PutArray2的结果为:\n"<PutArray2(a,10);
cout<<"数组a[10]调用函数PutArray3的结果为:\n"<PutArray3(a);
cout<<"数组b[8]调用函数PutArray3的结果为:\n"<PutArray3(b);
cout<<"向量verc1调用函数PutArray5的结果为:\n"<PutArray5(verc1);
cout<<"向量verc2调用函数PutArray5的结果为:\n"<PutArray5(verc2);
}
/*
(1)对于数组a[10]作为实参,对所有的以数组作为实参的函数的调用得用PutArray3(a),
而不能用PutArray3(a[10])和PutArray(a[]),否则出现编译错误,
这是由于数组的大小不作为实参的内容传递的原因
前者出现error C2664: 'PutArray3' : cannot convert parameter 1 from 'int' to 'int []'
后者出现error C2059: syntax error : ']'的提示。
(2)注意对PutArray3(b)的调用,声明里面形参为int[10],调用的时候传入的实参为int [8],
却能够编译成功,有利的证明了数组实参的元素个数确实是不作为实参的内容传入函数的
运行也没有什么错误,传人的八个元素,显示的确实十个,后面两个是随机的,实际是不属于
数组B的内容的,所以此处容易出现潜在的数组越界错误
(3)当调用PutArray4(b)的时候,由于实参是对数组的引用,它的元素个数是作为实参的一部分
传入函数的,所以当调用PutArray4(b)的时候,出现如下的编译错误:
error C2664: 'PutArray4' : cannot convert parameter 1 from 'int [8]' to 'int (&)[10]'
(4)PutArray5(verc1)和putArray(verc2)的调用是为了练习对vector和iterator的使用,同时说明了
vector容器类型作为实参的方法也可以用来传递数组的元素个数。
总结:可以用来传递数组元素个数的方法有如下3种:
(一)用两个实参,一个是数组名,一个是指出它的长度
(二)使用对数组的引用,此时它的数组元素是作为实参传入函数的
(三)使用vector向量来代替数组
*/
一般情况下,作为函数实参的数组都是将数组地址(数组名)转换成指向第一元素的指针传递给形参的。所以,如果需要同时传递数组大小,需要另外作为参数传递。这点与C函数相同。
但在C++中可以通过引用的方式同时传递数组首址及大小,示例如下:
void func(int (&arr)[10]) { cout<<arr[0]; }
|
此时调用func必须用有10个int元素的数组调用,否则会有编译错误。这就限制了该函数的使用范围。注意:上面例子中的形参是int (&arr)[10],这里的括号不能少,否则若是int &arr[10]就表示arr是一个有10个int引用类型元素的数组。
如果要使函数能在传递数组时同时传递其大小,并且可以针对不同大小的数组,可以使用函数模板来完成这项工作,例如:
template<typename T, size_t N> void func(T (&arr)[N]) { cout<<arr[0]; }
|
在这里运用了模板的非类型模板参数来传递数组大小,可以针对各种大小的数组。在编译时,编译器根据实参数组的大小来确定N值,从而可以让这个函数适用于各种大小的数组。编译后,对于不同的大小的数组会实例化相应的函数类型(实质上相当于对不同大小的数组进行函数重载,只是这枯燥的工作让编译器代做了)。
------------------------------------------------------------------------------
C++ 通过成员函数参数返回成员数组的值
通常对数组类型进行保护做法是这样的。
class A {
public :
A {}
~ A {}
enum {
MAX_VAL_COUNT = 10;
};
void getArraryValues(int (* pVal)[MAX_VAL_COUNT]) { memcpy(pVal,m_aVal,MAX_VAL_COUNT); }
或
void getArraryValues(int (& eVal)[MAX_VAL_COUNT]) { memcpy(&eVal,m_aVal,MAX_VAL_COUNT); }
或
void getArraryValues(const int* & eVal)) { eval = static_cast(m_aVal); }
private :
int m_aVal[MAX_VAL_COUNT]
}
上面的代码对类型加了强的限定,这样可以防止用户传入数组长度不够长,或防止类用户误修改私有成员内容
(当然这里类用户还是可以通过显式类型转换修改类私有成员)。
尽管如此,在C++中还是最好使用vector代替数组
#include
using namespace std;
class A {
public :
A {}
~ A {}
enum {
MAX_VAL_COUNT = 10;
};
void getArraryValues(vector& vVal) { vVal = m_vVal }
private :
vector m_vVal[MAX_VAL_COUNT]
}
-----------------------------------------------------------------------------------------------------------------------------------
/*程序作者:管宁
站点:www.cndev-lab.com
所有稿件均有版权,如要转载,请务必著名出处和作者*/
#include
main()
{
void search_score(); /* 定义自定义涵数类型为不返回型 */
void count_avg(); /* 定义自定义涵数类型为不返回型 */
static float a[3][4]={{97,45.5,66,77},{88,92.5,78.5,66},{83,74.5,92,100}}; /* 输入3个学生的各自4门课的成绩 */
search_score(a,0); /* 调换自定义涵数显示其中一个同学的各门课成绩 */
count_avg(*a,12); /* 调换自定义涵数显示3个同学各门课的平均成绩成绩 */
/* 注意上面的*a其实也就是a[0]或者是&a[0][]0将这行改写成count_avg(a[0],12);或者count_avg(&a[0][0],12)也都是对的 */
}
void search_score(p,n)
float (*p)[4]; /* 定义一个指针变量p,说明它是一个指向一个包含4个整型变量一维数组的指针 */
int n; /* 定义形式参数n为整形 */
{
int i; /* 定义用于循环的变量i */
for (i=0;i<4;i++ ) /* 这里循环4次用于打印一个同学的4门课成绩 */
{
printf("%7.2f",*(*(p+n)+i));
}
printf("\n");
}
void count_avg(p,n)
float *p;
int n;
{
float *p_end;
float sum = 0;
float avg;
p_end = p+n-1; /* 计算出最后一个数组元素的地址 */
for (;p<=p_end;p++) /* 循环到最后一个元素地址就停止 */
{
sum += *p;
}
avg = sum/n;
printf("avg=%7.2f\n",avg);
}
/*
注意此题的意思在于输入3个同4门课的成绩,计算出平均值和显示其中一个同学的4门课成绩,此例是对多维数组指针和多维数组
的指针作为涵数参数传递的总结,认真联系和体会可以很好的了解多维数组指针的概念到底是什么!
*/