简介
============================================================================================================
一、传递给函数的数组的处理
1、处理数组的程序要确保程序停留在数组的边界内
非引用数组形参的类型检查只是确保实参是和数组元素具有相同类型的指针,而不会检查实参实际上是否指向指定大小的数组。(看7.2.4 数组的引用做形参则是要求大小也要一致的)
引用类型就会检查实参数组的大小是否和形参数组大小一致。(7.2.4节)
任何处理数组的程序都要确保程序停留在数组的边界内
有三种常见的编程技巧确保函数的操作不超出数组实参的边界。
在数组本身放置一个标记来检测数组的结束, C风格字符串就是采用空字符null作为结束的标记(含有‘\0’结束的字符数组);
传递指向数组第一个和最后一个元素的下一个位置的指针。
将第二个形参定义为表示数组的大小。
2、使用标准库规范
被调用的函数形参里边一个形参是传递指向数组第一个,另一个形参是最后一个元素的下一个位置的指针。
调用这个函数需要传递两个指针:一个指向要输出的第一个元素,另一个则指向最后一个元素的下一个位置,只要正确计算指针,使他们标记一段有效的元素范围,程序就会安全。
void printValues(const int *beg,const int *end)
{
while(beg!=end){
cout<<*beg++<<endl;
}//函数的循环很像用vector迭代器编写的程序。每次循环都使beg指针指向下一个元素,从而实现数组的遍历。当beg指针等于结束标记时,循环结束,结束标记就是传递给函数的第二个形参。
}
int main(){
int j[2]={0,1};
printValues(j,j+2);//j指向数组的第一个元素,j+2指向数组最后一个元素的下一个位置
return 0;
}
3、显示传递表示数组大小的形参
将被调用函数的第二个形参定义为表示数组的大小。
void printValues(const int ia[],size_t size)
{
for (size_t i=0;i!=size;i++){
cout<<ia[i]<<endl;
//用size来确定要输出的元素的个数,只要传递给函数的size值不超过数组的实际大小,程序就能安全运行。
}
}
int main()
{ int j[]={0,1};
printValues(j,sizeof(j)/sizeof(*j));//5.8节上,sizeof(数组名)求的是整个数组的所有元素占有的内存大小。
//sizeof(*j)=sizeof(j[0])=sizeof(int类型的数)=4
return 0;
}
习题7.12 什么时候使用指针形参?什么时候使用引用形参?解释两者的优缺点。
当函数需要处理数组且函数体不依赖于数组的长度时应使用指针形参,其他情况下应该使用引用形参;
指针形参的优点是可以明确地表示函数所操纵的是指向数组元素的指针,而不是数组本身,而且可以使用任意长度的实参数组来调用函数(而引用形参是实参和形参必须对应);
指针形参的缺点是函数体不能依赖于数组的长度,否则容易造成数组内存的越界访问,从而产生错误的结果或者导致程序崩溃;
引用形参的优点是在函数体中依赖数组的长度是安全的,缺点是限制了可以传递的实参数组,只能使用长度匹配的实参数组来调用函数(就是实参)。
//习题 7.13 计算数组元素之和。要求编写函数三次,每次以不同的方法处理数组边界
int sum1(const int *begin,const int * end)
{
int sum=0;
while(begin!=end){
sum+=*begin++;
}
return sum;
}
int sum2(const int ia[],size_t size){
int sum=0;
for(size_t ix=0;ix!=size;ix++){
sum+=ia[ix];
}
return sum;
}
int sum3(int *begin,size_t size){
int sum=0;
int *p=begin;
while(p!=begin+size){
sum+=*p++;
}
return sum;
}
int main(){
int ia[]={1,2,3,4};
cout<<sum1(ia,ia+4)<<endl;
cout<<sum2(ia,4)<<endl;
cout<<sum3(ia,4)<<endl;
return 0;
}
//习题7.14
double vectorSum(vector<double>::iterator begin,vector<double>::iterator end)
{
double sum=0.0;//double类型初始化
while(begin!=end){
sum+=*begin++;
}
return sum;
}
int main(){
vector<double> dvec;
double dval;
while(cin>>dval)
dvec.push_back(dval); //初始化vector
cout<< vectorSum(dvec.begin(),dvec.end())<<endl;
return 0;
}

本文探讨了在C++中如何安全地处理传递给函数的数组,包括通过放置结束标记、传递边界指针和显示传递数组大小。强调了在函数中确保不超出数组边界的重要性,并比较了指针形参和引用形参在处理数组时的优缺点。同时,提出了计算数组元素之和的函数实现方法。
2375

被折叠的 条评论
为什么被折叠?



