目录
一、C++关键字
下列的关键字有的我们在C语言中就已经见过了,而有些比较陌生,不过不用慌,这些现在不用死记,以后多用就记住了。
二、命名空间
在C/C++中,变量,函数和类的名称都存在于全局作用域中,而C++为了避免这样的命名冲突和名字污染,添加了命名空间域。(关键字:namespace)
全局作用域和命名空间域就类似于这样(如果理解不对,请指教),相当于单独开了一个空间给命名空间域。
1、区别
1. C语言
在没有命名空间的C语言语法里这样写就是错误的,报错信息可以看见:rand重定义。
2. C++
定义了一个命名空间,在命名空间里面定义了一个rand变量,这样的话就不会和库函数里面的rand函数产生命名冲突。(:: 这个符号作用域限定符)
2、命名空间定义
#include <iostream>
// 正常定义
namespace cpp1
{
int a = 1;
int b = 2;
int Add(int a, int b)
{
return a + b;
}
}
// 嵌套定义
namespace cpp2
{
int a = 1;
int b = 2;
int Add(int a, int b)
{
return a + b;
}
namespace cpp3
{
int a = 1;
int b = 2;
int Add(int a, int b)
{
return a + b;
}
}
}
// 一个工程里面允许定义多个相同的命名空间——编译器最后会合成同一个命名空间中。
int main()
{
// 打印cpp2里面的函数
printf("%d\n", cpp2::Add(1, 2));
// 打印cpp2里面的cpp3里面的函数
printf("%d\n", cpp2::cpp3::Add(3, 4));
return 0;
}
3、命名空间的使用
#include <iostream>
namespace cpp
{
int a = 1;
int b = 2;
int Add(int a, int b)
{
return a + b;
}
}
// 将该命名空间进行展开
// using namespace cpp;
// 将命名空间域里面的变量或者函数进行个别展开
using cpp::a;
int main()
{
// 用命名空间名称 + 作用域作用符
// printf("%d\n", cpp::Add(1, 2));
// 用using + 命名空间名称,将该命名空间进行展开
// using namespace cpp;
// 将命名空间域里面的变量或者函数进行个别展开
// std::cout << a << std::endl;
// 该语句有错误————变量b未定义
// std::cout << b << std::endl;
return 0;
}
三、C++输入&输出
// 如果是自己做题, 可以将std这个命名空间域进行展开 using namespace std;
// 如果是写工程的话,不建议展开
#include <iostream>
int main()
{
int a = 10;
// C++没有占位符(格式输出符 : %d ···)
std::cin >> a; // 输入
std::cout << a;// 输出
return 0;
}
四、缺省参数
说白了就是函数传参的时候,可以进行默认传值(如果没有传值的话)。
缺省参数的初始化的顺序是有要求的,必须是连续的,必须从最右侧开始读入。
#include <iostream>
namespace C
{
// C语言写法
int Add(int a, int b)
{
return a + b;
}
}
namespace Cpp
{
// C++缺省参数写法
int Add(int a = 5, int b = 0)
{
return a + b;
}
// 也可以只缺省一个参数(数目没有要求)
int sub(int a, int b = 2)
{
return a * b;
}
}
int main()
{
// endl 的作用是 插入一个换行符,并且刷新输出流
std::cout << C::Add(1, 2) << std::endl;
std::cout << Cpp::Add(1, 2) << std::endl;
std::cout << Cpp::Add(1) << std::endl;
std::cout << Cpp::Add() << std::endl;
std::cout << Cpp::Add(1) << std::endl;
return 0;
}
五、函数重载
函数重载的意义是,允许有多个功能类似的同名函数的存在。(就比如说实现一个加法函数,可以有整型的加法函数,也可以有浮点型的加法函数等等,实现的都是加法的功能,如果要用函数名进行区别的话,比较不友好)
要求:函数的参数类型、参数类型顺序、个数不完全一样。
六、引用
引用:就相当于是给一个变量起了一个别名。
用值作为参数进行传递,形参会形成一份临时拷贝,效率低下。(建议用引用作为形参的类型)
#include <iostream>
using namespace std;
// 如果是学C语言的时候,我们写交换函数是传的变量的地址,通过对变量地址的解引用来操作变量的内容。
// 现在我们可以用一个引用类型进行接收,相当于我们还是对原来的变量进行修改(可以从例子看出来,取别名可以是相同的)
void swap(int&a, int &b)
{
a = a ^ b;
b = a ^ b;
a = a ^ b;
}
int main()
{
int a = 5, b = 6;
swap(a, b);
cout << a << " " << b;
return 0;
}
#include <iostream>
using namespace std;
int main()
{
int a = 10;
int& b = a;
b = 3;
cout << a;
return 0;
}
七、内联函数
内联函数其实对标的就是C语言中的宏函数。
如果让你写一个宏函数的话,可能会漏洞百出,比较的麻烦。
// 写一个加法的宏函数
// 错误写法一
#define Add(a, b) a + b
// 错误写法二
#define Add(a, b) a + b;
// 错误写法三
#define Add(a, b) (a + b)
// 正确写法
#define Add(a, b) ((a) + (b))
而为了解决这样的问题,C++引入了一个内联函数的语法,和宏函数一样,在编译时,编译器会在调用的地方进行展开。
#include <iostream>
using namespace std;
// 内联函数在函数的基础上加上一个inline的关键字。
inline int Add(int a, int b)
{
return a + b;
}
int main()
{
cout << Add(1, 2);
return 0;
}
八、auto关键字(C++11)
// auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&
// 在同一行定义多个变量,当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量
int main()
{
int x = 10;
auto a = &x;
auto* b = &x;
auto& c = x;
cout << typeid(a).name() << endl;
cout << typeid(b).name() << endl;
cout << typeid(c).name() << endl;
*a = 20;
*b = 30;
c = 40;
return 0;
}
九、基于范围的for循环(C++11)
#include <iostream>
using namespace std;
int main()
{
int a[] = {1, 2, 3};
for (auto x : a)
{
cout << x << " ";
}
return 0;
}
十、指针空值---nullptr(C++11)
谢谢大家!