【C++那些事儿】C++入门 | 命名空间 | 缺省参数 | 引用 | 内联函数 | auto关键字 | 范围for循环 | nullptr
📷 ���池俊:
个人主页
🔥个人专栏: ✅数据结构冒险记 ✅C++那些事儿
🌅 有航道的人,再渺小也不会迷途。
文章目录
- 前言
- 1. C++关键字(C++98)
- 2. 命名空间
- 2.1 命名空间定义
- 2.2 命名空间使用
- 3. C++输入&输出
- 4. 缺省参数
- 4.1 缺省参数概念
- 4.2 缺省参数分类
- 5. 函数重载
- 5.1 函数重载引入
- 1、参数【类型】不同构成重载
- 2、参数【个数】不同构成重载
- 3、参数【类型顺序】不同构成重载
- 5.2 C++支持函数重载的原理--名字修饰(name Mangling)
- 6. 引用
- 6.1 引用概念
- 6.2 引用特性
- 6.3 常引用
- 6.4 使用场景
- 1. 做参数
- 2. 做返回值
- 思考题
- 6.5 传值、传引用效率比较
- 1、值和引用的作为函数参数的性能比较
- 2、值和引用的作为返回值类型的性能比较
- 6.6 引用和指针的区别
- `引用和指针的不同点`
- 7. 内联函数
- PS:头文件中定义一个函数,如果该头文件在多个位置被包含,那么就会出现函数重定义的问题,编译器报错,那么这个问题该如何解决呢?
- 7.1 概念
- 7.2 特性
- 【面试题】
- 宏的优缺点?
- C++有哪些技术替代宏?
- 8. auto关键字(C++11)
- 8.1 类型别名思考
- 8.2 auto简介
- 8.3 auto的使用细则
- 8.3 auto不能推导的场景
- 9. 基于范围的for循环(C++11)
- 9.1 范围for的语法
- 9.2 范围for的使用条件
- 1. for循环迭代的范围必须是确定的
- 2. 迭代的对象要实现++和==的操作。
- 10. 指针空值nullptr(C++11)
- 10.1 C++98中的指针空值
前言
C++是在C的基础之上,容纳进去了面向对象编程思想,并增加了许多有用的库,以及编程范式等。熟悉C语言之后,对C++学习有一定的帮助,本章节主要目标:
- 补充C语言语法的不足,以及C++是如何对C语言设计不合理的地方进行优化的,比如:作用域 方面、IO 方面、函数 方面、指针 方面、宏 方面等。
- 为后续 类和对象 学习打基础。
1. C++关键字(C++98)
C++总计63个关键字,C语言32个关键字
asm do if return try continue auto double inline short typedef for bool dynamic_cast int signed typeid public break else long sizeof typename throw case enum mutable static union wchar_t catch explicit namespace static_cast unsigned default char export new struct using friend class extern operator switch virtual register const false private template void true const_cast float protected this volatile while delete goto reinterpret_cast 2. 命名空间
在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。
#include int rand = 10; // C语言没办法解决类似这样的命名冲突问题,所以C++提出了namespace来解决 int main() { printf("%d\n", rand); return 0; } // 编译后后报错:error C2365: “rand”: 重定义;以前的定义是“函数”
2.1 命名空间定义
定义命名空间,需要使用到 namespace关键字,后面跟 命名空间的名字,然 后接一对{} 即可,{}中即为命名空间的成员。
// lzf是命名空间的名字,一般开发中是用项目名字做命名空间名。 // 1. 正常的命名空间定义 namespace lzf { // 命名空间中可以定义变量/函数/类型 int rand = 10; int Add(int left, int right) { return left + right; } struct Node { struct Node* next; int val; }; } //2. 命名空间可以嵌套 // test.cpp namespace N1 { int a; int b; int Add(int left, int right) { return left + right; } namespace N2 { int c; int d; int Sub(int left, int right) { return left - right; } } } //3. 同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。 // ps:一个工程中的test.h和上面test.cpp中两个N1会被合并成一个 // test.h namespace N1 { int Mul(int left, int right) { return left * right; } }
注意:一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中
2.2 命名空间使用
命名空间中成员该如何使用呢?比如:
namespace lzf { // 命名空间中可以定义变量/函数/类型 int a = 0; int b = 1; int Add(int left, int right) { return left + right; } struct Node { struct Node* next; int val; }; } int main() { // 编译报错:error C2065: “a”: 未声明的标识符 printf("%d\n", a); return 0; }
命名空间的使用有三种方式:
- 加命名空间名称及作用域限定符(命名空间前缀)
当定义了一个命名空间后,可以通过在实体名称前加上命名空间名称和作用域限定符(::)来显式指定要使用的特定命名空间的实体。
int main() { // 使用命名空间前缀来调用变量 printf("%d\n", lzf::a); return 0; }
- 使用using将命名空间中某个成员引入
可以在特定的作用域内使用using声明来引入命名空间中的一个或多个实体,这样就可以直接使用这些实体而无需每次都加上命名空间前缀。
// 使用using声明来引入命名空间中的变量 b using lzf::b; int main() { printf("%d\n", lzf::a); // 现在可以直接调用变量 b,无需前缀 printf("%d\n", b); return 0; }
- 使用using namespace 命名空间名称 引入
也可以使用using声明来引入整个命名空间,这样命名空间中的所有实体都将被引入到当前作用域中。
using namespace lzf; int main() { // 现在可以直接调用命名空间中的所有变量和函数,无需前缀 printf("%d\n", a); printf("%d\n", b); printf("%d\n", Add(10, 20)); return 0; }
3. C++输入&输出
新生婴儿会以自己独特的方式向这个崭新的世界打招呼,C++刚出来后,也算是一个新事物
那C++是否也应该向这个美好的世界来声问候呢?我们来看下C++是如何来实现问候的。
#include // std是C++标准库的命名空间名,C++将标准库的定义实现都放到这个命名空间中 using namespace std; int main() { cout 头文件中。
- > 是流提取运算符。
- 使用C++输入输出更方便,不需要像 printf/scanf 输入输出时那样,需要手动控制格式。C++的输入输出可以自动识别变量类型。
- 实际上 cout 和 cin 分别是 ostream 和 istream 类型的对象,>>和 int a; double b; char c; // 无需使用格式化输入控制,可以自动识别变量的类型 cin > a; cin >> b >> c; cout cout Func(); // 没有传参时,使用参数的默认值 Func(10); // 传参时,使用指定的实参 return 0; } cout cout cout cout cout cout cout cout int a = 10; int& ra = a;// int a = 10; // int& ra; // 该条语句编译时会出错 int& ra = a; int& rra = a; printf("%p %p %p\n", &a, &ra, &rra); } const int a = 10; // int& ra = a; // 该语句编译时会出错,a为常量 const int& ra = a; // int& b = 10; // 该语句编译时会出错,b为常量 const int& b = 10; double d = 12.34; // int& rd = d; // 该语句编译时会出错,类型不同 const int& rd = d; // 隐式类型转换会产生临时变量,临时变量具有常性 } int temp = left; left = right; right = temp; } static int n = 0; n++; // ... return n; } int c = a + b; return c; } int main() { int& ret = Add(1, 2); Add(3, 4); cout int a[10000]; }; void TestFunc1(A a) {} void TestFunc2(A& a) {} void TestRefAndValue() { A a; // 以值作为函数参数 size_t begin1 = clock(); for (size_t i = 0; i
- 使用using namespace 命名空间名称 引入
- 使用using将命名空间中某个成员引入
- 10.1 C++98中的指针空值
The End