【C++那些事儿】C++入门 | 命名空间 | 缺省参数 | 引用 | 内联函数 | auto关键字 | 范围for循环 | nullptr

小明 2025-04-28 23:10:16 4

📷 ���池俊: 个人主页

🔥个人专栏: ✅数据结构冒险记 ✅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++学习有一定的帮助,本章节主要目标:

                                1. 补充C语言语法的不足,以及C++是如何对C语言设计不合理的地方进行优化的,比如:作用域 方面、IO 方面、函数 方面、指针 方面、宏 方面等。
                                2. 为后续 类和对象 学习打基础。

                                1. C++关键字(C++98)

                                C++总计63个关键字,C语言32个关键字

                                asmdoifreturntrycontinue
                                autodoubleinlineshorttypedeffor
                                booldynamic_castintsignedtypeidpublic
                                breakelselongsizeoftypenamethrow
                                caseenummutablestaticunionwchar_t
                                catchexplicitnamespacestatic_castunsigneddefault
                                charexportnewstructusingfriend
                                classexternoperatorswitchvirtualregister
                                constfalseprivatetemplatevoidtrue
                                const_castfloatprotectedthisvolatilewhile
                                deletegotoreinterpret_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
The End
微信