C++菜鸟学习笔记系列(19)——返回类型和return语句

简介: C++菜鸟学习笔记系列(19)——返回类型和return语句

C++菜鸟学习笔记系列(19)

本期主题:返回类型和return语句

return语句用于终止当前正在执行的函数并将控制权返回调用该函数的地方,在C++语言中return语句有两种形式:

return;
return 表达式;

(1)无返回值函数

第一种格式为无返回值的return语句,只能用在返回值类型为void的函数中。其实在返回值类型为void的函数中并不要求必须有return语句,因为在这类函数的最后一句中会隐式地执行return语句。


但是仍存在一种情况就是我们在void函数中间的位置提前退出,可以使用return语句。return的这种用法就有点类似于break语句在循环语句中终止循环的作用了。下面我们来看一个简单的例子:

/*
author: wxc_1998
date: 2018/11/1
*/
#include <iostream>
using namespace std;
void swap (int &val1, int &val2 );
void main()
{
  int i1 = 0, i2 = 0;
  cout << "please input a integer:" << endl;
  cin >> i1;
  cout << "please input a integer:" << endl;
  cin >> i2;
  swap (i1, i2);
  cout << "i1 = " << i1 << endl;
  cout << "i2 = " << i2 << endl;
  cout << "please press any key to continue!" << endl;
  cin.clear();
  cin.sync();
  cin.get();
}
void swap (int &val1, int &val2 )
{
  int val3 = 0;
  if (val1 == val2)
    return;
  else
  {
    val3 = val1;
    val1 = val2;
    val2 = val3;
  }
}

对于第二种形式我们是不能够用到void类型函数中的,如果我们强行使用void类型函数返回其他类型的值会出现编译错误,当然,如果第二种形式返回的类型也是一个void函数则会正常进行。

(2)有返回值函数

return语句的第二种形式提供了函数的结果,只要函数的返回值类型不是void,则必须使用return语句返回函数中的一个值,且其返回值的类型必须和函数声明时的类型相同,或者可以隐式转换成函数的返回类型。(通过前述我们可以看出尽管C++语言无法确保函数返回结果的正确性,但是可以保证返回值类型的正确性)

bool str_subrange( const string &str1, const string &str2)
{
  if (str1.size() == str2.size())
    return 1;
  auto size = (str1.size() < str2.size()) ? str1.size() : str2.size();
  for (decltype(size) i = 0; i != size; ++ i)
  {
    if (str1[i] == str2[i])
      return;
  }
}

对于上述代码第一个return 1;可以转换成bool类型所以没有错误,第二个return;语句没有返回值,所以编译器将会报告这一错误。


其实上述代码还有一个隐含的错误就是在含有return语句的for循环之后也应该有一条return语句,如果没有的话这个程序就是错误的,但是编译器是不能发现这些错误的。(错误原因:如果在for循环中所有次迭代都没有执行循环体那么这个函数就没有return语句了,所以会发生没有返回值后的错误。)

值的返回方式

返回一个值的方式和初始化一个变量或形参的方式完全相同,返回的值用于初始化调用点的一个临时量,这个临时量就是函数调用的结果。

注意:我们在返回值时不要返回局部对象的引用或指针,因为函数完成后,局部对象所占用的存储空间随之被释放掉。因此。这时函数终止之后局部变量的引用和指针将不再指向有效的区域。

(3)递归

如果一个函数调用了它本身,则不管这种调用时直接的还是间接的,都称该函数为递归函数。我们可以通过递归函数实现类似于循环的功能。

我们在之前发布的博客中写过一个关于求阶乘的小程序,在那个函数中我们是通过迭代语句来实现的,下面我们再举一个例子实现同样的功能,但是通过递归函数来实现。

/*
author: wxc_1998
date: 2018/11/3
*/
#include <iostream>
using namespace std;
int factorial(int n);
int main()
{
  begin:
  int val = 0, fac = 0;
  cout << "please in put a integer:" << endl;
  cin >> val;
  try
  {
    if (val > 0)
    fac = factorial(val);
    else
      throw runtime_error ("the value of input is must bigger than 0!");
  }
  catch(runtime_error err)
  {
    cout << err.what() << endl;
    goto begin;
  }
  cout << val << "! = " << fac << endl;
  cout << "press any key to continue!" << endl;
  cin.clear();
  cin.sync();
  cin.get();
}
int factorial (int val)
{
  if (val > 1)
    return factorial(val-1) * val;
  return 1;
}

关于上述代码中的try语句块和异常处理我就不做过多解释了,大家直接点击带有超链接的文字可以找到我之前写的博客。


对于递归函数部分,我们不断的调用factorial函数本身,只是形参n的值每次调用都减小1,直到等于1为止,factorial函数返回1,在本递归函数中其执行过程是先到最后一个调用之后才计算值的,就是类似于:

factorial(1) = 1;
factorial(2) = factorial(1) * 2;
factorial(3) = factorial(2) * 3;
factorial(4) = factorial(3) * 4;
... 

的过程。

好了,这次我们就先写到这里了,下次再见!

注:虽然这篇博客的内容十分简单,但是大家若有转载还请标明出处!

目录
相关文章
|
5月前
|
C++
c++学习笔记07 结构体
C++结构体的详细学习笔记07,涵盖了结构体的定义、使用、数组、指针、嵌套、与函数的交互以及在结构体中使用const的示例和解释。
48 0
|
3月前
|
存储 编译器 程序员
C++类型参数化
【10月更文挑战第1天】在 C++ 中,模板是实现类型参数化的主要工具,用于编写能处理多种数据类型的代码。模板分为函数模板和类模板。函数模板以 `template` 关键字定义,允许使用任意类型参数 `T`,并在调用时自动推导具体类型。类模板则定义泛型类,如动态数组,可在实例化时指定具体类型。模板还支持特化,为特定类型提供定制实现。模板在编译时实例化,需放置在头文件中以确保编译器可见。
42 11
|
4月前
|
安全 C语言 C++
C++学习笔记
C++学习笔记
|
5月前
|
C++
【学习笔记】【C/C++】 c++字面值常量
【学习笔记】【C/C++】 c++字面值常量
53 1
|
4月前
|
安全 程序员 C语言
C++(四)类型强转
本文详细介绍了C++中的四种类型强制转换:`static_cast`、`reinterpret_cast`、`const_cast`和`dynamic_cast`。每种转换都有其特定用途和适用场景,如`static_cast`用于相关类型间的显式转换,`reinterpret_cast`用于低层内存布局操作,`const_cast`用于添加或移除`const`限定符,而`dynamic_cast`则用于运行时的类型检查和转换。通过具体示例展示了如何正确使用这四种转换操作符,帮助开发者更好地理解和掌握C++中的类型转换机制。
|
5月前
|
C++
使用 QML 类型系统注册 C++ 类型
使用 QML 类型系统注册 C++ 类型
130 0
|
5月前
|
编译器 C++
【C/C++学习笔记】C++声明与定义以及头文件与源文件的用途
【C/C++学习笔记】C++声明与定义以及头文件与源文件的用途
73 0
|
5月前
|
存储 C++
【C/C++学习笔记】string 类型的输入操作符和 getline 函数分别如何处理空白字符
【C/C++学习笔记】string 类型的输入操作符和 getline 函数分别如何处理空白字符
61 0
|
5月前
|
C++
c++学习笔记09 引用
C++引用的详细学习笔记,解释了引用的概念、语法、使用注意事项以及引用与变量的关系。
46 0
|
5月前
|
存储 程序员 编译器
c++学习笔记08 内存分区、new和delete的用法
C++内存管理的学习笔记08,介绍了内存分区的概念,包括代码区、全局区、堆区和栈区,以及如何在堆区使用`new`和`delete`进行内存分配和释放。
59 0