- 注册时间
- 2011-1-27
- 最后登录
- 2021-8-19
- 在线时间
- 229 小时
终身VIP会员
花钱是让你服务的,不是叫你大哥 ...
- 魔鬼币
- 10632
|
楼主 |
发表于 2011-4-21 13:32:29
|
显示全部楼层
习题7.1
形参是一个函数的操作数;实参是调用函数的时候给函数传递的参数;
习题7.2
下列哪些函数是错误的? 为什么? 请给出修改意见:
(a). 函数体中定义的返回值 与 函数声明中的返回值 类型不匹配;(前者是字符串型, 后者是整形)。
(b). f2函数 没有声明返回值类型;
(c). calc函数没有在函数定义中给出 返回值;
(d). 语法错误, 没有在函数体上加上括号;
习题7.3
编写一个带有两个int型形参的函数,产生第一个参数的第二个参数次幂的值。编写程序传递两个int数值调用该函数, 请检验其结果。
(这个代码不好写,因为如果参数也可能是负数,我们这里先假设次幂数 以及 底数都为正数)。
int pow(int x,int y);
int main()
{
int i=10,j=5;
cout<<pow(i,j);
return 0;
}
int pow(int x,int y)
{
int result=1;
while(y!=0)
{
result*=x;
--y;}
return result;
}
习题7.4
编写一个函数, 返回其形参的绝对值;
double pow(int x);
int main()
{
double i;
cin>>i;
cout<<pow(i)<<endl;
return 0;
}
double pow(int x)
{
if(x>=0)
return x;
else return -x;
}
习题7.5
int func(int i,int *p);
int main()
{
int j=4,js=3;
int *q=&js;
cout<<func(j,q);
return 0;
}
int func(int i,int *p)
{
if(i>*p)
return i;
else if(i<*p)
return *p;
//else cout<<"两个数一样大!";
}
注:int型数据 无法和 *int型数据做比较,这题目出的让人产生歧义;
习题7.6
编写函数交换两个int型指针所指向的值,调用并检验该函数,输出交换后的值:
void func(int *p1,int *p2);
int main()
{
int i=3,j=4;
int *pp1=&i,*pp2=&j;
cout<<"*pp1:"<<*pp1<<endl;
cout<<"*pp2:"<<*pp2<<endl;
func(pp1,pp2);
cout<<"*pp1:"<<*pp1<<endl;
cout<<"*pp2:"<<*pp2<<endl;
return 0;
}
void func(int *p1,int *p2)
{
int temp=0;
temp=*p1;
*p1=*p2;
*p2=temp;
}
习题7.7
Void f(T) 传递在函数中的是一个实参的局部副本;
Void f(T&) 传递到函数中的是一个实参的别名;
习题7.8
举一个例子说明什么时候应该将形参定义为引用类型。再举一个例子说明什么时候不应该将形参定义为引用。
当希望改变主调函数中的实参的值的时候,被调函数应使用引用类型;
void func(int &val);
int main()
{
int x=1;
cout<<"在func函数未调用之前,x:"<<x<<endl;
func(x);
cout<<"在func函数被调用之后,x:"<<x<<endl;
return 0;
}
void func(int &val)
{
++val;
}
// 调用func函数实现 实参+1 的功能。
习题7.9
将(7.2.2节定义的)find_val 函数的形参表中 occurs的声明修改为非引用参数类型, 并重新执行这个程序,该程序的行为发生了什么改变 ?
略!
习题7.10
略! 可用,但是不会修改~
习题7.11
主要是不希望实参被复制;在向函数传递大型对象时,需要使用引用形参,这是引用形参使用的另一种情况。虽然复制实参对于内置数据类型的对象或者规模较小的类类型对象来说没有什么问题,但是对于大部分的类类型或者大型数组,他的效率通常太低了;
如果在需要const引用时,将形参定义为普通引用,会导致程序运行效率的降低,因为会多次调用复制构造函数 以及 相关的析构函数,一定程度上降低了程序的运行速度;
习题7.12
什么时候应使用指针形参?什么时候应使用引用形参? 解释两者的优点和缺点;
答: 当函数希望操作的是数组的指针时候,应使用指针形参;但是指针形参由于编译器会忽略其指向的数组的长度,所以可能会在函数中造成数组的越界访问,程序的执行可能产生错误的输出,也可能崩溃,这取决于越界访问的内存中恰好存储的数值是什么。
如果形参是数组的引用,编译器不会将数组实参转化为指针,而是传递数组本身的引用本身,也就是说,当你希望直接在函数中操纵数组元素的时候,应该使用引用本身。在这种情况下,数组大小成为形参和实参类型的一部分,编译器会检查数组实参的大小与形参的大小是否匹配。
7.13 编写程序计算数组元素之和。要求编写函数三次,每次以不同的方法处理数组边界。
方法一:
int printValues(int ia[]) //直接将形参设为数组的指针;
{
int sum=0;
for(size_t i=0;i!=10;++i)
sum+=ia[i];
return sum;
}
int main()
{
int j[10]={0,1,2,3,4,5,6,7,8,9};
cout<<printValues(j);
return 0;
}
自己规划实参指针指向的数组的大小 以及 函数体中数组的大小;
方法二:
int printValues(int (&ia)[10]) //指向数组的引用;
{
int sum=0;
for(size_t i=0;i!=10;++i)
sum+=ia[i];
return sum;
}
int main()
{
int j[10]={0,1,2,3,4,5,6,7,8};
cout<<printValues(j);
return 0;
}
方法三:
int printValues(const int *beg, const int *end) //传递指向数组的第一个以及最后一个元素的位置的指针。
{
int sum=0;
while(beg !=end){
sum+=*beg++;}
return sum;
}
int main()
{
int j[10]={0,1,2,3,4,5,6,7,8,9};
cout<<printValues(j,j+10);
return 0;
}
方法四:
int printValues(const int ia[], size_t sz) //第一个形参是一个指向数组的指针,第二个参数指定数组的大小。
{
int sum=0;
for(size_t i=0;i!=10;++i)
{
sum+=ia[i];}
return sum;
}
int main()
{
int j[10]={0,1,2,3,4,5,6,7,8,9};
cout<<printValues(j,sizeof(j)/sizeof(*j));
return 0;
}
7.14
编写程序求 vector<double>对象中所有元素之和。
暂略。
7.15
编写一个主函数main,使用两个值作为实参,并输出他们的和。
略。
7.16
编写程序使之可以接受本节介绍的命令行选项,并输出传递给main的实参的值。
略。
7.17
什么时候返回引用是正确的?而什么时候返回const引用是正确的?
答:当需要返回对象本身的时候,可以返回引用,这时候,调用函数和返回结果时,都没有复制这些对象的数据; 千万不要返回局部对象的引用,因为当函数执行完毕的时候,将释放分配给局部对象的存储空间。此时局部对象的引用就会指向不确定的内存。同时,不能返回指向局部对象的指针,因为一旦函数结束,局部对象被释放,返回的指针就变成了指向不再存在的对象的悬垂指针。
当不希望引用返回值被修改,函数返回值应该声明为const; |
|