• C++特性——命名空间、I/O流以及缺省参数


    C++特性

    1. 写在前面

    可以认为,C++的语法和语义基本上包含了C语言的所有内容。二者之间的关系大致可以用下图表示:

    在这里插入图片描述

    同时,C++在C语言的基础上引入了许多额外的特性和概念,下面,我们就来学习C++有而C语言没有的特性。


    2. 命名空间

    我们都知道,C语言有一大不足之处,那就是命名冲突,这可能是和库里面函数的名字发生冲突,也可能是与自己定义的变量冲突,例如:

    #include 
    #include 
    
    int rand = 1;
    
    int main()
    {
    	printf("%d\n", rand);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    会有如下报错信息:
    注:对于为什么会发生命名冲突以及其他情况可以看看👉变量名和函数名的冲突问题

    在这里插入图片描述

    这里就可以看见,全局变量rand库函数rand的名字之间发生了冲突。而为了解决这种类似的命名冲突,C++就有了命名空间这一概念和用法:

    C++中的命名空间是一种用于组织和管理代码的机制,允许将全局作用域内的标识符(例如变量、函数、类)分组为命名空间。这有助于避免命名冲突,并提供更好的代码结构和可维护性。

    具体用法:

    namespace space_name
    {
        //变量
        //函数
        //结构
        //…………
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    例如,对于上面的全局变量rand,我们可以这样写从而避免错误:

    #include 
    #include 
    
    //定义了一个名为test的命名空间
    namespace test
    {
    	int rand = 1;
    }
    
    int main()
    {
    
    	printf("%d\n", test :: rand);
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    注:符号::为域作用限定符,用于引用指定命名空间的成员。

    2.1 命名空间的嵌套

    命名空间可以嵌套定义,例如:

    #include 
    #include 
    
    namespace test_1
    {
    	int num_1 = 1;
    
    	namespace test_2
    	{
    		int num_2 = 2;
    	}
    }
    
    int main()
    {
    	printf("%d\n", test_1 :: test_2 :: num_2);
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    小细节:不同级别的命名空间的名字可以相同,例如,上面的test_2就可以改为test_1,程序同样可以正常运行。但是,对于同一级别的命名空间的名字,如果两个空间内没有同名变量,那这两个命名空间就可以同名,否则就不能同名,例如:

    这种写法是正确的:

    namespace test_1
    {
    	int num = 1;
    
    }
    
    namespace test_1
    {
    	int num_1 = 2;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    而这种写法是错误的:

    namespace test_1
    {
    	int num = 1;
    
    }
    
    namespace test_1
    {
    	int num = 2;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2.2 命名空间的完全展开

    我们可以用using namespace space_name;,来将一个命名空间完全展开,这样,再使用命名空间内的成员时,就可以不用使用域作用限定符::,例如:

    #include 
    #include 
    
    namespace test
    {
    	int num = 1;
    }
    
    using namespace test;
    
    int main()
    {
    	printf("%d\n", num);
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    注意:将命名空间完全展开这一做法具有一定的危险性,如果我们将命名空间比作是一道城墙,那么将命名空间展开就可以看作是将这道城墙推到,让城墙内的东西完全暴露。因此,只有确保命名空间的内容不会和库中内容发生冲突时,才可以将命名空间展开

    错误示例:

    #include 
    #include 
    
    namespace test
    {
    	int rand = 1;
    }
    
    using namespace test;
    
    int main()
    {
    	printf("%d\n", rand);
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    报错信息:

    在这里插入图片描述

    2.3 命名空间的指定展开

    每次指定命名空间很不方便,但是直接将命名空间展开又会有冲突风险,那么我们就可以采取一个折中的办法——命名空间的指定展开

    我们可以用using space_name :: number;来实现,例如:

    #include 
    #include 
    
    namespace test
    {
    	int num1 = 1;
    	int num2 = 2;
    	int rand = 3;
    }
    
    //对num1, num2指定展开
    using test::num1;
    using test::num2;
    
    int main()
    {
    	printf("%d\n", num1);
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    3. C++的I/O流

    一般来说,我们学习一门语言的第一串代码就是打印字符串Hello World,现在就让我们来看看C++版的Hello World

    #include 
    
    //有关输入输出流的关键字通常都在 std 命名空间中
    using namespace std;
    
    int main()
    {
    	cout << "Hello World" << endl;
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    要理解这段代码,我们就需要了解C++的I/O流

    C++ 中的输入输出流(I/O streams)是用于处理输入和输出的重要概念。它们是 C++ 标准库中的一部分,用于读取和写入数据到不同的设备,例如键盘、屏幕、文件、网络等。C++ 中主要的 I/O 流类是基于两个主要类模板构建的:istreamostream。这两个类分别用于输入和输出。

    以下是常用的类和基本操作:

    • 上面所包含的头文件iostream就是istreamostream的派生类,它提供了输入和输出的功能

    • coutconsole out,称为流插入,将类容输出到控制台,相当于C语言的printf。需要注意,cout可以自动识别变量类型,因此可以多组不同类型的数据同时输出,例如:

      int num1 = 10;
      double num2 = 3.14;
      cout << "Hello World" << endl << num1 << endl << num2 << endl;
      
      • 1
      • 2
      • 3
    • <<:用于将数据写入流

    • endl:C++的换行符,例如

      cout << "Hello World" << endl << num1 << endl << num2 << endl;
      //等价于
      cout << "Hello World" << '\n' << num1 << '\n' << num2 << '\n';
      
      • 1
      • 2
      • 3
    • cinconsole in,称为流提取,用于从流中读取数据,相当于C语言中的scanf。和cout一样,cin也可以自动识别变量类型

    • >>:用于从流中读取数据,例如:

      int num1 = 0;
      double num2 = 0.0;
      
      cin >> num1 >> num2;
      
      • 1
      • 2
      • 3
      • 4

    4. 缺省参数

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

    缺省参数分为以下两类:

    • 全缺省参数:函数的所有参数都为缺省参数,例如:

      void Func(int a = 10, int b = 20);
      
      • 1
    • 半缺省参数:部分参数为缺省参数,例如:

      void Func(int a, int b = 10);
      
      • 1

    缺省参数的使用实例:

    #include 
    
    using namespace std;
    
    void Func(int a, int b = 10)
    {
    	cout << "a = " << a << endl << "b = " << b << endl;
    }
    
    int main()
    {
    	Func(100);
    	Func(100, 0);
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    output:

    a = 100
    b = 10
    a = 100
    b = 0
    
    • 1
    • 2
    • 3
    • 4

    4.1 使用缺省参数的注意事项

    1. 当一个函数的参数为部分缺省时缺省值只能从右往左给,且必须连续,否则编译器无法判断传入的实参代表着哪个形参。例如:

      void Func(int a, int b = 10, int c)
      {
      	cout << b << endl;
      }
      
      • 1
      • 2
      • 3
      • 4

      会有如下报错信息:

      在这里插入图片描述

    2. 如果一个函数的参数都是缺省参数,那么传入的实参必须是连续的。例如下面的函数调用就是错误的:

      #include 
      
      using namespace std;
      
      void Func(int a = 1, int b = 10, int c = 100)
      {
      	cout << a << endl << b << endl << c << endl;
      }
      
      int main()
      {
      	Func( , 1, );
      
      	return 0;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
    3. 缺省参数不能在函数的声明和定义中同时出现,且只能在函数声明的时候给(如果同时,那么编译器不知道用哪一个,如果只在定义中给,那么当其他文件引用时,就不知道这个值)

    4. 缺省参数必须是常量或者是全局变量


    本篇完。

  • 相关阅读:
    Google Cloud Computer Engine 磁盘扩容
    Spring Boot传参注解详解
    Vue3通透教程【十六】TS编译配置
    微信页面公众号页面 安全键盘收起后键盘下方页面留白
    LeetCode每日一题——902. 最大为 N 的数字组合
    Python学习笔记(十一)——面向对象二
    计算机毕业设计Java校园网上跳蚤书市系统(源码+系统+mysql数据库+Lw文档)
    嵌入式软件设计专栏导读
    使用Wireshark软件抓包(分析报文)
    设备管理团队如何做好停机维护工作_基于PreMaint设备数字化平台
  • 原文地址:https://blog.csdn.net/l315225/article/details/133801197