C++重要语法

命名空间

std 是C++的标准命名空间,它是一个定义在 C++ 标准库中的所有类、函数和变量的命名空间。使用方法如下:

1
using namespace std;
1
std::cout << "Hello" << std::endl;

自定义命名空间:

1
2
3
4
5
6
7
namespace cir {
constexpr double PI = 3.145926;
/*获取周长*/
double get_L(double R);
/*获取面积*/
double get_S(double R);
}

其中在 C++ 中,如果你想在命名空间内定义一个常量(如 PI),通常需要使用 const 关键字或者将其定义为 constexpr(C++11 及以上版本)。直接使用 double PI = 3.14; 在命名空间中是不合法的,因为命名空间不支持直接初始化变量。你需要使用 constconstexpr

接下载需要具体化函数内容有两种写法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include "cir.h"
/*写法1*/
double cir::get_L(double R)
{
return R*2*cir::PI;
}
double cir::get_S(double R)
{
return R*R*cir::PI;
}
/*写法2*/
namespace cir {
double get_L(double R)
{
return R*2*cir::PI;
}
double get_S(double R)
{
return R*R*cir::PI;
}
}

std包含的内容

std命名空间包含了许多类、函数和对象,例如:

  • 输入输出库(如std::cout , std::cin , std::endl

  • 容器类(如std::vector , std::map , std::set

  • 字符串类(std::string

  • 异常类(std::exception和相关子类)

  • 算法(如std::sort , std::find

  • 实用工具(如std::pair , std::tuple

  • 其他许多功能

使用建议

对于小型代码或示例代码,使用using namespace std; 通常是安全的。对于大型项目或库,建议显式地使用std:: 前缀,以避免潜在的名称冲突,并提高代码的可读性和可维护性。std命名空间是 C++ 编程的基础部分,理解和正确使用它对于编写健壮和高效的 C++ 代码至关重要。

输入输出

C++ 中的输入和输出(I/O)主要是通过标准库中的输入输出流来实现的。最常用的是iostream库,它

提供了用于输入和输出的基本流类,包括cincoutcerrclog

基本使用输出流如下:

1
std::cout << "Hello" << "woeld" << i << std::endl;

输入(箭头指向数据的方向):

1
std::cin >> i;

标准错误流 (cerr) 和标准日志流 ( clog)

cerr用于输出错误消息。与cout不同,cerr不是缓冲的,这意味着它会立即输出。

clog类似于cerr,但它是缓冲的。它通常用于记录错误和日志信息。

变量类型

C++中可以直接使用bool类型的数据,包含true,false值。

内联函数

内联函数(Inline Function)是C++中一种特殊的函数,其定义直接在每个调用点展开。这意味着编译器会将函数调用替换为函数本身的代码,这样可以减少函数调用的开销,尤其是在小型函数中。主要作用为提升代码的可读性。关键字 inline 必须与函数定义体放在一起才能使函数成为内联。在函数声明处添加 inline 关键字虽然没有错,但这种做法是无效的,编译器会忽略函数声明处的 inline 关键字。

1
2
3
inline int add(int i, int j){
return i+j;
}

Lambda匿名函数

Lambda 表达式是 C++11 引入的一种匿名函数的方式,它允许你在需要函数的地方内联地定义函数,而无需单独命名函数。相较于普通非匿名函数,匿名函数无需进行另外的声明和定义,仅当调用该匿名时,函数体才会创建,且调用完毕后会立即释放资源。因此匿名函数会更加节省空间,常用于像std::sort这样可以重写排序方式的函数。Lambda表达式基本语法如下:

1
2
3
4
5
6
//  捕获列表         参数          返回值类型
[capture clause](parameters) -> return_type{
//函数体
//可以使用捕获列表中的参数
return expression;//可选返回语句
}

Lambda 表达式由以下部分组成:

  • 捕获列表(Capture clause:用于捕获外部变量,在 Lambda 表达式中可以访问这些变量。捕获列表可以为空,也可以包含变量列表[var1, var2, ...]

  • 参数列表(Parameters):与普通函数的参数列表类似,可以为空或包含参数列表(param1,param2, ...)

  • 返回类型(Return type):Lambda 表达式可以自动推断返回类型auto,也可以显式指定返回类型 -> return_type 。如果函数体只有一条返回语句,可以省略返回类型。

  • 函数体(Body):Lambda 表达式的函数体,包含需要执行的代码。

匿名函数的使用例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//例子1:
auto testReturn = [](int a1, int a2) {return a1>a2 };
bool flag = testReturn(23, 21);
cout<<flag<<endl;

//例子2:
int as = 100
auto testReturn = [](int a1, int a2) {return a1>a2 };
bool flag = testReturn(as, 21);
cout<<flag<<endl;

//例子3:
int as = 100
auto testReturn = [&](int a1, int a2) {a1 = 10return a1>a2 };
bool flag = testReturn(as, 21);
cout<<flag<<" "<<as<<endl;

重点:区分auto add = [=](int a1, int a2) {return a1+a2 };auto add = [&](int a1, int a2) {return a1+a2 }。其中的区别主要为[=][&],其中[=]表示按数值传入上方所用的变量,其中[&]表示按引用传入上方所用的变量。按数值传入的变量只可以访问不能修改,按引用传入的变量可以访问并且修改。

Lambda还有一个重要的作用就是把自身当作回调函数的参数,演示代码如下:

1
2
3
4
5
6
7
8
9
10
int get_best(int a, int b, bool (*compare)(int a, int b))
{
if(compare(a, b))return a;
else return b;
}
int main(void)
{
std::cout << get_best(12, 34, [](int a,int b)->bool{if(a<b)return true; else return false;}) << std::endl;
return 0;
}

使用该方法可以快速的编写回调函数。