为什么不把要返回元素直接当成函数的返回值返回呢

不把要返回元素直接当成函数的返回值返回的原因:如果把要返回元素直接当成函数的返回值返回,会使函数的返回值变得复杂,不易阅读和理解,并且会影响到使用该函数的程序的代码结构,还会使返回值的结构变得极其复杂,导致使用时难以理解和处理。

一、不把要返回元素直接当成函数的返回值返回的原因

如果把要返回元素直接当成函数的返回值返回,会使函数的返回值变得复杂,不易阅读和理解,并且如果要增加新的返回元素,则需要修改函数的返回值,这样会影响到使用该函数的程序的代码结构,不利于软件的扩展和维护,此外如果返回的元素之间有复杂的数据结构关系,例如嵌套的数据结构,还会使返回值的结构变得极其复杂,导致使用时难以理解和处理。

例如C里没有异常没有type deduction也无所谓构造函数,你的一个函数如果可能成功可能失败,通用做法是返回一个状态码,真正的返回值用传指针方式弄出去。这样基本也就是C能做到的最好效果了。C++里则完全不同,虽然传统方式差不多也是这样的,特别是某style guide这种邪教资料四处泛滥破坏历史发展进程的情况下。这个确实很无奈。C++标准前进的方向是该返回什么就返回什么,guaranteed copy elision、optional、structured binding、tuple都是可以使用的工具。直接返回该返回的对象优势也很多,不需要这个对象default constructible(可能需要std::optional / boost::optional / exception式error reporting),可以auto推导类型方便重构,部分场景下可以改进性能等等。错误报告可以像boost一样使用异常或者传指针/引用的error code来实现,一般error code的类型不会没事重构的。

二、函数返回值公式简介

函数可以有返回值,也可以没有返回值。

  • 没有返回值的函数:功能只是完成一个操作,应将返回值类型定义为void,函数体内可没有return语句。
  • 有返回值的函数:函数的最后会有一个返回值return,可以用来获取该函数执行结果返回给该函数,让外部调用该函数的。

返回值可指定,如果不指定默认返回None。函数的返回值类型是在定义函数时指定的。return 语句中表达式的类型应与定义函数时指定的返回值类型一致。如果不一致,则以函数定义时的返回值类型为准,对 return 语句中表达式的类型自动进行转换,然后再将它返回给主调函数使用。

在调用函数时,如果需要从被调函数返回一个值供主调函数使用,那么返回值类型必须定义成非 void 型。此时被调函数中必须包含 return 语句,而且 return 后面必须要有返回值,否则就是语法错误。一个函数中可以有多个 return 语句,但并不是所有的 return 语句都起作用。执行到哪个 return 语句,就是哪个 return 语句起作用,该 return 语句后的其他语句都不会执行。

三、C++中的返回值

函数可以有返回值,只要 return 就可以给出一个,不过常常不用它,有两个原因:第一,C/C++里返回值是复制出去的,而对于大的对象,复制的代价很高;第二,有些对象是不能复制的,至少编译器不知道怎么复制,比如数组。于是有了下面这样的函数:

bool GetObj(ObjType& obj);
bool Encode(const char* src, char* dest);

用一个参数来代替返回值,而返回值只是指示函数执行是否成功。返回一个大对象是困难的,但这个困难存在于 C 程序中,而不是 C++ 程序中。 C 函数里较少通过返回一个指针来返回对象,因为:

  1. 如果指针指向栈变量,毫无疑问,要么不用这个返回值,要么是一个错误。
  2. 如果指针指向堆变量,需要用这个函数的程序员会好好的看文档且足够细心会调用 free,要么就是内存泄漏。
  3. 如果指针指向 static 变量,那么用这个函数的程序员牢牢记住“下次调用这个函数以后,上次的返回值也会跟着变”。

在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 里,比比皆是,事实上它存在两大缺陷:第一,如果需要的数量超出给出的,要么是一个安全问题(经典的缓冲区溢出,如 strcpy),要么是失败,程序员不得不作出估计——众所周知,程序员的估计能力比他们的薪水低得多;第二,如果执行成功,到底 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++的库将会变得又干净,又舒服:

std::auto_ptr<std::vector<ObjType> > AssembleObjList();

延伸阅读

return 工作原理

被调函数运行结束后才会返回主调函数,但是被调函数运行结束后系统为被调函数中的局部变量分配的内存空间就会被释放。也就是说,return 返回的那个值在被调函数运行一结束就被释放掉了,那么它是怎么返回给主调函数的呢?

事实上在执行 return 语句时系统是在内部自动创建了一个临时变量,然后将 return 要返回的那个值赋给这个临时变量。所以当被调函数运行结束后 return 后面的返回值真的就被释放掉了,最后是通过这个临时变量将值返回给主调函数的。而且定义函数时指定的返回值类型实际上指定的就是这个临时变量的类型。

文章标题:为什么不把要返回元素直接当成函数的返回值返回呢,发布者:Z, ZLW,转载请注明出处:https://worktile.com/kb/p/49368

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
Z, ZLWZ, ZLW站长
上一篇 2023年4月15日
下一篇 2023年4月15日

相关推荐

  • 工作日程管理软件有什么

    工作日程管理软件有:1、PingCode;2、Worktile;3、Asana;4、禅道;5、Redmine。PingCode是国内国内的一款知名研发项目管理软件,曾在2021年,被知名媒体36氪评为:2021年国内研发项目管理榜单名列前茅的研发项目管理系统。 一、PingCode 这是国内国内的一…

    2023年4月21日
    14100
  • 什么是SecurePatch

    SecurePatch是一种安全软件补丁,用于修复已知的漏洞和弱点,提高计算机系统的安全性。SecurePatch是由全球领先的安全软件公司开发的,旨在保护用户的计算设备和数据免受黑客攻击和恶意软件的侵害。 SecurePatch是一种安全软件补丁,用于修复已知的漏洞和弱点,提高计算机系统的安全性。…

    2023年5月28日
    6500
  • 360考核和kpi考核有什么区别

    360考核和kpi考核的区别:1、定义不同;2、过程不同;3、目的不同;4、结果不同。其中,定义不同指360°考核帮助一个组织中的成员从与自己有工作关系的主体中获取本人绩效信息反馈的过程,kpi考核是用于衡量工作人员工作绩效表现的量化指标。 1、定义不同 360考核:360度考核法是常见的绩效考核方…

    2022年11月16日
    1.3K00
  • 计算机中应用最普遍的字符编码是

    本文将对计算机中最常用的字符编码方式进行详述,主要包括:1、ASCII编码;2、Unicode编码;3、UTF-8编码;4、编码方式的选用原则。希望通过本文的阅读,能够帮助你更深入地理解字符编码在计算机领域中的应用。 1、ASCII编码 ASCII编码是较早的字符编码标准,主要用于表示英文字符。它使…

    2023年8月4日
    17500
  • 设备管理的概念是什么

    设备管理是:是以设备为研究对象,追求设备综合效率,应用一系列理论、方法,通过一系列技术、经济、组织措施,对设备的物质运动和价值运动进行全过程(从规划、设计、选型、购置、安装、验收、使用、保养、维修、改造、更新直至报废)的科学型管理。 一、设备管理的概念 设备管理 是项目管理(Engineering …

    2023年5月6日
    34300
  • Kyligence韩卿:立志做出中国自己的全球拔尖数据平台

    文| babayage 编辑 |馨 月 2016年初,Kyligence成立。这次创业,不只是一次追求商业成功的尝试,更承载着韩卿本人怀揣多年的信念:在国际基础软件领域立足并领导行业。 从中国来,到全球去 韩卿讲述了对自己产生了巨大影响的三段经历 一.韩卿大学毕业后的名列前茅份工作就职于浙大中控。浙…

    2022年3月20日
    67300
  • 管理上的缺陷主要有哪几类

    管理上的缺陷主要有:1、决策错误;2、领导方式问题;3、缺乏有效沟通;4、资源分配不合理;5、人力资源管理不当;6、未对风险进行有效管理。其中,决策错误主要是因为对情况的判断不准确,或是未能全面考虑各种因素,导致决策的效果不理想。 1、决策错误 成功的管理:在做出决策时,会全面分析和考虑各种可能的影…

    2023年7月18日
    67700
  • Linux并发和竞态问题究竟是什么

    摘要:并发(Concurrency)和竞态问题(Race Condition)在Linux操作系统中是系统设计和性能优化领域内经常讨论的两个核心概念。在服务器、应用程序、多线程环境中,并发是指系统能够同时处理多个任务或进程的能力;而竞态问题通常是由并发执行引起的,涉及到多个进程或线程在没有适当的同步…

    2023年11月16日
    1100
  • 社交型知识库有哪些平台

    社交型知识库是结合社交网络和知识管理功能的在线平台,它们有效促成了信息的共享与个人间互动。目前,1、Quora、2、Stack Exchange、3、Reddit、4、Zhihu以及5、LinkedIn Learning是该领域的一些主要平台。这些平台促进了专业知识的交流,支持用户通过提问、回答、讨…

    2023年11月15日
    1400
  • 现阶段的编程语言都有什么缺陷

    Python的劣势是速度较慢,且有一些特定情况下才会出现(无法重现)的 bug;C/C++C/C++的劣势是学习难度大,且拥有大量极为复杂的功能交互方式,容易造成资源浪费;Java的劣势是占用大量内存,并且启动时间较长;C#的劣势是跨平台能力太差,且在国内就业环境不太好。 Python 优势:简单易…

    2023年2月22日
    9300

发表回复

登录后才能评论
站长微信
站长微信
电话联系

400-800-1024

工作日9:30-21:00在线

分享本页
返回顶部