C++入门:函数

文章介绍了C++中的函数概念,包括函数的作用、声明和定义,以及C++标准库提供的内置函数。重点讲解了Lambda函数的语法,如捕获列表、参数列表、返回类型和函数体,并通过实例展示了Lambda在迭代和条件判断中的应用。还特别提到了[this]和[*this]在Lambda表达式中的含义及使用注意事项。
摘要由CSDN通过智能技术生成

函数是一组一起执行一个任务的语句。每个 C++ 程序都至少有一个函数,即主函数 main() ,所有简单的程序都可以定义其他额外的函数。

您可以把代码划分到不同的函数中。如何划分代码到不同的函数中是由您来决定的,但在逻辑上,划分通常是根据每个函数执行一个特定的任务来进行的。

函数声明告诉编译器函数的名称、返回类型和参数。函数定义提供了函数的实际主体。

C++ 标准库提供了大量的程序可以调用的内置函数。例如,函数 strcat() 用来连接两个字符串,函数 memcpy() 用来复制内存到另一个位置。

函数还有很多叫法,比如方法、子例程或程序,等等。

Lambda 函数与表达式

Lambda函数的语法定义如下:

[capture](parameters) mutable ->return-type{statement}

其中:

[capture]:捕捉列表。捕捉列表总是出现在 lambda 表达式的开始处。事实上,[] 是 lambda 引出符。编译器根据该引出符判断接下来的代码是否是 lambda 函数。捕捉列表能够捕捉上下文中的变量供 lambda 函数使用。

(parameters):参数列表。与普通函数的参数列表一致。如果不需要参数传递,则可以连同括号 () 一起省略。

mutable:mutable 修饰符。默认情况下,lambda 函数总是一个 const 函数,mutable 可以取消其常量性。在使用该修饰符时,参数列表不可省略(即使参数为空)。

->return_type:返回类型。用追踪返回类型形式声明函数的返回类型。出于方便,不需要返回值的时候也可以连同符号 -> 一起省略。此外,在返回类型明确的情况下,也可以省略该部分,让编译器对返回类型进行推导。

{statement}:函数体。内容与普通函数一样,不过除了可以使用参数之外,还可以使用所有捕获的变量。

在 lambda 函数的定义式中,参数列表和返回类型都是可选部分,而捕捉列表和函数体都可能为空,C++ 中最简单的 lambda 函数只需要声明为:

[]{};

两个实际应用到lambda表达式的代码。

std::vector<int> v = { 1, 2, 3, 4, 5, 6 };
int even_count = 0;
for_each(v.begin(), v.end(), [&even_count](int val){
    if(!(val & 1)){
        ++ even_count;
    }
});
std::cout << "The number of even is " << even_count << std::endl;
int count = std::count_if( coll.begin(), coll.end(), [](int x){ return x > 10; });  
  
int count = std::count_if( coll.begin(), coll.end(), [](int x){ return x < 10; });  
  
int count = std::count_if( coll.begin(), coll.end(), [](int x){ return x > 5 && x<10; }); 

[]:默认不捕获任何变量;

[=]:默认以值捕获所有变量;

[&]:默认以引用捕获所有变量;

[x]:仅以值捕获x,其它变量不捕获;

[&x]:仅以引用捕获x,其它变量不捕获;

[=, &x]:默认以值捕获所有变量,但是x是例外,通过引用捕获;

[&, x]:默认以引用捕获所有变量,但是x是例外,通过值捕获;

[this]:通过引用捕获当前对象(其实是复制指针);

[*this]:通过传值方式捕获当前对象;

特殊说明

[this]: 通过引用捕获当前对象(对象本身)

[*this]: 通过传值捕获当前对象(对象拷贝,且只是一个地址值,可以说没有意义)

举例说明:

#include <iostream>
using namepsace std;

//定义一个类
class MM 
{
public:
  void print() {}
};

int main()
{
  MM mm;

  //打印对象地址作对比
  cout << "对象本身地址:" << &mm << endl;
  
  [&mm](){cout << "[&mm]: " << &mm << endl;}();    //相当于[this]
  [mm](){cout << "[mm]: " << &mm << endl;}();      //相当于[*this]
  [mm](){cout << "[mm]: " << &mm << endl;}();      //相当于[*this]

  return 0;
}

结果:

对象本身地址:012FF984
[&mm]: 012FF984
[mm]: 012FF878
[mm]: 012FF850

尝试将捕获的指针调用成员函数:

[&mm](){cout << this->print();}();    //相当于[this]
//[mm](){cout << this->print();}();    //相当于[*this],无法调用,因为传入的只是一个值

一个新手可能会犯的错误

由于在实际写代码过程中,可能会与到函数的定义和声明不在同一文件,声明出现在头文件中的情况

这时,对带默认值的函数在声明和定义时,需要注意,默认值出现在声明的代码中,定义中不能再对参数赋与默认值,否则会报错。

<Plus.h> //声明在头文件中
int Plus(int a, int b = 10)
<Plus.cpp>//定义在cpp文件中
int Plus(int a, int b)//不能再对b赋值了
{
    return a + b;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

灰度少爷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值