什么是函数的返回值
4个回答
展开全部
一个函数的函数名既是该函数的代表,也是一个变量。由于函数名变量通常用来把函数的处理结果数据带回给调用函数,即递归调用,所以一般把函数名变量称为返回值。
C++中编辑
函数可以有返回值,也可以没有返回值。对于没有返回值的函数,功能只是完成一个操作,应将返回值类型定义为void,函数体内可以没有return语句,当需要在程序指定位置退出时,可以在该处放置一个
例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
voidbackward(intn)
{
cout<<n%10;
if(n<10)return;
elsebackward(n/10);
}
intmain()
{
intn;
cout<<"输入整数:"<<endl;
cin>>n;
cout<<"原整数:"<<n<<endl<<"反向数:";
backward(n);
cout<<endl;
return0;
}
函数可以有返回值,只要 return 就可以给出一个。不过我们常常不用它--有两个原因:
1、C/C++里返回值是复制出去的,而对于大的对象,复制的代价很高;
2、有些对象是不能复制的--至少编译器不知道怎么复制--比如数组。
于是我们有了很多这样的函数:
bool GetObj(ObjType& obj);
bool Encode(const char* src, char* dest);
用一个参数来代替返回值,而返回值只是指示函数执行是否成功。我本人一直固执的认为,这是C的处理方式,C++不该这样,返回就是返回,就该光明正大的返回,而不是在文档里为某个参数悄悄的注上: // out
诚然返回一个大对象是困难的,但这个困难是 C 程序员的,而不是 C++ 程序员的 -- 我们可以返回指针。C也有指针,但很少有人敢在 C 函数里返回一个指针,因为:
1、如果指针指向栈变量,毫无疑问,要么你不用这个返回值,要么是一个错误;
2、如果指针指向堆变量,要么你在祈祷用这个函数的程序员会好好的看文档且足够细心会调用 free,要么就是内存泄漏;
3、如果指针指向 static 变量,那么用这个函数的程序员牢牢记住“下次调用这个函数以后,上次的返回值也会跟着变”,要么就是你被别人骂成“专出 BUG 的垃圾”。
在C++里直接返回裸指针的话,情况并不会有什么起色,不过 C++ 有智能指针的,通常它们指向堆变量,占用的空间和裸指针一样大。考虑前面第一个函数,我们写成:
std::auto_ptr<ObjType> GetObj();
那么一切迎刃而解,返回值如果你不要,作为临时变量,会立即被析构,返回的对象被释放;如果你要,就得赋值给另一个智能指针。总之不用程序员记得,编译器会保证这个对象的释放。
考虑第二个函数,稍微有一点麻烦,因为 auto_ptr 是不能用来持有数组的,不过,在C++的世界里,std::string 几乎总是比 char* 好用:
std::auto_ptr<std::string> Encode(const char* src);
最后考虑最麻烦的情况:
bool AssembleObjList(ObjType objList[], size_t length);
这种类型的函数无论是在 C标准库里,还是在各种操作系统的 API 里,比比皆是,事实上它存在两大缺陷:
1、如果需要的数量超出给出的,要么是一个安全问题(经典的缓冲区溢出,如 strcpy),要么是失败,程序员不得不作出估计--众所周知,程序员的估计能力比他们的薪水低得多;
2、如果执行成功,到底 Assemble 了多少个?
于是我们见到了这样的函数:
bool AssembleObjList(ObjType objLIst[], size_t* lengthPtr);
这个函数通常是两步调用的:
size_t length = 0;
AssembleObjList(0, &length);
ObjType* objList = new ObjType[length];
AssembleObjList(objList, &length);
for(size_t i=0; i<length; ++i)// 处理每个元素
这种形式能解决上面列出的两个问题,但这实在是太麻烦、太可恶了。我的答案仍然是--C++程序员应该用C++的库:
std::auto_ptr<std::vector<ObjType> > AssembleObjList();
又干净,又舒服!
C++标准库里居然没有一个可以持有数组的智能指针,所以 boost库不错,可以这样:
std::pair<boost::scoped_array<ObjType>, size_t> AssembleObjList();
可惜这个并不比标准库的解法更优秀--因为要返回数目的缘故,不过我个人更喜欢这个解,因为他更接近最优的解--传说中的 trule 手法:
TruleVector<ObjType> AssembleObjList();
其中 TruleVector是这样一个模板:它只有两种操作,一是构造,二是自动转型为 std::vector,而且它具有 “auto_ptr 式的所有权转移语义”。也就是说,TruleVector除了作为数组型的返回值,你无法把他用于其它任何任务。
不过由于 std::vector具有值语义,所以写的代码还是稍微有一点不同寻常:
typedef std::vector<ObjType> ObjListType;
ObjListType list;
list.swap(AssembleObjList());
最后一句在有的产品上可能要写成:
list.swap(static_cast<ObjListType>(AssembleObjList()));
这样别扭的原因,可以归咎于C++库里缺一个引用语义的线性容器。
php中编辑
值通过使用可选的返回语句返回。任何类型都可以返回,其中包括列表和对象。这导致函数立即结束它的运行,并且将控制权传递回它被调用的行。更多信息见 return()。
例子 17-11. return()的用法
<?php
function square($num)
{
return $num * $num;
}
echo square(4); // outputs '16'.
?>函数不能返回多个值,但为了获得简单的结果,可以返回一个列表。
例子 17-12. 返回一个数组以得到多个返回值
<?php
function small_numbers()
{
return array (0, 1, 2);
}
list ($zero, $one, $two) = small_numbers();
?>从函数返回一个引用,必须在函数声明和指派返回值给一个变量时都使用引用操作符 & :
例子 17-13. 由函数返回一个引用
<?php
function &returns_reference()
{
return $someref;
}
$newref =& returns_reference();
?>
C++中编辑
函数可以有返回值,也可以没有返回值。对于没有返回值的函数,功能只是完成一个操作,应将返回值类型定义为void,函数体内可以没有return语句,当需要在程序指定位置退出时,可以在该处放置一个
例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
voidbackward(intn)
{
cout<<n%10;
if(n<10)return;
elsebackward(n/10);
}
intmain()
{
intn;
cout<<"输入整数:"<<endl;
cin>>n;
cout<<"原整数:"<<n<<endl<<"反向数:";
backward(n);
cout<<endl;
return0;
}
函数可以有返回值,只要 return 就可以给出一个。不过我们常常不用它--有两个原因:
1、C/C++里返回值是复制出去的,而对于大的对象,复制的代价很高;
2、有些对象是不能复制的--至少编译器不知道怎么复制--比如数组。
于是我们有了很多这样的函数:
bool GetObj(ObjType& obj);
bool Encode(const char* src, char* dest);
用一个参数来代替返回值,而返回值只是指示函数执行是否成功。我本人一直固执的认为,这是C的处理方式,C++不该这样,返回就是返回,就该光明正大的返回,而不是在文档里为某个参数悄悄的注上: // out
诚然返回一个大对象是困难的,但这个困难是 C 程序员的,而不是 C++ 程序员的 -- 我们可以返回指针。C也有指针,但很少有人敢在 C 函数里返回一个指针,因为:
1、如果指针指向栈变量,毫无疑问,要么你不用这个返回值,要么是一个错误;
2、如果指针指向堆变量,要么你在祈祷用这个函数的程序员会好好的看文档且足够细心会调用 free,要么就是内存泄漏;
3、如果指针指向 static 变量,那么用这个函数的程序员牢牢记住“下次调用这个函数以后,上次的返回值也会跟着变”,要么就是你被别人骂成“专出 BUG 的垃圾”。
在C++里直接返回裸指针的话,情况并不会有什么起色,不过 C++ 有智能指针的,通常它们指向堆变量,占用的空间和裸指针一样大。考虑前面第一个函数,我们写成:
std::auto_ptr<ObjType> GetObj();
那么一切迎刃而解,返回值如果你不要,作为临时变量,会立即被析构,返回的对象被释放;如果你要,就得赋值给另一个智能指针。总之不用程序员记得,编译器会保证这个对象的释放。
考虑第二个函数,稍微有一点麻烦,因为 auto_ptr 是不能用来持有数组的,不过,在C++的世界里,std::string 几乎总是比 char* 好用:
std::auto_ptr<std::string> Encode(const char* src);
最后考虑最麻烦的情况:
bool AssembleObjList(ObjType objList[], size_t length);
这种类型的函数无论是在 C标准库里,还是在各种操作系统的 API 里,比比皆是,事实上它存在两大缺陷:
1、如果需要的数量超出给出的,要么是一个安全问题(经典的缓冲区溢出,如 strcpy),要么是失败,程序员不得不作出估计--众所周知,程序员的估计能力比他们的薪水低得多;
2、如果执行成功,到底 Assemble 了多少个?
于是我们见到了这样的函数:
bool AssembleObjList(ObjType objLIst[], size_t* lengthPtr);
这个函数通常是两步调用的:
size_t length = 0;
AssembleObjList(0, &length);
ObjType* objList = new ObjType[length];
AssembleObjList(objList, &length);
for(size_t i=0; i<length; ++i)// 处理每个元素
这种形式能解决上面列出的两个问题,但这实在是太麻烦、太可恶了。我的答案仍然是--C++程序员应该用C++的库:
std::auto_ptr<std::vector<ObjType> > AssembleObjList();
又干净,又舒服!
C++标准库里居然没有一个可以持有数组的智能指针,所以 boost库不错,可以这样:
std::pair<boost::scoped_array<ObjType>, size_t> AssembleObjList();
可惜这个并不比标准库的解法更优秀--因为要返回数目的缘故,不过我个人更喜欢这个解,因为他更接近最优的解--传说中的 trule 手法:
TruleVector<ObjType> AssembleObjList();
其中 TruleVector是这样一个模板:它只有两种操作,一是构造,二是自动转型为 std::vector,而且它具有 “auto_ptr 式的所有权转移语义”。也就是说,TruleVector除了作为数组型的返回值,你无法把他用于其它任何任务。
不过由于 std::vector具有值语义,所以写的代码还是稍微有一点不同寻常:
typedef std::vector<ObjType> ObjListType;
ObjListType list;
list.swap(AssembleObjList());
最后一句在有的产品上可能要写成:
list.swap(static_cast<ObjListType>(AssembleObjList()));
这样别扭的原因,可以归咎于C++库里缺一个引用语义的线性容器。
php中编辑
值通过使用可选的返回语句返回。任何类型都可以返回,其中包括列表和对象。这导致函数立即结束它的运行,并且将控制权传递回它被调用的行。更多信息见 return()。
例子 17-11. return()的用法
<?php
function square($num)
{
return $num * $num;
}
echo square(4); // outputs '16'.
?>函数不能返回多个值,但为了获得简单的结果,可以返回一个列表。
例子 17-12. 返回一个数组以得到多个返回值
<?php
function small_numbers()
{
return array (0, 1, 2);
}
list ($zero, $one, $two) = small_numbers();
?>从函数返回一个引用,必须在函数声明和指派返回值给一个变量时都使用引用操作符 & :
例子 17-13. 由函数返回一个引用
<?php
function &returns_reference()
{
return $someref;
}
$newref =& returns_reference();
?>
展开全部
程序执行完后会将一个数(或是其他类型的值)返回给这个函数(相当于这个函数最后储存了这个数,是这个数的代言人,呵呵)
举个列:
int A( ){
int a=2;
int b=4;
int c;
c=a+b;
return c;
}
主函数调用这个函数时:
void main( ){
cout<<A( );
}
就将return的那个值输出来了;
倘若没有return c这句,得出的结果不会输出来;
A()这个函数执行后什么也没得到,其只是执行了
一个加法问题,留下的是“空气”(呵呵)。
举个列:
int A( ){
int a=2;
int b=4;
int c;
c=a+b;
return c;
}
主函数调用这个函数时:
void main( ){
cout<<A( );
}
就将return的那个值输出来了;
倘若没有return c这句,得出的结果不会输出来;
A()这个函数执行后什么也没得到,其只是执行了
一个加法问题,留下的是“空气”(呵呵)。
本回答被提问者采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
函数的返回值其实很简单,你把函数看成一个具备某种功能的黑盒子,调用函数的时候,就相当于给它传入函数要求的数据,然后函数开始按它的功能运行,最后输出一个运行结果,这个输出的结果就是返回值。只是不同的函数实现不同的功能。
调用函数的时候传入的叫参数,传入的参数要严格的按函数的定义要求,如参数的类型。如果有多个参数还必须按每个参数的顺序来传入。
当然函数不一定要返回一个值,可以返回空值。
调用函数的时候传入的叫参数,传入的参数要严格的按函数的定义要求,如参数的类型。如果有多个参数还必须按每个参数的顺序来传入。
当然函数不一定要返回一个值,可以返回空值。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
解释:
一个函数的函数名既是该函数的代表,也是一个变量。由于函数名变量通常用来把函数的处理结果数据带回给调用函数,即递归调用,所以一般把函数名变量称为返回值。
相关简介:
函数可以有返回值,只要 return 就可以给出一个。不过人们常常不用它,有两个原因:
1、C/C++里返回值是复制出去的,而对于大的对象,复制的代价很高;
2、有些对象是不能复制的--至少编译器不知道怎么复制--比如数组。
于是有了很多这样的函数:
bool GetObj(ObjType& obj);
bool Encode(const char* src, char* dest);
用一个参数来代替返回值,而返回值只是指示函数执行是否成功。我本人一直固执的认为,这是C的处理方式,C++不该这样,返回就是返回,就该光明正大的返回,而不是在文档里为某个参数悄悄的注上: // out
诚然返回一个大对象是困难的,但这个困难是 C 程序员的,而不是 C++ 程序员的 -- 也可以返回指针。C也有指针,但很少有人敢在 C 函数里返回一个指针,因为:
1、如果指针指向栈变量,毫无疑问,要么不用这个返回值,要么是一个错误;
2、如果指针指向堆变量,要么在祈祷用这个函数的程序员会好好的看文档且足够细心会调用 free,要么就是内存泄漏;
3、如果指针指向 static 变量,那么用这个函数的程序员牢牢记住“下次调用这个函数以后,上次的返回值也会跟着变”,要么就是被别人骂成“专出 BUG 的垃圾”。
一个函数的函数名既是该函数的代表,也是一个变量。由于函数名变量通常用来把函数的处理结果数据带回给调用函数,即递归调用,所以一般把函数名变量称为返回值。
相关简介:
函数可以有返回值,只要 return 就可以给出一个。不过人们常常不用它,有两个原因:
1、C/C++里返回值是复制出去的,而对于大的对象,复制的代价很高;
2、有些对象是不能复制的--至少编译器不知道怎么复制--比如数组。
于是有了很多这样的函数:
bool GetObj(ObjType& obj);
bool Encode(const char* src, char* dest);
用一个参数来代替返回值,而返回值只是指示函数执行是否成功。我本人一直固执的认为,这是C的处理方式,C++不该这样,返回就是返回,就该光明正大的返回,而不是在文档里为某个参数悄悄的注上: // out
诚然返回一个大对象是困难的,但这个困难是 C 程序员的,而不是 C++ 程序员的 -- 也可以返回指针。C也有指针,但很少有人敢在 C 函数里返回一个指针,因为:
1、如果指针指向栈变量,毫无疑问,要么不用这个返回值,要么是一个错误;
2、如果指针指向堆变量,要么在祈祷用这个函数的程序员会好好的看文档且足够细心会调用 free,要么就是内存泄漏;
3、如果指针指向 static 变量,那么用这个函数的程序员牢牢记住“下次调用这个函数以后,上次的返回值也会跟着变”,要么就是被别人骂成“专出 BUG 的垃圾”。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询
广告 您可能关注的内容 |