C++7.2.5数组做实参---避免越界
来源:互联网 发布:p图滤镜软件 编辑:程序博客网 时间:2024/06/06 09:34
简介
============================================================================================================
一、传递给函数的数组的处理
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类型的数)=4return 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.14double 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++7.2.5数组做实参---避免越界
- C++:重载运算符避免数组越界
- C语言数组名做实参与C++容器名做实参对主程序的影响
- C(4)数组or数组元素做实参
- 【C/C++】数组越界
- 二维数组如何做实参
- C语言中的数组越界
- C语言中的数组越界
- C语言中的数组越界
- 用数组元素做函数实参
- C++不对数组越界做检查
- UITableView 避免奔溃的数组越界处理方法
- 论C语言中的数组下标越界
- C语言数组越界问题实例
- C语言中数组越界的例子
- C/C++ bug_1:字符数组越界
- C# 数组越界的一场处理
- C/C++中键盘输入数组越界问题
- java的concurrent用法详解
- Linux NFS文件系统
- 实现随时随地一键退出所有Activity
- 广播接收者BroadcastReceiver
- @PathVariable和@RequestParam的区别
- C++7.2.5数组做实参---避免越界
- Redis--java
- 【深入Java虚拟机】之四:类加载机制
- 如何使用短信猫发送中文短信
- Base.UDP
- 无符号整型赋值陷阱
- 陈怡暖:(午评)英国自摆乌龙,休市等待激变
- 有趣的Autolayout示例-Masonry实现
- 带附件的java.mail邮件发送