【高分求救】函数返回值测试

Herowuking 2008-01-03 09:55:30

#include <iostream>
#include <windows.h>
using namespace std;

int vAdd(int &a, int &b) //函数按值返回
{
int temp;
temp = a+b;
return temp;
};

int* pAdd(int &a, int &b) //函数值用指针返回
{
int temp;
temp = a+b;
return &temp; //返回局部指针为什么正常??
};

const int* cpAdd(int &a, int &b) //函数返回值用const指针返回
{
int temp;
temp = a+b;
return &temp;
};

int& rAdd(int &a, int &b) //函数返回值用引用返回
{
int temp;
temp = a+b;
return temp; //返回局部引用为什么也正常??
};

int main()
{
int A,B,Flag =0; //A、B接收输入的两个整数,Flag判断用户的选择
int Sum =0;
bool quit = false;
while (!quit) {
//用do-while循环处理用户的选择,如果没有正确的输入理论上应该一直出现选择界面
do {
cout<<"======Choose a method to add two integer number:======"<<endl;
cout<<"1.return by value;\n"
<<"2.return by pointer;\n"
<<"3.return by reference;\n"
<<"4.return by const pointer.\n";
cin>>Flag;
//如果缺少下面两句,错误输入将会导致死循环
cin.clear();
cin.ignore();
} while(!(Flag ==1 || Flag ==2|| Flag ==3|| Flag ==4)); //end do-while

cout<<"Please input two integer number which you want to add:"<<endl;
cin>>A>>B;

//Lable 1
if (Flag ==1)
Sum = vAdd(A,B);
else if (Flag ==2){
int *pSum = pAdd(A,B);
Sum = *pSum;
}
else if (Flag == 3)
Sum = rAdd(A,B);
else if (Flag ==4){
const int* csum = cpAdd(A,B);
Sum = *csum;
} //end if

cout<<"the sum of "<<A<<" and "<<B<<" is:"<<Sum<<endl;
cout<<"Press Q for quit,else other key for continue...\n";
char cquit;
cin>>cquit;
//同上。如果缺少下面两句,错误输入将会导致死循环
cin.clear();
cin.ignore();
if (cquit == 'Q' || cquit == 'q') {
quit = true;
//直接退出控制台,即便是在VC里面启动程序
HWND hWnd = ::FindWindow("ConsoleWindowClass",NULL);
SendMessage(hWnd,WM_CLOSE,0,0);
} //end if
} //end while

return 0;
}

/*
//用下面的switch语句代替Label 1处的if语句会报指针初始化错误!
switch(Flag) {
case 1:
Sum = vAdd(A,B);
break;
case 2:
int *pSum = pAdd(A,B);
Sum = *pSum;
break;
case 3:
Sum = rAdd(A,B);
break;
case 4:
const int* csum = cpAdd(A,B);
break;
default:
cout<<"Wrong choice!"<<endl;
}
*/

疑问:
1.为什么我的程序中返回局部变量的指针和引用都没有出错呢?
2.按照如下步骤测试程序会出现奇怪的错误:
a.运行程序出现选择界面,输入1选择第一种返回方式调用函数
b.任意输入两个数字如1 1
c.出现是否继续的提示时,输入不是q的任何字母让程序继续
d.此时再次出现选择界面,输入字母w(不是数字),程序仍然继续...,Why?
按照程序逻辑输入错误的选择字符应该会再次出现选择界面的呀??
3.为什么程序代码最后的注释中的switch语句组替换程序中的if语句组会出错呢?

菜鸟 Herowuking 求教
QQ:442448734
Email wuying283@qq.com

==============================
代码测试环境:
Windows XPSP2
VC 6.0(SP6)
...全文
180 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
Herowuking 2008-01-04
  • 打赏
  • 举报
回复
To healer_kx(甘草):
此贴分数有限,而回帖的人那么多,如果分都给你了别人就没有了。对于每个人有实际意义的回复我从来都不会吝啬分数的,你的回复我同样很感谢!
hastings 2008-01-03
  • 打赏
  • 举报
回复
int V()
{
int tmp(8);
return tmp;
}
int* P()
{
int tmp(8);
return &tmp;
}
int& R()
{
int tmp(8);
return tmp;
}
int main()
{
int a=V();
int* b=P();
int& c=R();
int d=R();
cout<<a<<' '<<*b<<' '<<c<<' '<<d<<'\n';
cout<<V()<<' '<<*P()<<' '<<R()<<'\n';
/////////////////////////////////////
return 0;
}

Dev-C++结果:
8 2090068098 2090068098 8
8 2090068098 2090068098
请按任意键继续. . .

VS2008结果:
8 8 8 8
8 8 8
请按任意键继续. . .
grellen 2008-01-03
  • 打赏
  • 举报
回复
up
光跃 2008-01-03
  • 打赏
  • 举报
回复
返回栈中临时对象或变量的指针是错误的操作,但是并不等于返回不到有意义的值。栈中的地址处于未初始化段,他的值是最近一次使用所存入的值。在没有新的值覆盖的情况下,该值不变,而不是通常感觉上的一些不可思议的随机数。
所以返回一个临时变量的指针,可能还能找到那个值,但是很快会被覆盖掉,极不稳定
ltc_mouse 2008-01-03
  • 打赏
  • 举报
回复
我在Dev C++中,case分支中也不能直接定义变量的。还是用语句块吧~
switch(flag)
{
case 2:
{
int *pSum = pAdd(A,B);
Sum = *pSum;
}
break;
...
}

关于返回局部指针和局部引用,你在返回后马上进行了赋值操作,这时候栈内容还没发生变化,所以还能取到正确的值。
int *pSum1 = pAdd(A,B);
int *pSum2 = pAdd(A,Sum);
再去看Sum = *pSum1 和 Sum = *pSum2,很可能就检查出问题了
sheenl 2008-01-03
  • 打赏
  • 举报
回复
d.此时再次出现选择界面,输入字母w(不是数字),程序仍然继续...,Why?
=====================================================================


cin>>Flag;
前面加一句
Flag = 5;之类的试试
jjfwenwenti 2008-01-03
  • 打赏
  • 举报
回复
up
接分


///////////.....
cin.clear();
cin.ignore();
//这个两句清空原来的缓存,防止输入了非int数出错而陷入循环.

//也可以把Flag申明为char,相应的检测写为
//....
while(!(Flag =='1' || Flag =='2'|| Flag =='3'|| Flag =='4'));
//...

我也是猜的,不知道是不是,你去试试..
hai040 2008-01-03
  • 打赏
  • 举报
回复
2是因为输入字母不会改变flag的值,可以在cin之前把flag还原成0
还有char cquit;cin>>cquit;改成cin.get()会好点
csdn5211 2008-01-03
  • 打赏
  • 举报
回复
1.肯定会错的,不过编译可以过而已,不是没错。
sheenl 2008-01-03
  • 打赏
  • 举报
回复
//用下面的switch语句代替Label 1处的if语句会报指针初始化错误!
============================================================
可能是因为vc6比较傻, 只能在程序块的开始部分定义变量, 不能在代码中间定义变量, 或者可能根本就不能在switch里面定义变量之类的, 总之原则上, 那段switch的代码没有错误

至于为什么返回局部变量的指针和引用不出错, 那就很正常了. 本来也就没有一定会出错的理由. 返回局部变量的指针或引用, 本质上只是返回了一个野指针, 这个野指针可能指着没人使用的空白地, 自由自在, 一切正常. 也可能指向其他的数据或者根本就指着不存在的地址, 那就会出错. 结果是不可预测的, 所以可能给出正确结果, 也可能给出错误结果, 也可能程序直接就抛出异常退出了.
healer_kx 2008-01-03
  • 打赏
  • 举报
回复
我个人认为楼主的学习态度挺不错的,就差一点再钻研的劲头了.其实你baidu一下就能知道很多东西,结贴吧,把分都给我...我可以给你指明了一条学习的正道啊...
ryfdizuo 2008-01-03
  • 打赏
  • 举报
回复
^_^^_^
慢慢来吧,
ltc_mouse 2008-01-03
  • 打赏
  • 举报
回复
lz不用太激动,呵呵~ 每个人回复问题的方式不同,不用太在意。甘草大虾都肯定你的学习态度了,^_^
Herowuking 2008-01-03
  • 打赏
  • 举报
回复
To wpalhm:
我正在看书的过程中有些问题想自己验证一下编的小程序,遇到了困难是自己刚学基础不扎实,但是既然CSDN给我们提供了这个交流和相互帮助的平台,我问这点问题应该没有什么问题吧。如果每个人都要自己在别人跌倒的地方再跌倒一次,那又有什么意义呢?
我知道错了,但是具体原因暂时还不太明白,所以我来CSDN请教高手,如果有人把错误原因告诉我了,我想下次不会再犯同样的错误了吧。
wpalhm 2008-01-03
  • 打赏
  • 举报
回复
推荐你看一些基础的书籍!做程序一定不能心浮气躁,要踏踏实实。你的这些问题书上都有讲的,并不是别人给你指出了错误、改正了错误,你就会学到东西的!
你只是明白了这里错了,但却明白不了错的原因。那是要靠你自己一点一点的去总结的.

64,681

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧