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

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

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

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

例如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日

相关推荐

  • oa是做什么的

    OA系统是组织内为提高工作效率、优化流程管理、增强沟通协作而设计的一套办公自动化软件。1、它覆盖了日常企业行政管理活动2、信息发布和资源共享3、电子文档管理和流转4、项目与任务管理等多项功能。具体而言,这类系统通常通过集成电子邮件、日程安排、任务分派和追踪、以及文件共享等模块,支持团队内部的协同工作…

    2024年1月11日
    19000
  • 房屋建设项目如何管理好

    房屋建设项目的有效管理关键在于明确项目目标、高效的团队协作、严格的成本控制、细致的进度监控,以及有效的质量保障。这些要素相互支持,共同构成房屋建设项目管理的核心框架。明确项目目标不仅涉及建设目标的设定,还包括对项目范围和期望成果的明确。这是项目成功的基石,因为只有清楚地知道要达成的目标,才能够针对性…

    2024年4月10日
    6200
  • 什么是工业APP

    工业APP是为了解决特定问题、满足特定需要而将工业领域的各种流程、方法等工业技术要素,通过数据建模与分析、结构化整理、系统性抽象提炼,并基于统一的标准,将这些工业技术要素封装固化后所形成的一种可高效重用和广泛传播的工业应用程序。 一、什么是工业APP 工业APP是为了解决特定问题、满足特定需要而将工…

    2023年5月10日
    57200
  • linux shell 是什么意思

    Linux shell是Linux系统中的一个命令行界面,用户可以通过它来与操作系统进行交互。shell接收并解析用户输入的命令,然后将其传递给操作系统执行。shell同时也是一个编程环境,可以用来编写shell脚本,自动执行一系列的命令。 Linux Shell是一个命令行界面,它为用户提供了与操…

    2023年6月13日
    76200
  • 什么是自动化运维

    自动化运维就是把周期性、重复性、规律性的工作都交给工具去做,具体来说有应用系统维护自动化,巡检自动化和故障处理自动化这三个方面。自动化运维依赖于具体的智能管理平台,最终达到提升运维效率的目的。 一、什么是自动化运维 自动化运维就是把周期性、重复性、规律性的工作都交给工具去做,具体来说有应用系统维护自…

    2023年7月28日
    1.0K00
  • 少儿编程必须学会什么

    少儿编程必须学会的三个要点包括1、基础编程概念、2、逻辑思维能力、3、项目实践经验。尤其是逻辑思维能力,它是编程学习的核心。通过编程解决实际问题的过程,孩子能够学会如何分析问题、拆解问题并寻找解决方法。这种能力的培养对孩子今后无论是学习其他科学技术,还是面对生活中的各种挑战都具有重要作用。 一、基础…

    2024年4月26日
    1300
  • 扩建项目如何进行隔离管理

    在进行扩建项目时,进行有效的隔离管理是至关重要的。这不仅涉及到工程的顺利进行,还关乎到施工人员的安全以及对环境的保护。有效的隔离管理措施包括物理隔离、工期管理隔离、噪音与尘埃控制、安全与健康管理。其中,物理隔离是最直观、最基础的一种方式,它涉及到使用围挡、标识牌等物理屏障来明确区分施工区域与非施工区…

    2024年4月10日
    6300
  • 知识库管理需要哪些最佳实践

    知识库管理是保证信息有效组织、检索和共享的关键。最佳实践的核心观点包括:1、定义清晰的目标和范围,确保知识库集中于最有价值的信息;2、保持知识的实时更新,以确保知识的准确性和相关性;3、实施有效的分类和标签系统,简化搜索过程;4、鼓励知识共享文化,激发团队成员贡献和使用知识库;5、利用技术,借助专业…

    2023年11月15日
    34300
  • 汇编程序需要学什么语言

    汇编程序员需要学习汇编语言,这是一种低级编程语言,与机器代码一一对应,直接控制硬件。汇编语言对于理解计算机的基础工作原理至关重要。对于汇编语言的学习,最关键的是理解CPU的处理机制、寄存器的用途以及内存管理方式。CPU是计算机的大脑,汇编语言允许程序员编写指令来直接控制CPU的操作。每种CPU可能拥…

    2024年4月27日
    900
  • 如何管理项目生产要素分析

    项目生产要素分析是对于项目成功至关重要的一个步骤,它涉及对项目所需的人力、物力、财力和信息力四大生产要素的全面理解和有效管理。其中,人力资源的管理尤为关键,因为人员的能力和态度直接影响项目的执行效率和最终成果。有效的人力资源管理应包括合理的人员配置、技能培训、激励机制和团队建设等方面,确保项目团队能…

    2024年4月10日
    5300

发表回复

登录后才能评论
注册PingCode 在线客服
站长微信
站长微信
电话联系

400-800-1024

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

分享本页
返回顶部