1、命名空间 — namespace

1.1 定义

命名空间域需要使用namespace关键字,后面跟命名空间的名字然后接{  }即可,{  }中是命名空间的成员。

1.2 namespace用法

1.2.1命名空间使用

在C语言中,int i = 0; 当我们再次定义int i = 10;时会报错,如下图,输出报错: " i ",重定义。

此时,使用namespace生成命名空间域,把变量/函数/类型用域封装起来,防止命名冲突,

使用时,用域名 :: 值 链接,如下图。

#include <iostream>
// using namespace std;
namespace yq  // 定义了一个名为id的空间域
{
    // 命名空间中可以定义变量/函数/类型
	int i = 10;
}
int main()
{
	int i = 0;

    printf("%d ", i); //此时i的值为0
	printf("%d ", yq::i); // 此时i的值为10

	return 0;
}

注意:编译默认查找规律:当前局部域  —> 全局域找—> 到展开的命名空间中查找

1.2.2 using namespace     

作用:using namespace是指展开命名空间,展开后,不需要每次调用都加上域名::值,但是展开后也可能造成定义冲突,有三种用法

1、using id :: i   指定访问某一个, 指定展开后,可以直接用

2、using namespace id    指定展开某一个域, 指定展开后,这个域里面定义的内容相当于在全局域中

3、using namespace std    全展开,  std是C++的库的域的名称

1.3 作用

命名空间域主要在写项目中常用,可以解决定义冲突问题,方便多人协作。

2、C++输入输出

在C++里面,cin 和 cout 输入输出数据时,可以自动识别类别。 

2.1 C++的输入 ---  cin

定义: cin 类似于C语言中的scanf ,都是从终端输入数据,但不同的是 cin 采用 >>, >> 后接要输入的数据所接收的值。

2.2 C++的输出 --- cout

定义: cout 类似于C语言中的printf ,打印数据 ,但不同的是 cout采用 <<, << 后接要输出的值,cout << 后可以接一个endl 表示结束自动换行。

示例:

3、缺省参数

3.1 定义:

        缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。

示例:当我们传参时,指定实参则a的值为实参值 a = 10,若不指定,则用形参的缺省值,a = 20

 3.2 分类

3.2.1 全缺省参数

        全缺省是使用函数时指不传参给函数,全采用形参的缺省值,如下图所示

3.2.2 半缺省参数

        半缺省是使用函数时指传一部分参给函数,必须按顺序传参,为传参部分采用形参的缺省值

4、函数重载

4.1 定义:

        函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数或类型或类型顺序)不同,常用来处理实现功能类似数据类型
不同的问题。
void Add(int left, int right) {
	cout << "int Add(int left, int right)" << endl;
}
int main()
{
	Add(1,2);
	return 0;
}

4.2 分类

4.2.1 参数类型不同

        在函数同名时,根据函数的形参的类型不同,在调用函数时传的实参的值不同调用不同的函数,如下图所示:

4.2.2 参数个数不同

        在函数同名时,根据函数的形参的个数不同,在调用函数时传的实参的个数不同调用不同的函数,如下图所示:

4.2.3 参数顺序不同

        在函数同名时,根据函数的形参的类型顺序不同,在调用函数时传的实参的类型顺序不同调用不同的函数,如下图所示:

5、引用

5.1 定义

        引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。

5.2 具体结构

类型 & 引用变量名(对象名) = 引用实体

示例:

5.3 引用特性

1. 引用在定义时必须初始化
2. 一个变量可以有多个引用
3. 引用一旦引用一个实体,再不能引用其他实体

5.4 使用场景

5.4.1 做参数

        在函数传参时,&left后,left 为x的别名,类似于用指针接收了X地址的作用,此时更改 left 的值,x 的值也会更改。

void Swap(int& left, int& right)  //此时 left 是x的别名,right 是y的别名
{
    int temp = left;
    left = righe;
    right = temp;
}

 int main()
{
    int x = 1;
    int y = 2;
    Swap(x,y);
    cout << "x = " << x << "y = " << y << endl; // x = 2, y = 1.
    return 0;
}
5.4.2 做返回值
int& Count()
{
    int n = 0;
    n++;
    return n;    
}

 int main()
{
    Count()
    cout << "n = " << n  << endl; // 此时n 为1
    return 0;
}

5.5  引用 权限问题

        引用的权限不能放大,只能平移和缩小

实例:

放大:权限的放大,不可以

const int m = 0;

int & n = m;

// const m 时, m 的值不可以修改,n是m 的别名,修改n 会更改m ,冲突,程序报错

// m 为只读,n 为可读可写,权限放大,不可以

平移:权限的平移,可以

int x = 0;

int& y = x;

// 此时,y 为 x 的别名,x 为可读可写,y 也是可读可写,权限平移,可行

缩小:权限的缩小,可以,

int x = 0;

const int z = x;

// 此时,z 为 x 的别名,x 为可读可写,z 为只读,权限缩小,可行

6、内联函数

6.1 概念

        以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调 用建立栈帧的开销,内联函数提升程序运行的效率

6.2 特性

        1. inline是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会 用函数体替换函数调用,缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运 行效率。

        2. inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,一般建 议:将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不 是递归、且频繁调用的函数采用inline修饰,否则编译器会忽略inline特性。

        3. inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址 了,链接就会找不到。

// F.h
#include <iostream>
using namespace std;

inline void f(int i); // 使用 inline 可以在调用时直接展开函数,减少运行时间

// F.cpp
#include "F.h"
void f(int i)
{
    cout << i << endl;
}

// main.cpp
#include "F.h"
int main()
{
    f(10);
    return 0;
}

// 链接错误:main.obj : error LNK2019: 无法解析的外部符号 "void __cdecl 
f(int)" (?f@@YAXH@Z),该符号在函数 _main 中被引用

7、auto关键字

7.1 类型别名思考

        随着程序越来越复杂,程序中用到的类型也越来越复杂,经常体现在类型难于拼写,含义不明确导致出错,所以用auto修饰的变量可以自动确定定义变量的类型。

注意 :使用auto定义变量时必须对其进行初始化,在编译阶段编译器需要根据初始化表达式来推导auto 的实际类型。因此auto并非是一种“类型”的声明,而是一个类型声明时的“占位符”,编译器在编 译期会将auto替换为变量实际的类型。

int main()
{
    int a = 10;
    auto b = a;  // 此时 b 的类型为int 
    auto c = 'a';  // 此时 c 的类型为 char
}

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐