数组作为函数参数并传递数组元素个数的几种有效方法
//由于数组的元素个数默认情况下是不作为实参内容传入调用函数的,本程序用来讨论有此带来的
//相关问题,以及解决问题方法,即给调用函数传递数组的元素个数的几种有效方法并实现它
#include<iostream>
#include<vector>
using namespace std;
void PutArray1(int *p,int length)
{
for(int ix=0;ix<length-1;ix++)
cout<<p[ix]<<"\t";
cout<<p[ix]<<endl;
}
void PutArray2(int p[],int length)
{
for(int ix=0;ix<length-1;ix++)
cout<<p[ix]<<"\t";
cout<<p[ix]<<endl;
}
void PutArray3(int p[10])
{
for(int ix=0;ix<9;ix++)
cout<<p[ix]<<"\t";
cout<<p[ix]<<endl;
}
void PutArray4(int (&p)[10])//注意对int数组的引用是int (&a)[10],而不是int & a[10],否则有编译错误
{
for(int ix=0;ix<9;ix++)
cout<<p[ix]<<"\t";
cout<<p[ix]<<endl;
}
void PutArray5(vector<int>verc)
{
vector<int>::iterator begin_iter=verc.begin();
vector<int>::iterator end_iter=verc.end();
int size=verc.size ();
cout<<"使用两个迭代器来输出int向量"<<"\n"<<endl;
for( vector<int>::iterator iter=begin_iter ;iter!=end_iter;iter++)
cout<<*iter<<"\t";
cout<<endl;
cout<<"使用向量参数传进来的元素规模输出int向量\n"<<endl;
for(int ix=0;ix<size-1;ix++)
cout<<verc[ix]<<"\t";
cout<<verc[ix]<<endl;
}
void main()
{
int a[10]={0,1} ,b[8]={0,1};
vector<int> verc1(a,a+10);
vector<int> verc2(b,b+8);
cout<<"数组a[10]调用函数PutArray1的结果为:\n"<<endl;//由此PutArray1和PutArray2和PutArray3的第一次输出的输出结果可以
PutArray1(a,10);
cout<<"数组a[10]调用函数PutArray2的结果为:\n"<<endl;//说明PutArray1(int * p)和PutArray2(int p[])以及PutArray3(int p[10]这
PutArray2(a,10);
cout<<"数组a[10]调用函数PutArray3的结果为:\n"<<endl;//三个函数是等价的;实参传递的都是int *p;他们的元素个数都不作为实参内容传进
PutArray3(a);
cout<<"数组b[8]调用函数PutArray3的结果为:\n"<<endl; //函数。
PutArray3(b);
cout<<"向量verc1调用函数PutArray5的结果为:\n"<<endl;
PutArray5(verc1);
cout<<"向量verc2调用函数PutArray5的结果为:\n"<<endl;
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向量来代替数组
//由于数组的元素个数默认情况下是不作为实参内容传入调用函数的,本程序用来讨论有此带来的
//相关问题,以及解决问题方法,即给调用函数传递数组的元素个数的几种有效方法并实现它
#include<iostream>
#include<vector>
using namespace std;
void PutArray1(int *p,int length)
{
for(int ix=0;ix<length-1;ix++)
cout<<p[ix]<<"\t";
cout<<p[ix]<<endl;
}
void PutArray2(int p[],int length)
{
for(int ix=0;ix<length-1;ix++)
cout<<p[ix]<<"\t";
cout<<p[ix]<<endl;
}
void PutArray3(int p[10])
{
for(int ix=0;ix<9;ix++)
cout<<p[ix]<<"\t";
cout<<p[ix]<<endl;
}
void PutArray4(int (&p)[10])//注意对int数组的引用是int (&a)[10],而不是int & a[10],否则有编译错误
{
for(int ix=0;ix<9;ix++)
cout<<p[ix]<<"\t";
cout<<p[ix]<<endl;
}
void PutArray5(vector<int>verc)
{
vector<int>::iterator begin_iter=verc.begin();
vector<int>::iterator end_iter=verc.end();
int size=verc.size ();
cout<<"使用两个迭代器来输出int向量"<<"\n"<<endl;
for( vector<int>::iterator iter=begin_iter ;iter!=end_iter;iter++)
cout<<*iter<<"\t";
cout<<endl;
cout<<"使用向量参数传进来的元素规模输出int向量\n"<<endl;
for(int ix=0;ix<size-1;ix++)
cout<<verc[ix]<<"\t";
cout<<verc[ix]<<endl;
}
void main()
{
int a[10]={0,1} ,b[8]={0,1};
vector<int> verc1(a,a+10);
vector<int> verc2(b,b+8);
cout<<"数组a[10]调用函数PutArray1的结果为:\n"<<endl;//由此PutArray1和PutArray2和PutArray3的第一次输出的输出结果可以
PutArray1(a,10);
cout<<"数组a[10]调用函数PutArray2的结果为:\n"<<endl;//说明PutArray1(int * p)和PutArray2(int p[])以及PutArray3(int p[10]这
PutArray2(a,10);
cout<<"数组a[10]调用函数PutArray3的结果为:\n"<<endl;//三个函数是等价的;实参传递的都是int *p;他们的元素个数都不作为实参内容传进
PutArray3(a);
cout<<"数组b[8]调用函数PutArray3的结果为:\n"<<endl; //函数。
PutArray3(b);
cout<<"向量verc1调用函数PutArray5的结果为:\n"<<endl;
PutArray5(verc1);
cout<<"向量verc2调用函数PutArray5的结果为:\n"<<endl;
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向量来代替数组
函数参数为数组名时如何传参?
void UpperCase( char str1[] ) // 将 str 中的小写字母转换成大写字母
{
for(int i=0; i<sizeof(str1)/sizeof(str1[0]); ++i )
if( 'a'<=str1[i] && str1[i]<='z' )
str1[i] -= ('a'-'A' );
}
int main()
{
char str[] = "aBcDe";
cout << "str字符长度为: " << sizeof(str)/sizeof(str[0]) << endl;
UpperCase( str );
cout << str << endl;
return 0;
}
答案:str字符长度为: 6
ABCDe
解释:
(1)在main函数中对字符数组名str使用sizeof时,sizeof给出的是整个数组所占的内存大小,即sizeof(str)/sizeof(str[0])=6/1=6。
对于非字符数组原理一样,如:
int str_int[] = {1,2,3};
cout << "str_int字符长度为: " << sizeof(str_int)/sizeof(str_int[0]) << endl;
会输出:
str_int字符长度为:3
即,sizeof(str_int)/sizeof(str_int[0]) =12/4=3。
注意:字符数组和非字符数组在使用sizeof时的主要区别是:sizeof(字符数组名),计算了\0的数目,如例子中有5个字符,但是最终得出的字符长度为6。而sizeof(非字符数组名),仅计算数组中实有元素的数量,在例子中为3。
(2)当函数参数为数组名时,如例子中的函数:void UpperCase( char str1[] ),这时虽然函数的形参在形式上看起来是数组的形式,但是实际上是一个指向数组首地址的指针,所以在函数内部使用sizeof(str1)得到的只是指针的大小,每个指针所占内存均为4个字节,故sizeof(str1)/sizeof(str1[0])=4/1=4。
这时若函数参数换成整型的,void UpperCase( int str_int1[] ) :(函数内容有变,但是这里不考虑,只观察sizeof的变化。)
在main函数中换成整型数组:
int str_int[] = {1,2,3};
cout << "str_int字符长度为: " << sizeof(str_int)/sizeof(str_int[0]) << endl;
UpperCase( str_int );
则函数中的sizeof(str_int1)/sizeof(str_int1[0]) =4/4=1。
(3)由此可见,不管函数参数是数组形式还是指针形式,系统都将其当作指针形式进行处理。故一般在传递函数参数时,不光要传递数组首地址,还需另设一变量,将数组的长度传递进来,如void UpperCase( char str1[],int len )。
(4)正如高质量编程中的一道题:
char str[] =“Hello”;
char *p = str;
int n=10;
请计算
sizeof (str) = 6
sizeof (p) = 4
sizeof (n) = 4
void Func (char str[100])
{
请计算
sizeof(str) = 4
}
void *p = malloc(100);
请计算
sizeof(p) = 4
解释:sizeof如用于数组,只能测出静态数组的大小,无法检测动态分配的或外部数组大小。