工大后院

 找回密码
 加入后院

扫一扫,访问微社区

QQ登录

只需一步,快速开始

搜索
查看: 3247|回复: 20

有请编程高手指导下!!!

[复制链接]
发表于 2008-2-24 00:37 | 显示全部楼层 |阅读模式
#include <iostream.h>
char *f()
{
char s[]="HELLO";
return s;
}
char *f1()
{
char *p=NULL;
char s[]="world";
p=s;
return p;
}
int *f2()
{
int *p;
int i = 32;
p = &i;
return p;
}

void main()
{
     cout <<  << endl;
     cout <<f1() << endl;
     cout << f2() << endl;
}
该程序的输出结果是f(),f1()输出乱码,f2()输出内存地址。


改动下程序
#include <iostream.h>
char *f()
{
char s[]="HELLO";
return s;
}
char *f1()
{
char *p=NULL;
char s[]="world";
p=s;
return p;
}
int *f2()
{
int *p;
int i = 32;
p = &i;
return p;
}

void main()
{
     cout << *f() << endl;
     cout <<*f1() << endl;
     cout << *f2() << endl;
}
输出结果是 H
                   W
                   32


哪位高手可以解释下原因????????????
发表于 2008-2-24 12:42 | 显示全部楼层
应该是返回值的类型与其所在函数类型的关系问题
回复

使用道具 举报

发表于 2008-2-24 12:58 | 显示全部楼层
f2()中返回的是临时变量的指针
这个也许在不同的编译器不同的系统有不同的结果?
个人觉得三个函数都不安全
回复

使用道具 举报

发表于 2008-2-24 13:39 | 显示全部楼层
函数也是内存地址,看作指针,f()、f1()返回的是内存地址,但是该地址要转变为char型,不一定可转为可见字符及有意义字符,故是乱码,而f2()的转为int型,故是地址(数字)。

*f()、*f1()、*f2()则为指针指向内容,因此可输出H、W、32。

菜鸟看法,望版主众人指正。共同进步。
回复

使用道具 举报

发表于 2008-2-24 13:51 | 显示全部楼层
  1. #include
  2. char *f1()
  3. {
  4. char *p=NULL;
  5. char s[]="world";
  6. p=s;
  7. std::cout<<&p<<std::endl;
  8. return p;
  9. }
  10. int main(){
  11. std::cout<<f1()<<std::endl;
  12. std::cout<<(int)f1()<<std::endl;
  13. }
复制代码
受教了,THX LS

[ 本帖最后由 onttpi 于 2008-2-24 13:56 编辑 ]
回复

使用道具 举报

发表于 2008-2-24 13:58 | 显示全部楼层
突然想起以前看过的东西,有兴趣的猜猜输出是:
  1. std::cout<<'A'<<'AA'<<std:endl;
复制代码
注意,两个都是单引号...
回复

使用道具 举报

发表于 2008-2-24 14:05 | 显示全部楼层
LZ的代码用printf("%p",f1());会有不同的结果..
printf VS cout..
回复

使用道具 举报

发表于 2008-2-24 14:15 | 显示全部楼层
cout用了运算符重载,可以说是比较“智能”的,无须像printf指定类型……

刚开始看C++ Primer
回复

使用道具 举报

发表于 2008-2-24 14:16 | 显示全部楼层
char s[]="HELLO"; 这样声明的变量是在堆栈区里的.当函数调用结束后(执行完return s;),该指针所指的内存单元将会被释放,这个函数是有隐患的.
回复

使用道具 举报

发表于 2008-2-24 14:50 | 显示全部楼层
我觉得cout输出串指针导致的问题吧。
cout输入串指针也是按照是否\0来判断结束的,返回的指针是指向首地址,在下个cout之前,无法获取到\0,所以输出乱码。
还有,楼上的char s[]="HELLO"应该是在静态存储区的吧?在程序结束前都不会自动释放。
回复

使用道具 举报

发表于 2008-2-24 22:41 | 显示全部楼层
静态区需要const来声明吧....
回复

使用道具 举报

发表于 2008-2-25 09:21 | 显示全部楼层
静态区需要static来声明吧....
回复

使用道具 举报

发表于 2008-2-25 10:55 | 显示全部楼层
是我搞错,char *ptr="hello"是静态,char s[]="hello"是堆栈。
回复

使用道具 举报

发表于 2008-2-25 17:02 | 显示全部楼层
我觉得4楼说得不准确,指针只有分指向某种类型的指针,指针本身严格来说不属于任何一种类型。
回复

使用道具 举报

发表于 2008-2-25 17:07 | 显示全部楼层
指整应该就是一个内存地址吧?或者说指针本质上是一个数?
回复

使用道具 举报

发表于 2008-2-26 14:31 | 显示全部楼层
说指针本身是个数没错,因为是变量的值不外乎也就是内存位置所存储的值,指针也一样。但是也不能把指针跟数等同,因为它不完全支持数的运算啊。
回复

使用道具 举报

发表于 2008-3-8 22:08 | 显示全部楼层
我是搞嵌入式的 对该问题有些看法 特来吹吹牛

首先这里涉及的堆(heap)和栈(stack)的概念

在一个函数内如果静态分配内存 就是像这里的 char s[]="HELLO";
是在该函数的stack中分配 生命周期只在该函数范围内 一旦函数返回 变量就失去意义的
同时由于在嵌入式系统中 函数的栈通常比较小 所以如果分配比较大的内存 就需要在heap中动态分配 如
char* longString = (char*)malloc(MAX); // MAX的值比较大
同时可以把该指针返回
return longString;
后在main函数可以继续使用

像上面那样即使能够输出正确的返回值也是不安全的 最常见的bug就是会出现内存泄露

。。。。。。。。。。。
就当我是吹牛吧

[ 本帖最后由 kpkp 于 2008-3-8 22:46 编辑 ]
回复

使用道具 举报

发表于 2008-3-9 00:57 | 显示全部楼层
LS的是观点 3F 9F都有说了
欢迎常过来“吹牛”
回复

使用道具 举报

发表于 2008-3-9 16:50 | 显示全部楼层
原来我不懂....
回复

使用道具 举报

发表于 2008-3-15 17:08 | 显示全部楼层
17楼的仁兄说的非常正确
不必要太谦虚
不管是C调用还是STD调用,都在函数调用时在栈区分配合适的内存,作为存储和运行的空间.
所以当函数返回时,虽然返回的指针值没有变,但是指针所指向的数据已经被POP掉了,也就是指向了内容不明的地址了.
这方面内容要搞清楚,建议读一读汇编的书,专门看"汇编与C的混合编程"还有函数调用规则.
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入后院

本版积分规则

QQ|Archiver|手机版|小黑屋|广告业务Q|工大后院 ( 粤ICP备10013660号 )

GMT+8, 2024-5-15 04:40

Powered by Discuz! X3.5

Copyright © 2001-2024 Tencent Cloud.

快速回复 返回顶部 返回列表