修改临时变量的值??

jamseyang 2010-05-04 05:00:45
问题1、myfun和GetString函数中产生的临时变量有什么本质的区别,为什么一个可以修改,另一个不可以修改

#include <iostream>
#include <string>
using namespace std;

int *pNum = NULL;
void myfun(const int &rNum)
{
int *p = (int*)&rNum;
*p = 200;
pNum = (int*)&rNum;
}

char *GetString()
{
char *p = "hello ABC";
return p;
}

int main(int argc, char* argv[])
{
int num = 10;
myfun(num+2);//产生临时int类型变量
cout<<*pNum<<endl;
char *p = GetString();
cout<<p<<endl;

*pNum = 1024;// 这里可以修改.
strcpy(p,"Test"); //这里为什么不能修改呢?
return 0;
}



问题2、
关于百度百科中常引用的疑惑



http://baike.baidu.com/view/2129184.htm?fr=ala0_1_1
四、常引用
【例】:假设有如下函数声明:
  string foo( );
  void bar(string & s);
  那么下面的表达式将是非法的:
  bar(foo( ));
  bar("hello world");
  原因在于foo( )和"hello world"串都会产生一个临时对象,而在C++中,这些临时对象都是const类型的。因此上面的表达式就是试图将一个const类型的对象转换为非const类型,这是非法的。
  引用型参数应该在能被定义为const的情况下,尽量定义为const 。


我编译时bar(foo( ))这句没有问题呀!
...全文
399 48 打赏 收藏 转发到动态 举报
写回复
用AI写文章
48 条回复
切换为时间正序
请发表友善的回复…
发表回复
jamseyang 2010-05-06
  • 打赏
  • 举报
回复
谢谢大家好,结帖了!
fwyweiyi 2010-05-05
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 falcomavin 的回复:]
int num = 10;
myfun(num+2);///的确是产生了临时变量,但该变量并非const,当然可以作为实参传递给

不好意思,刚才这里说错了!这里并没有产生临时对象!而是给num加了2以后,再传给函数myfun,也就是说,实际参数依然是num,不过此时它的值不是10,而是12了。当然此num定义为非const,函数中修改它的值也就很正常了。

另外,我认为说临时对象都是c……
[/Quote]

的确是有临时变量的产生,如楼主所说,num 与 rNum 的地址是不一样的。

大家都有惯性思维了,觉得CONST 的变量是不可改变的,

但是用指针是可以改变CONST 变量的内容的 , 不信可以自己试试下面这段代码。

这也是用指针危险的地方,能绕开语法检查,编译器不会报错!

#include "stdafx.h"

int main()
{
const int num = 10;
int *p=(int *)#
*p=13;
return 0;
}
请叫我卷福 2010-05-05
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 xiuxianshen 的回复:]
建议你看看const char *和char const *的差别吧
[/Quote]
他两没区别
黑娃 2010-05-05
  • 打赏
  • 举报
回复
[Quote=引用 38 楼 jamseyang 的回复:]
谢谢你的回复,可是num并不是全局变量呀,我调试了num始终都没有改变!不知大侠是如何调试的!

引用 33 楼 falcomavin 的回复:
你有设置断点观察myfun函数执行时num的值么?何以说事实不是这样?我经调试观察,执行到myfun的时候,实参num的确从10编程了12,而且函数中将num值改为了200,更重要的是num是个全局变量,假设真的是传递了临时变量tmp给myfun函……
[/Quote]

真是对不住,一直把pnum和rnum看成一样了- -,诸多误导,请原谅。
经仔细调试后,myfun确实有临时变量产生,如LZ所理解
pengzhixi 2010-05-05
  • 打赏
  • 举报
回复
[Quote=引用 43 楼 jamseyang 的回复:]
下面的函数会有警告,我想主要是因为常量的关系吧


C/C++ code

char *GetString()
{
char szBuffer[]= "hello ABC";
return szBuffer;
}


警告 1 warning C4172: 返回局部变量或临时变量的地址
[/Quote]

这个不是因为常量的关系,这种形式的数组是可以修改的,而是因为你返回了一个局部变量的地址,因为一旦函数返回那么这个数组的内存就被销毁了。你在外面的访问的话就不合法了。
jamseyang 2010-05-05
  • 打赏
  • 举报
回复
下面的函数会有警告,我想主要是因为常量的关系吧


char *GetString()
{
char szBuffer[]= "hello ABC";
return szBuffer;
}

警告 1 warning C4172: 返回局部变量或临时变量的地址
feidaozouren 2010-05-05
  • 打赏
  • 举报
回复
在楼主的一再反问下,falcomavin 还这么固执己见,是不是该反思一下了,falcomavin 调试的是什么代码,贴出来看看,以免不必要的误解。
pengzhixi 2010-05-05
  • 打赏
  • 举报
回复
[Quote=引用 40 楼 jamseyang 的回复:]
事实是下面的函数VC2005没有任何警告产生

引用 16 楼 linsen_519 的回复:
char *GetString()
{
char *p = "hello ABC";
return p;
}
能return算你运气~好的编译器会警告的,"hello abc "返回const char*
strcpy(p,"Test") 你在企图改变一个常量指针//……
[/Quote]

你这边是返回地址,编译器根本就不知道你会在外面修改它。
jamseyang 2010-05-05
  • 打赏
  • 举报
回复
事实是下面的函数VC2005没有任何警告产生
[Quote=引用 16 楼 linsen_519 的回复:]
char *GetString()
{
char *p = "hello ABC";
return p;
}
能return算你运气~好的编译器会警告的,"hello abc "返回const char*
strcpy(p,"Test") 你在企图改变一个常量指针//……
[/Quote]
pengzhixi 2010-05-05
  • 打赏
  • 举报
回复
[Quote=引用 38 楼 jamseyang 的回复:]
谢谢你的回复,可是num并不是全局变量呀,我调试了num始终都没有改变!不知大侠是如何调试的!

引用 33 楼 falcomavin 的回复:
你有设置断点观察myfun函数执行时num的值么?何以说事实不是这样?我经调试观察,执行到myfun的时候,实参num的确从10编程了12,而且函数中将num值改为了200,更重要的是num是个全局变量,假设真的是传递了临时变量tmp给myfun函……
[/Quote]

就是生成了临时对象,你可以在那个函数里面输出p和pNum里面包含的地址不就知道了。
jamseyang 2010-05-05
  • 打赏
  • 举报
回复
谢谢你的回复,可是num并不是全局变量呀,我调试了num始终都没有改变!不知大侠是如何调试的!
[Quote=引用 33 楼 falcomavin 的回复:]
你有设置断点观察myfun函数执行时num的值么?何以说事实不是这样?我经调试观察,执行到myfun的时候,实参num的确从10编程了12,而且函数中将num值改为了200,更重要的是num是个全局变量,假设真的是传递了临时变量tmp给myfun函数,则myfun中改变成200的值应该是tmp而不是num,你看看myfun执行完了之后num已经变成200了[/Quote]
田暗星 2010-05-05
  • 打赏
  • 举报
回复
[Quote=引用 35 楼 zhao4zhong1 的回复:]
VC调试时按Alt+8,TC或BC用TD调试,打开汇编窗口看每句C对应的汇编不就啥都明白了吗。
想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。
从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单!
[/Quote]
Ctrl+V 来了楼主快跑吧
azure110 2010-05-05
  • 打赏
  • 举报
回复
问题一 是关于作用域 的问题,其实你后面一个函数返回 的那个指针已经是野指针了,你能正确反馈只能说是运气,
问题二,
string foo( );///返回的是string,不是const string,
赵4老师 2010-05-05
  • 打赏
  • 举报
回复
VC调试时按Alt+8,TC或BC用TD调试,打开汇编窗口看每句C对应的汇编不就啥都明白了吗。
想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。
从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单!
feidaozouren 2010-05-05
  • 打赏
  • 举报
回复
[Quote=引用 32 楼 einst1993 的回复:]
31L
写法不同会有
“指针的值不能修改“

“指向的内容不能修改“
的区别。
[/Quote]所指的是
char *const 和 const char* 
的区别吧
黑娃 2010-05-05
  • 打赏
  • 举报
回复
[Quote=引用 27 楼 jamseyang 的回复:]
你是指num++了吗,但事实并不是这样的呀!

引用 25 楼 falcomavin 的回复:
myfun(num+2)不会产生临时变量,不信你用断点看,执行到此没有临时变量产生,反且num的值增加了2
[/Quote]


你有设置断点观察myfun函数执行时num的值么?何以说事实不是这样?我经调试观察,执行到myfun的时候,实参num的确从10编程了12,而且函数中将num值改为了200,更重要的是num是个全局变量,假设真的是传递了临时变量tmp给myfun函数,则myfun中改变成200的值应该是tmp而不是num,你看看myfun执行完了之后num已经变成200了
Einst1993 2010-05-05
  • 打赏
  • 举报
回复
31L
写法不同会有
“指针的值不能修改“

“指向的内容不能修改“
的区别。
feidaozouren 2010-05-05
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 xiuxianshen 的回复:]
建议你看看const char *和char const *的差别吧
[/Quote]貌似二者没有区别吧

还有10楼的
“myfun(num+2)这里其实是对num的引用,并不是对临时变量num+2的修改,从cout结果也看出来了,修改是作用在num上的。”这句话不敢苟同,如果10楼的调试下,就会知道答案的,呵呵
feidaozouren 2010-05-05
  • 打赏
  • 举报
回复
[Quote=引用 29 楼 feidaozouren 的回复:]
其实楼主所说的临时变量并没有本质的区别,不过是作用域和生命期的问题罢了。
myfun(num+2);//产生临时int类型变量
int temp = num+2 的生命期是到主函数结束,故可以继续使用,而
char *p = "hello ABC";
char *p 在该函数返回时生命期就结束了,故不能继续使用
feidaozouren 2010-05-05
  • 打赏
  • 举报
回复
[Quote=引用楼主 jamseyang 的回复:]
问题1、myfun和GetString函数中产生的临时变量有什么本质的区别,为什么一个可以修改,另一个不可以修改
[/Quote]其实楼主所说的临时变量并没有本质的区别,不过是作用域和生命期的问题罢了。
myfun(num+2);//产生临时int类型变量
int temp = num+2 的生命期是到主函数结束,而
char *p = "hello ABC";
char *p 在该函数返回时生命期就结束了。
加载更多回复(28)

65,210

社区成员

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

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