0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

C++基础知识之函数1

jf_78858299 来源:QStack 作者: 月下西楼 2023-04-03 10:34 次阅读

函数是 C++ 中的一个重要概念,它可以让我们将一段代码封装起来,然后在需要的时候调用它。C++ 中的函数有以下几个特点:

  • 函数可以有参数和返回值。
  • 函数可以被其他函数调用。
  • 函数可以被重载,即可以定义多个同名的函数,只要它们的参数列表不同即可。

函数的定义和调用

在 C++ 中,函数的定义和调用都非常简单。以下是一个简单的函数的定义和调用的示例:

#include 

// 定义一个名为 add 的函数,它有两个参数 x 和 y,返回值为 x + y
int add(int x, int y) {
    return x + y;
}

int main() {
    // 调用 add 函数,并将返回值赋值给变量 z
    int z = add(1, 2);
    std::cout << "1 + 2 = " << z << std::endl;
    return 0;
}

在这个示例中,我们定义了一个名为 add 的函数,它有两个参数 x 和 y,返回值为 x + y。然后在 main 函数中,我们调用了 add 函数,并将返回值赋值给变量 z,最后输出了 1 + 2 = 3。

函数的参数和返回值

在 C++ 中,函数可以有参数和返回值。以下是一个带有参数和返回值的函数的示例:

#include 

// 定义一个名为 add 的函数,它有两个参数 x 和 y,返回值为 x + y
int add(int x, int y) {
    return x + y;
}

int main() {
    // 调用 add 函数,并将返回值赋值给变量 z
    int z = add(1, 2);
    std::cout << "1 + 2 = " << z <<
    std::endl;

// 调用 add 函数,并将返回值赋值给变量 z
}

在这个示例中,我们定义了一个名为 add 的函数,它有两个参数 x 和 y,返回值为 x + y。然后在 main 函数中,我们调用了 add 函数两次,并将返回值分别赋值给变量 z,最后输出了 1 + 2 = 3 和 3 + 4 = 7。

函数的重载

在 C++ 中,函数可以被重载,即可以定义多个同名的函数,只要它们的参数列表不同即可。以下是一个函数重载的示例:

#include 

// 定义一个名为 add 的函数,它有两个参数 x 和 y,返回值为 x + y
int add(int x, int y) {
    return x + y;
}

// 定义一个名为 add 的函数,它有三个参数 x、y 和 z,返回值为 x + y + z
int add(int x, int y, int z) {
    return x + y + z;
}

int main() {
    // 调用 add 函数,并将返回值赋值给变量 z
    int z = add(1, 2);
    std::cout << "1 + 2 = " << z << std::endl;

    // 调用 add 函数,并将返回值赋值给变量 z
    z = add(1, 2, 3);
    std::cout << "1 + 2 + 3 = " << z << std::endl;

    return 0;
}

在这个示例中,我们定义了两个同名的函数 add,它们的参数列表不同。这就是函数重载的一个例子。函数重载可以让我们定义多个同名的函数,只要它们的参数列表不同即可。这样可以让我们更方便地使用函数,而不需要为每个函数取不同的名字。

参数传递

在 C++ 中,函数的参数传递有两种方式:值传递和引用传递。

值传递

值传递是指将参数的值复制一份,然后将这份复制传递给函数。在函数内部,对参数的修改不会影响到原始的参数。以下是一个值传递的示例:

#include 

// 定义一个名为 add 的函数,它有两个参数 x 和 y,返回值为 x + y
int add(int x, int y) {
    x = x + 1;
    y = y + 1;
    return x + y;
}

int main() {
    int a = 1;
    int b = 2;
    int c = add(a, b);
    std::cout << "a = " << a << std::endl; // 输出 a = 1
    std::cout << "b = " << b << std::endl; // 输出 b = 2
    std::cout << "c = " << c << std::endl; // 输出 c = 5
    return 0;
}

在这个示例中,我们定义了一个名为 add 的函数,它有两个参数 x 和 y,返回值为 x + y。然后在 main 函数中,我们定义了三个变量 a、b 和 c,并将 a 和 b 的值分别赋为 1 和 2。然后我们调用了 add 函数,并将 a 和 b 作为参数传递给它。在 add 函数内部,我们对 x 和 y 的值进行了修改,但是这些修改不会影响到 a 和 b 的值。

引用传递

引用传递是指将参数的引用传递给函数。在函数内部,对参数的修改会影响到原始的参数。以下是一个引用传递的示例:

#include 

// 定义一个名为 add 的函数,它有两个参数 x 和 y,返回值为 x + y
int add(int& x, int& y) {
    x = x + 1;
    y = y + 1;
    return x + y;
}

int main() {
    int a = 1;
    int b = 2;
    int c = add(a, b);
    std::cout << "a = " << a << std::endl; // 输出 a = 2
    std::cout << "b = " << b << std::endl; // 输出 b = 3
    std::cout << "c = " << c << std::endl; // 输出 c = 6
    return 0;
}

在这个示例中,我们定义了一个名为 add 的函数,它有两个参数 x 和 y,返回值为 x + y。然后在 main 函数中,我们定义了三个变量 a、b 和 c,并将 a 和 b 的值分别赋为 1 和 2。然后我们调用了 add 函数,并将 a 和 b 的引用作为参数传递给它。在 add 函数内部,我们对 x 和 y 的值进行了修改,这些修改会影响到 a 和 b 的值。

选择哪种方式

在选择参数传递方式时,需要考虑以下几个因素:

  • 如果参数是一个较小的基本类型(如 int、double 等),可以使用值传递。
  • 如果参数是一个较大的结构体或类,可以使用引用传递,这样可以避免复制大量的数据。
  • 如果需要在函数内部修改参数的值,并且希望这些修改能够影响到原始的参数,可以使用引用传递。

函数匹配

在C++中,函数匹配是指编译器在调用函数时,根据实参的类型和数量,从函数的重载集合中选择一个最佳的匹配函数的过程。函数匹配是C++中的一个重要概念,它决定了程序调用哪个函数,因此对于C++程序员来说,了解函数匹配的规则和原理是非常重要的。C++中的函数匹配规则比较复杂,主要包括以下几个方面:

  • 实参类型的精确匹配
  • 实参类型的标准类型转换
  • 实参类型的用户自定义类型转换
  • 函数模板的匹配
实参类型的精确匹配

如果函数的形参类型和实参类型完全一致,那么这个函数就是一个精确匹配。例如,下面的代码中,foo函数的形参类型和实参类型完全一致,因此它是一个精确匹配:

void foo(int x, double y) {
    // ...
}

int main() {
    int a = 1;
    double b = 2.0;
    foo(a, b); // 精确匹配
    return 0;
}
实参类型的标准类型转换

如果函数的形参类型和实参类型不一致,但是可以通过标准类型转换(如整型提升、算术类型转换、指针类型转换等)将实参类型转换为形参类型,那么这个函数就是一个标准类型转换匹配。 实例如,下面的代码中,foo函数的形参类型是int, 而实参类型是short,但是可以通过整型提升将short类型转换为int类型,因此foo函数是一个标准类型转换匹配:

void foo(int x, double y) {
    // ...
}

int main() {
    short a = 1;
    double b = 2.0;
    foo(a, b); // 标准类型转换匹配
    return 0;
}
实参类型的用户自定义类型转换

如果函数的形参类型和实参类型不一致,且不能通过标准类型转换将实参类型转换为形参类型,但是可以通过用户自定义类型转换将实参类型转换为形参类型,那么这个函数就是一个用户自定义类型转换匹配。例如,下面的代码中,foo函数的形参类型是double,而实参类型是int,但是可以通过用户自定义类型转换将int类型转换为double类型,因此foo函数是一个用户自定义类型转换匹配:

class A {
public:
    operator double() const {
        return 0.0;
    }
};

void foo(double x) {
    // ...
}

int main() {
    A a;
    foo(a); // 用户自定义类型转换匹配
    return 0;
}

在上面的例子中,foo函数的形参类型是double,而实参类型是A,但是可以通过用户自定义类型转换将A类型转换为double类型。具体来说,A类定义了一个类型转换函数operator double(),该函数将A类型转换为double类型。当我们调用foo函数时,编译器会自动调用A类的类型转换函数,将A类型转换为double类型,然后将转换后的double类型作为实参传递给foo函数。

函数模版匹配

在C++中,函数模板匹配是通过模板参数推导来实现的。当我们调用一个函数模板时,编译器会根据实参的类型推导出模板参数的类型,然后根据模板参数的类型来匹配函数模板。具体来说,编译器会根据实参的类型推导出模板参数的类型,然后将模板参数的类型与函数模板的形参类型进行匹配。如果匹配成功,则使用该函数模板来生成对应的函数实例;否则,编译器会报错。

❝需要注意的是,函数模板匹配是一种非常灵活的机制,它可以根据实参的类型来推导出模板参数的类型,从而实现类型自动推导。但是,由于函数模板匹配是在编译时进行的,因此需要满足一定的语法规则和限制。例如,函数模板的形参类型不能是引用类型,否则会导致模板参数推导失败;函数模板的形参类型不能是void类型,否则会导致编译错误等。 下面是一个函数模板匹配的例子:

template <typename T>
void foo(T x) {
    std::cout << x << std::endl;
}

int main() {
    foo(1); // T = int
    foo(1.0); // T = double
    foo("hello"); // T = const char*
    return 0;
}

在上面的代码中,我们定义了一个函数模板foo,它有一个模板参数T和一个形参x。当我们调用foo函数时,编译器会根据实参的类型推导出模板参数的类型,然后将模板参数的类型与函数模板的形参类型进行匹配。例如,当我们调用foo(1)时,编译器会推导出T为int,从而使用foo来生成对应的函数实例。当我们调用foo(1.0)时,编译器会推导出T为double,从而使用foo来生成对应的函数实例。当我们调用foo("hello")时,编译器会推导出T为const char,从而使用foo来生成对应的函数实例。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 封装
    +关注

    关注

    126

    文章

    7767

    浏览量

    142699
  • 函数
    +关注

    关注

    3

    文章

    4303

    浏览量

    62411
  • C++
    C++
    +关注

    关注

    22

    文章

    2104

    浏览量

    73480
  • 代码
    +关注

    关注

    30

    文章

    4741

    浏览量

    68325
收藏 人收藏

    评论

    相关推荐

    学51单片机C51基础知识

    带您从零学51单片机C51基础知识 C51基础知识1 单片机的汇编(ASM)和
    发表于 02-10 14:30 109次下载

    C++C/C++程序设计教程_C/C++概述

    C++基础知识,简要介绍了C++的一些简单知识,概念,函数
    发表于 12-25 10:15 0次下载

    C++语言基础知识讲解

    C++语言基础知识讲解,喜欢的朋友可以下载来学习。
    发表于 01-14 15:30 21次下载

    Visual C++教程之C++基础知识介绍

    本文档的主要内容详细介绍的是Visual C++教程之C++基础知识介绍主要内容包括了:1 类和对象,2 类的成员及特性,3 继承和派生类
    发表于 02-15 15:59 9次下载
    Visual <b class='flag-5'>C++</b>教程之<b class='flag-5'>C++</b>的<b class='flag-5'>基础知识</b>介绍

    C++程序设计教程之基础知识资料概述

    本文档详细介绍的是C++程序设计教程之基础知识资料概述主要内容包括了:1.程序设计语言 ,2.C++前史 ,3.C++,4.
    发表于 02-28 11:11 13次下载
    <b class='flag-5'>C++</b>程序设计教程之<b class='flag-5'>基础知识</b>资料概述

    C++程序设计的基础知识初步了解C++的资料免费下载

    本文档的主要内容详细介绍的是C++程序设计的基础知识初步了解C++的资料免费下载包括了:1 认识C++,2
    发表于 06-10 08:00 25次下载
    <b class='flag-5'>C++</b>程序设计的<b class='flag-5'>基础知识</b>初步了解<b class='flag-5'>C++</b>的资料免费下载

    C++函数模板的概念及意义

    一、函数模板的引出:1c++中有几种交换变量的方法:(1)定义宏代码块(2)定义函数代码版本一:#include <iostream>#i
    的头像 发表于 12-24 15:58 833次阅读

    C++重载函数学习总结

    函数重载是c++c的一个重要升级;函数重载通过参数列表区分不同的同名函数;extern关键字能够实现c
    的头像 发表于 12-24 17:10 776次阅读

    C++基础语法inline 内联函数

    上节我们分析了C++基础语法的const,static以及 this 指针,那么这节内容我们来看一下 inline 内联函数吧! inline 内联函数 特征 相当于把内联函数里面的内
    的头像 发表于 09-09 09:38 2115次阅读

    C++核心编程基础知识大全免费下载

    C++核心编程基础知识大全免费下载
    发表于 12-03 18:06 2次下载

    C/C++基础知识汇总

    这是一篇五万字的C/C++知识点总结,包括答案。
    的头像 发表于 06-12 15:10 2347次阅读

    C++基础知识

    C++基础知识
    的头像 发表于 01-12 11:00 1354次阅读
    <b class='flag-5'>C++</b><b class='flag-5'>基础知识</b>

    深度解析C++中的虚函数

    函数作为C++的重要特性,让人又爱又怕,爱它功能强大,但又怕驾驭不好,让它反咬一口,今天我们用CPU的角度,撕掉语法的伪装,重新认识一下虚函数。 虚函数
    的头像 发表于 02-15 11:14 808次阅读
    深度解析<b class='flag-5'>C++</b>中的虚<b class='flag-5'>函数</b>

    C++基础知识函数2

    C++中,我们可以使用inline关键字来定义内联函数。内联函数是一种特殊的函数,它在编译时会被直接嵌入到调用它的代码中,从而避免了函数
    的头像 发表于 04-03 10:34 508次阅读

    C++语言基础知识

    电子发烧友网站提供《C++语言基础知识.pdf》资料免费下载
    发表于 07-19 10:58 7次下载