• Index

返回值和函数参数

Reads: 31

没有返回值的函数

并不是所有的功能都有运算结果,也就是说,并不是所有的函数都有返回值。返回类型是void的函数不需要返回值,并且可以省略不写return;

例如,我有一个函数,专门用来输出提示信息的。

#include <iostream>

void print_tips(void)
{
    std::cout << "************************************************" << std::endl;
    std::cout << "* 小古银的C++教程                              *" << std::endl;
    std::cout << "* 新手专用的教程                               *" << std::endl;
    std::cout << "* 有了它,你不在烦恼入不了门                   *" << std::endl;
    std::cout << "* 有了它,你的头发将会和我一样加了特效         *" << std::endl;
    std::cout << "* C++圈里面个个都是人才,说话又好听            *" << std::endl;
    std::cout << "* 右边就是对不齐                               *" << std::endl;
    std::cout << "************************************************" << std::endl;
}

int main(void)
{
    print_tips();
    return 0;
}

注意:没有返回值不代表不返回,有不少的情况还是需要写return;的。

返回多个值的函数

现在写一个整数除法的函数,返回商和余数。这样就要返回两个值了。当需要返回两个值时,此时,返回类型就必须是std::tuple

基础示例

#include <iostream>
#include <tuple>

// 除法运算
// 参数: a 被除数
// 参数: b 除数, 该参数不能传入0
// 返回值: 商和余数
std::tuple<int, int> dividedby(int a, int b)
{
    return { a / b, a % b };
}

int main(void)
{
    auto [quotient, remainder] = dividedby(15, 4);
    std::cout << "商:" << quotient << std::endl;
    std::cout << "余数:" << remainder << std::endl;
    return 0;
}

输出结果:

商:3
余数:3

基础讲解

注意:调用别人的函数时,一定要看函数的说明文档,像上面定义的函数是有前提条件的:除数不能传0

由于intint的运算也是int,所以a / b就是计算结果的整数部分(如:9除以2的结果就是整数4)。而a % b求出余数。然后将它们用{}装起来作为std::tuple的初始值,然后返回std::tuple对象。

用变量保存返回值时则必须使用关键字auto,然后在[]里面写需要被赋值的变量,然后返回的std::tuple对象就会对[]里面的变量逐一初始化。

返回类型推导

当使用关键字auto作为函数的返回类型时,编译器可以根据返回值去确定返回类型,如果使用了return;或者没有return,那么返回类型就是void

注意

  • 如果返回值是用{}括起来的数据组合,那么编译器将推导不出返回类型,因为非常多的类型都可以使用{}
  • 如果用auto作为函数的返回类型,那么只有当函数定义写在调用者前面的时候,编译器才能根据返回值进行推导。而实际工程中,函数定义一般都是对调用者不可见(因为函数定义放在其他源文件中)。因此,实际工程中只有模板能用这个特性。

基础示例

#include <iostream> // std::cout std::endl

auto power(int a, int b)
{
    if (b == 0)
    {
        return static_cast<double>(1);
    }
    double result = a;
    for (int i = 1; i < std::abs(b); ++i)
    {
        result *= a;
    }
    return b < 0 ? (1 / result) : result;
}

int main(void)
{
    std::cout << power(2, 10) << std::endl;
    std::cout << power(10, -1) << std::endl;
    return 0;
}

基础讲解

函数power()用于求ab次方。只有当返回值类型都是一样的时候,编译器才能推导出返回类型。假设上面代码不转换1的类型而直接写return 1;,那么编译时就会报错,因为返回类型不一样。

没有参数

当一个函数没有参数时,那么函数名称后的()内就不需要填任何东西,也可以填一个void代表没有参数。例如:void print();或者void print(void);,它们是等价的。

不过我个人习惯是在()里面写void,所以在我的教程中,无参数的函数都是这样写的。

无名参数

有时候的重载函数需要用参数区分,但是用以区分的参数实际上在函数定义中没有作用。当局部变量没有被使用时,编译器一般会报警告,这个时候,就可以只写参数类型而不写参数名称,这就是无名参数。例如void print(int, int);,函数定义也不需要写参数名称。

默认实参

当函数有一个参数需要用户提供,但是这个参数经常是某个值而且不需要求改,那么就可以用默认实参。

注意

  1. 有默认实参的参数必须在没有默认实参的参数后面。
  2. 默认实参只写在函数声明中,不能写在函数定义中。

基础示例

#include <iostream> // std::cout std::endl
#include <cmath> // std::abs

double power(int a, int b = 2);

int main(void)
{
    std::cout << power(100) << std::endl; // 当不填写第二个参数时, 则默认第二个参数是2
    std::cout << power(2, 10) << std::endl;
    std::cout << power(10, -1) << std::endl;
    return 0;
}

double power(int a, int b)
{
    if (b == 0)
    {
        return static_cast<double>(1);
    }
    double result = a;
    for (int i = 1; i < std::abs(b); ++i)
    {
        result *= a;
    }
    return b < 0 ? (1 / result) : result;
}

输出结果:

10000
1024
0.1

补充知识(了解即可)

  1. 返回多个值的函数从C++17开始加入。

  2. C++11引入返回类型后置。例如:auto get(void) -> int;,将数据类型放到函数后面。C++14开始引入返回类型推导,并且允许省略后置的类型,那么前面的代码就可以简写成:auto get(void);;


Comments

Make a comment

  • Index

WARNING: You are using an old browser that does not support HTML5. Please choose a modern browser (Chrome / Microsoft Edge / Firefox / Sarafi) to get a good experience.