【C++的奇迹之旅(二)】C++关键字&&命名空间使用的三种方式&&C++输入&输出&&命名空间std的使用惯例

04-13 1481阅读

【C++的奇迹之旅(二)】C++关键字&&命名空间使用的三种方式&&C++输入&输出&&命名空间std的使用惯例

文章目录

  • 📝前言
  • 🌠 C++关键字(C++98)
  • 🌉 命名空间
    • 🌠命名空间定义
    • 🌉命名空间使用
    • 🌠命名空间的使用有三种方式:
      • 🌉加命名空间名称及作用域限定符
      • 🌠使用using将命名空间中某个成员引入
      • 🌉 使用using namespace 命名空间名称 引入
      • 🌠命名空间的查找先后顺序
      • 🌉 C++输入&输出
      • 🌠`std`命名空间的使用惯例
      • 🚩总结

        📝前言

        C++是在C的基础之上,容纳进去了面向对象编程思想,并增加了许多有用的库,以及编程范式

        等。熟悉C语言之后,对C++学习有一定的帮助,本章节主要目标:

        1. 补充C语言语法的不足,以及C++是如何对C语言设计不合理的地方进行优化的,比如:作用

          域方面、IO方面、函数方面、指针方面、宏方面等。

        2. 为后续类和对象学习打基础。

        🌠 C++关键字(C++98)

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

        ps:下面我们只是看一下C++有多少关键字,不对关键字进行具体的讲解。后面我们学到以后再

        细讲。

        语言的发展就像是练功打怪升级一样,也是逐步递进,由浅入深的过程。我们先来看下C++的历史版本。

        asmdoifreturntrycontinue
        autodoubleinlineshorttypedeffor
        booldynamic_castintsignedtypeidpublic
        breakelselongsizeoftypenamethrow
        caseenummutablestaticunionwchar_t
        catchexplicitnamespacestatic_castunsigneddefault
        charexportnewstructusingfriend
        classexternoperatorswitchvirtualregister
        constfalseprivatetemplatevoidtrue
        const_castfloatprotectedthisvolatilewhile
        deletegotoreinterpret_cast

        🌉 命名空间

        在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。

        【C++的奇迹之旅(二)】C++关键字&&命名空间使用的三种方式&&C++输入&输出&&命名空间std的使用惯例

        🌠命名空间定义

        定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}

        中即为命名空间的成员。

         1. 正确的命名空间定义
        //正确的命名空间定义
        namespace Asen
        {
        	//命名空空间中可以定义变量/函数/类型
        	int rand = 10;
        	
        	int Add(int begin, int end)
        	{
        		return begin + end;
        	}
        	struct Node
        	{
        		struct Node* next;
        		int data;
        	};
        }
        
        1. 命名空间可以嵌套
        namespace Asen
        {
        	int a;
        	int b;
        	
        	int Add(int left, int right)
        	{
        		return left + right;
        	}
        	namespace needs_confidence
        	{
        		int Sub(int begin, int end)
        		{
        			return begin - end;
        		}
        	}
        }
        
        1. 同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。

          如:一个工程中的test.h和上面test.cpp中两个asen会被合并成一个

          【C++的奇迹之旅(二)】C++关键字&&命名空间使用的三种方式&&C++输入&输出&&命名空间std的使用惯例

        注意:一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中

        🌉命名空间使用

        命名空间中成员该如何使用呢?比如以下代码运行:

        namespace Asen
        {
        	int a = 0;
        	int b = 1;
        	
        	int Add(int left, int right)
        	{
        		return left + right;
        	}
        	namespace needs_confidence
        	{
        		int Sub(int begin, int end)
        		{
        			return begin - end;
        		}
        	}
        }
        int main()
        {
        	printf("%d\n", a);
        	return 0;
        }
        

        运行截图:

        【C++的奇迹之旅(二)】C++关键字&&命名空间使用的三种方式&&C++输入&输出&&命名空间std的使用惯例

        🌠命名空间的使用有三种方式:

        🌉加命名空间名称及作用域限定符

        int main()
        {
        	printf("%d\n", Asen::a);
        	return 0;
        }
        

        【C++的奇迹之旅(二)】C++关键字&&命名空间使用的三种方式&&C++输入&输出&&命名空间std的使用惯例

        🌠使用using将命名空间中某个成员引入

        using Asen::b;
        int main()
        {
        	printf("%d\n", Asen::a);
        	printf("%d\n", b);
        	return 0;
        }
        

        【C++的奇迹之旅(二)】C++关键字&&命名空间使用的三种方式&&C++输入&输出&&命名空间std的使用惯例

        🌉 使用using namespace 命名空间名称 引入

        using namespace Asen;
        int main()
        {
        	printf("%d\n", Asen::a);
        	printf("%d\n", b);
        	Add(66, 88);
        	return 0;
        }
        

        【C++的奇迹之旅(二)】C++关键字&&命名空间使用的三种方式&&C++输入&输出&&命名空间std的使用惯例

        🌠命名空间的查找先后顺序

        一. 命名空间的查找顺序是:

        当前命名空间 > 父命名空间 > 全局命名空间 > 模块命名空间 > 内置模块命名空间

        从最具体的当前命名空间开始向上级别进行查找,一直到全局和内置模块命名空间,以此来解决可能出现的同名变量和函数的命名冲突问题。

        具体规则如下:

        1. 当前命名空间

          首先在当前命名空间中查找。

        2. 父命名空间

          如果当前命名空间没有找到,则查找其直接父命名空间。

        3. 嵌套的父命名空间

          如果直接父命名空间也没有找到,则继续向上查找更高层次的父命名空间。

        4. 全局命名空间

          如果所有父命名空间都没有找到,则最后在全局命名空间中查找。

        5. 导入的命名空间

          如果使用了using指令导入其他命名空间,也会在导入的命名空间中查找。

        举个例子:

        namespace A 
        {
          void func() 
          {
            // do something 
          }
        }
        namespace B 
        {
        	  namespace C 
         	 {
          	 	 void func() 
          	 	 {
            	 	 // do something
           		 } 
         	 }
         	 using namespace A;
        	  void test() 
         	 {
           		 func(); // 会调用B::C::func()
          	 }
        }
        

        这里B命名空间中的test函数,首先在B命名空间中查找func,没有找到,然后去B的子命名空间C中查找,找到就调用C中的func。

        简单总结

        编译默认查找

        a、当前局部域 : 自留地

        b、全局域找 : 村子野地

        c、到展开的命名空间中查找 : 相当于张大爷在自己的自留地加了声明,谁需要就来摘

        二. 以下是有关命名空间的查找使用实例:

        namespace Asen
        {
        	namespace needs_confi
        	{
        		int rand = 0;
        		 
        		int Add(int left, int right)
        		{
        			return left + right;
        		}
        		struct Node
        		{
        			struct Node* next;
        			int data;
        		};
        	}
        }
        namespace needs_confi
        {
        	int rand = 0;
        	int Add(int left, int right)
        	{
        		return (left + right) * 10;
        	}
        }
        int main()
        {
        	printf("%p\n", rand);
        	printf("%d\n", Asen::needs_confi::rand);
        	printf("hello world\n");
        	printf("%d\n", Asen::needs_confi::Add(2, 3));
        	printf("%d\n", needs_confi::Add(2, 3));
        	struct Asen::needs_confi::Node pnode;
        }
        

        【C++的奇迹之旅(二)】C++关键字&&命名空间使用的三种方式&&C++输入&输出&&命名空间std的使用惯例

        三· 展开命名空间暴露问题:

        展开命名空间可能会导致的主要问题如下:

        1. 名称冲突

          当使用using namespace将一个命名空间中的所有名称导入到当前作用域时,如果导入的命名空间和当前命名空间存在同名的变量/函数等,就会产生名称冲突,编译或运行时可能会出现错误。

        2. 污染全局作用域

          使用using namespace后,导入的所有名称都会暴露到全局作用域,可能会与其他代码产生冲突,也更难追踪是哪个命名空间中的名称。

        3. 难以区分来源

          如果直接使用using namespace,在代码中看到一个名称就不知道它来自哪个具体的命名空间。这给代码维护和调试带来困难。

        4. 性能影响

          使用using namespace后,编译器需要在更广泛的作用域中查找名称,这可能会影响编译效率和程序性能。

        5. 依赖隐藏

          使用using namespace可能会隐藏某些依赖关系,例如标准库名称可能会屏蔽用户自定义的同名名称。

        6. 难以控制

          直接使用using namespace没有办法精细控制导入的范围,无法选择性导入某些名称。

        因此一般来说,不推荐在头文件中使用using namespace,在源文件中使用也应谨慎。建议直接使用具体的命名空间限定名称。

        如:这里我包含了两个头文件,其中这个#include"Stack.h"的内容如下,这里主要是用namespace 空间定义,然后展开namespace ,目的是为了看两个命名空间都有相同的内容,在查找时看看会先用哪个?还是会编译报错:

        【C++的奇迹之旅(二)】C++关键字&&命名空间使用的三种方式&&C++输入&输出&&命名空间std的使用惯例

        #include"Queue.h"
        #include"Stack.h"
        namespace xjh
        {
        	typedef struct Stack
        	{
        	}ST;
        	void STInit(ST* ps)
        	{}
        	struct Queue
        	{
        		//...
        	};
        }
        // 展开命名空间 
        using namespace ahui;
        using namespace xjh;
        // 编译默认查找
        // a、当前局部域				: 自留地
        // b、全局域找				: 村子野地
        // c、到展开的命名空间中查找  : 相当于张大爷在自己的自留地加了声明,谁需要就来摘
        int main()
        {
        	struct Stack st1;
        	STInit(&st1);
        	printf("%d\n", sizeof(st1));
        	ahui::ST st;
        	printf("%d\n", sizeof(st));
        	STInit(&st);
        	STPush(&st, 1);
        	STPush(&st, 2);
        	STPush(&st, 3);
        	STPush(&st, 4);
        	return 0;
        }
        

        代码运行:

        【C++的奇迹之旅(二)】C++关键字&&命名空间使用的三种方式&&C++输入&输出&&命名空间std的使用惯例

        🌉 C++输入&输出

        和我们刚学C语言时,学习了printf和scanf来进行输出和输入,C++同样也有输入和输出,我们来看下C++是如何来实现问候的。

        #include
        // std是C++标准库的命名空间名,C++将标准库的定义实现都放到这个命名空间中
        using namespace std;
        int main()
        {
        	cout
           int a;
           double b;
           char c;
             
           // 可以自动识别变量的类型
           cina;
           cin>b>>c;
             
           cout
VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]