C/C++如何返回一个数组/指针
我写C也有几年了,但是始终有个问题没搞清楚过就是返回多个值的时候.
譬如:
主函数如此调用
printf(SubFunction);//就是显示子函数返回的几个数值
子函数:
LPSTR SubFunction(void);
{char p[5];
p[1]='a';
.....
//对p进行赋值操作
return p;}
//这样写就会报警,编译通过但是输出是乱码.
////////////////////////////////////////////
另外一种写法:
LPSTR SubFunction(void);
{LPSTR p;
*(p+5)='\0';
*(p+x)=x;//赋值操作.不知道对不对
return p;}
//编译通过但是执行过程中出错--弹个筐筐出来.我一般戏称"非操" 即9X下的非法操作^_^
////////////////////////////////////////////
这2种是我一直没有实验成功过的办法.我在传出参数的时候一直没有比较好的办法,只有写结构体勉强应付.但是始终觉得不爽.不知道有没有高手能回答小弟的问题.
问题点数:20、回复次数:33Top
1 楼defyer007(深入浅出)回复于 2005-07-30 23:42:16 得分 0
传引用或指针参数啊,返回一个,再在函数体里面对参数进行修改,相当于返回了多个值
不知道是不是楼主想表达的意思Top
2 楼azuresn(司空摘星)回复于 2005-07-30 23:44:51 得分 0
如果你要返回指针,那么你的函数申明也应该和返回值类型对应,例如:
LPSTR * SubFunction(void) //LPSTR是你自己定的一个类型吧?
{
LPSTR * p;
//...中间处理过程
return p;
}Top
3 楼raynors(搞笑鸡)回复于 2005-07-30 23:53:46 得分 0
回楼上的 LPSTR 就是相当于 char *.属于WINDOWS基础类
defyer007:不知道你什么意思 可否写一二句出来SEE
///////
当然 p如果是全局变量就没这问题.但是我为了程序结构更加紧密基本上没用什么全局变量.我一个工程可能包含很多.H文件Top
4 楼megaboy(飞天御剑流之杀神一刀斩)回复于 2005-07-31 00:41:43 得分 0
数组不能作为函数的返回值,以数组作返回值是违法C标准的。但你可以返回指向数组的指针。
LPSTR SubFunction(void);
{LPSTR p;
*(p+5)='\0';
*(p+x)=x;//赋值操作.不知道对不对
return p;}
上面这段代码问题在于p没分配空间就使用了,会造成程序崩溃的。Top
5 楼LoveYouJustOneDay(哈哈)回复于 2005-07-31 00:50:36 得分 0
LPSTR SubFunction(void);
{char p[5];
p[1]='a';
.....
//对p进行赋值操作
return p;} // p是局部数组,返回之后就销毁了
{LPSTR p; //p的内存谁分配
*(p+5)='\0';
*(p+x)=x;//赋值操作.不知道对不对
return p;}
Top
6 楼LoveYouJustOneDay(哈哈)回复于 2005-07-31 00:53:44 得分 0
LPSTR SubFunction(void);
{char *p=malloc(5);
p[1]='a';
.....
//对p进行赋值操作
return p;}Top
7 楼atgjplh(永远的C/C++(unix/liunx))回复于 2005-07-31 09:27:22 得分 0
我们刚学的只能学习一下了Top
8 楼raynors(搞笑鸡)回复于 2005-07-31 10:19:38 得分 0
回LoveYouJustOneDay
char *p=malloc 语句会报错.
不过问题解决了,程序如下
LPSTR SubFunction(void)
{LPSTR p;
char a[5];
a[...]=...;
memset(&p,1,sizeof(p));
p=a;
return p
}
期待有更好的解决办法,或者大师详解.知其然而不能不知其所以然Top
9 楼raynors(搞笑鸡)回复于 2005-07-31 11:00:48 得分 0
不好了,出大问题了.
原封不动的子函数在main()下可以用cout和printf显示出
但是在WinMain下 用MessageBox都是乱码 更谈不上导出参数了Top
10 楼raynors(搞笑鸡)回复于 2005-07-31 14:01:25 得分 0
顶啊,我的问题还没解决啊.有这方面的经验的来解答
如何在WIN32程序里面返回多个值
除开结构体外Top
11 楼lyclowlevel(蓬蒿人)回复于 2005-07-31 14:11:34 得分 0
LPSTR SubFunction(void);
{char p[5];
p[1]='a';
.....
//对p进行赋值操作
return p;}
以上的写法显然是不可以的,因为p是一个局部变量,将局部变量做为返回值,将会使程序
的行为是未定义的。
解决的办法是:你在SubFunction中进行动态分配,然后返回由动态分配而得的指针。
char *p=new char[5];
//进行赋值操作;
return p;
Top
12 楼LoveYouJustOneDay(哈哈)回复于 2005-07-31 14:13:02 得分 0
malloc有些编译器下需要强制转换
char *p=(char*)malloc(5);
LPSTR 这些类型还是尽量少用比较好
Top
13 楼raynors(搞笑鸡)回复于 2005-07-31 21:35:58 得分 0
我不多说了直接把代码贴出拉了
#include "windows.h"
char * CreateRandomWords()
{ char * p=(char * )malloc(sizeof(p));
char pp[5];
// memset(&pp,1,sizeof(pp));
// memset(&p,1,sizeof(p));
pp[0]='1';
pp[1]='2';
pp[2]='2';
pp[3]='2';
pp[4]='2';
pp[5]='\0';
p=pp;
// MessageBox(NULL,p,"DDD",MB_OK);
return p;
}
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hpInstance,LPSTR D3,int d4)
{ char * DDD ;//=(char *)malloc(sizeof(DDD));
DDD=CreateRandomWords();
MessageBox(NULL,DDD,"ddd",MB_OK);
}
问题是谁能把DDD搞个正确的数值出来呢???如果是
main()
{char *DDD;
printf(DDD)} 输出就是正确的 问题出在那里???
Top
14 楼dlutyuanhongl()回复于 2005-08-01 07:50:39 得分 0
//// 正确写法如下
char * CreateRandomWords()
{
//
char pp[6];
// memset(&pp,1,sizeof(pp));
// memset(&p,1,sizeof(p));
pp[0]='1';
pp[1]='2';
pp[2]='2';
pp[3]='2';
pp[4]='2';
pp[5]='\0';
char * p = new char[sizeof(pp)];
strcpy(p, pp);
// MessageBox(NULL,p,"DDD",MB_OK);
return p;
}
/// 使用时
char * pp = CreateRandomWords();
cout << pp << endl;
delete pp; // 这儿不能少Top
15 楼jeanssun(西部牛仔||孙耀文)回复于 2005-08-01 08:38:56 得分 0
楼上的哥们,p是局部变量啊,这样是不对的!可以考虑传递指针进来!
Top
16 楼yc0188(守护瓶(萍))回复于 2005-08-01 08:53:28 得分 0
LPSTR SubFunction(void);
{LPSTR p = new(); //开辟空间后再返回
*(p+5)='\0';
*(p+x)=x;//赋值操作.不知道对不对
return p;}Top
17 楼Atomictry(天影)回复于 2005-08-01 09:07:21 得分 0
#include "windows.h"
char * CreateRandomWords()
{ char * p=(char * )malloc(sizeof(p));
char pp[5];
// memset(&pp,1,sizeof(pp));
// memset(&p,1,sizeof(p));
pp[0]='1';
pp[1]='2';
pp[2]='2';
pp[3]='2';
pp[4]='2';
pp[5]='\0';
p=pp; // 你这里写有何意义? p指向pp地址,当函数返回的时候,pp就出栈了,p指针指向无效内存空间,也许有时候是对的,因为碰巧p指向的内存的值还没变,但是这块内存并不是你的了。
// MessageBox(NULL,p,"DDD",MB_OK);
return p;
}
/**************************/
void Caller();
void SubFunction(char *pText1, char *pText2);
// 方法1,用静态变量进行返回
char *SubFunction(void)
{
static char szText[5] = "adfa"; // 用静态空间
//对p进行赋值操作
return szText;
}
void Caller() // 这个函数调用SubFunction
{
TRACE("%s\n", SubFunction);
}
// 方法2,用指针传递
void SubFunction(char *pText1, char *pText2)
{
// 对pText1, pText2运算
strcpy(pText1, "love");
strcpy(pText2, "you");
return;
}
void Caller() // 这个函数调用SubFunction
{
char szText1[5], szText2[5]; // 当然这里也可以动态分配内存
SubFunction(szText1, szText2); // szText1, szText2就是带回的值
TRACE("%s %s\n", szText1, szText2);
}
注: // 如果是c++的话,还可以用引用带回返回值。Top
18 楼sunstarstar(孙逊)回复于 2005-08-01 10:42:24 得分 0
楼上的说得精辟,我帮忙补充一下 ^_^
// 方法3,使用引用实现
void SubFunction(char& pText1, char& pText2);//先声明一下
...
void SubFunction(char& pText1, char& pText2)
{
...
return;
}
void Caller() // 这个函数调用SubFunction
{
....
}
Top
19 楼OpenHero(开勇)回复于 2005-08-01 11:09:08 得分 0
楼主局部变量都没有搞清楚~~~
楼上两位差不多解决了
但是还有方法
不过也说不上
就是在通一个class里面解决~~~
Top
20 楼yfqian(小钱)回复于 2005-08-01 14:22:14 得分 0
局部变量存放在栈内存,当函数返回时就释放内存,所以返回局部指针是很危险的,这时它指的内容不确定。。Top
21 楼tb01412(tb)回复于 2005-08-01 15:53:10 得分 0
典型的局部变量和内存分配,回收的问题
分配内存有两种方式,一种是在堆上分配,也就是malloc和new这两个东东,一个是用于C,一个是用于C++,在堆上分配的内存要用free和delete来释放
另一种分配内存的方式是在栈上分配,就比如char p[10],就会在栈上开辟十个字节的空间,在栈上分配的空间会在其作用域不存在时自动释放,比如你在一个函数中声明一个这样的变量,当这个函数退出时,这个变量所指向的空间会被收回;
所以你在子函数中声明一个char *变量,并用malloc分配空间后,并没有手动释放,那么在其它函数访问它就是合法的,但程序结束时就手动释放它,不然的话,就有内存泄漏的问题
你在子函数中声明一个数组,它会在栈上分配空间,当此子函数结束后,些内存中的内容会被自动回收
所以你在调用的函数中就引用了一个被释放了的地址,当然要出错了
最好还想说一点的是:声明一个全局变量,它会被自动初始化(好像是编译器做的工作),而一个局部变量是不会被自动初始化;而字符串常量和宏定义的东东在被编译时好像已被放在了文本段(请参阅可执行文件的结构)Top
22 楼raynors(搞笑鸡)回复于 2005-08-23 17:04:35 得分 0
首先感谢大家的耐心阅读,这个帖子出来有一段时间了.
再次说这个问题捆饶了我很久了.我学C也有一些年头了,每次遇到这个问题我都回避了.
出去了几天 本来想结帖.但是看了楼上的几位的发言.我的确是学到了不少东西.
但是我的实质问题仍然没有解决.
====================================大家的建议
dlutyuanhongl() 的解法我没有试验,似乎他的解法马上就被楼下的给否决了
Atomictry(天影 -- 哈哈哈哈,日子没法过了) 仁兄给出了2种可以实现的方案
不过我的SubFunctionName = CreateRandomWord(XXX) 一眼就看的出来.我肯定是不打算返回静态值--静态值的做法的确有效--不过只在测试程序结构时候用的上
另外一种就是引用指针
我想说 引用指针--那是何~~~必~~~呢 我大可在MIAN 前面 char PP[10],然后直接给PP赋值,简单的多了.
/////////////////////////////////////////
我题目的前提就是怎样在不定义全局变量的情况下来返回参数(结构体是有效的,但是结构体我用不上)
--另外说一句,我只是想在平常锻炼我的写大型程序的能力,不是钻牛角尖.大家都知道大型程序结构最重要.如果连这个小小的问题都要用到全局变量,那写出来的程序结构怕是日后连自己都搞不明白了
再次提出我的问题
char * CreateRandomWord()
{
char pp[5];
//对pp赋值,这个赋值过程一定要存在,因为是random
return (可以是任何变量,只要引出来的是PP内容)
}
谢谢大家
Top
23 楼raynors(搞笑鸡)回复于 2005-08-24 12:34:57 得分 0
顶起 问题仍在Top
24 楼yayafu(维生素C)回复于 2005-08-24 12:59:15 得分 0
都给你说明了啊。不能用局部变量,如果不想用全局变量,就要用动态分配空间 malloc(),还要注意用free()释放指针,回去再好好学学C,这些年可以说你还没把C学懂Top
25 楼yayafu(维生素C)回复于 2005-08-24 13:09:28 得分 10
char * CreateRandomWord()
{
char *pp = new char[5]; //或 (char*)malloc(5);
//对pp赋值,这个赋值过程一定要存在,因为是random
return pp(可以是任何变量,只要引出来的是PP内容)
}
winmain(...)
{
char* p = CreateRandomWord();
//显示 p
delete[] p; //或free(p);
}
Top
26 楼bugebear3(bug)回复于 2005-08-24 15:30:31 得分 0
楼上讲得是对的.
使用malloc()分配的是一块连续的内存空间,由于它是连续的,我们可以象操作数组一样操作它.这也是为什么我们常将malloc()用来处理数组的动态分配的缘由了.Top
27 楼djfu(飞龙在天)回复于 2005-08-24 20:15:15 得分 0
yayafu
===========
正解。Top
28 楼djfu(飞龙在天)回复于 2005-08-24 20:24:48 得分 10
再次提出我的问题
char * CreateRandomWord()
{
char pp[5];
//对pp赋值,这个赋值过程一定要存在,因为是random
return (可以是任何变量,只要引出来的是PP内容)
}
==============================
如果一定要这样的话,也可以。
有2种方法可以实现:
1)、在函数里面申请空间,把pp的内容拷到新申请的空间去。但是函数外面用完记得释放内存。
char * CreateRandomWord()
{
char pp[5];
//.... Any operator for pp
char *temp = new char[5];
memcpy(temp, pp, 5);
return temp;
}
2) 可以给CreateRandomWord传递一个已经分配好内存空间的指针或引用进来
void CreateRandomWord( char *&Pointer)
{
char pp[5];
//.... Any operator for pp
memset(Pointer, pp, 5);
}
Top
29 楼waynahu(FIRE_BIRD-->涅磐)回复于 2005-08-25 09:19:19 得分 0
晕死, 看来楼主对c的内存管理知之甚少啊!Top
30 楼xiao_xiao_zi(笑小子)回复于 2005-08-25 11:22:42 得分 0
~~~~~~~~~~~~
用了C几年~~~~,还会犯这种错误~~~
在函数内分配空间,然后返回指针Top
31 楼heguosheng(何国胜)回复于 2005-08-25 14:32:14 得分 0
在函数内分配空间,然后返回指针
---------------------------
对于内存,谁分配谁回收
对于处女,谁污染谁治理
好象楼上的违反了这个原则
不过也不失为一种解决方法Top
32 楼robothn(雷鸟)回复于 2005-08-25 14:35:41 得分 0
1.函数内 static 变量
2.singleton
3.
const vector<string> & GetMyStrings()
{
vector<string> vs;
vs.push_back("1");
vs.push_back("3");
vs.push_back("5");
return vs;
}
vector<string> vs = GetMyStrings();
办法很多Top
33 楼searoom(海龙)回复于 2005-08-25 22:02:01 得分 0
1. 不能返回在函数内部的 "栈内存", 因为它在函数退出的时候会被自动销毁,这也是我们写函数定义局部变量而不担心其释放问题
2. 返回在函数内部申请的"堆内存",必须由用户自己控制该内存的释放,因为这点不好控制,容易被忘记,所以大多都给函数传递外部的指针进来. 如果你把它看作类似于 New 一样, 也好理解Top




