【CPP】CPP的命名空间输入输出缺省参数函数重载

目录

      • 1 命名空间 -- namespace
      • 2 CPP的输入与输出(io)
        • 2.1 输入输出流的一些规定
        • 2.2 实操一下
        • 2.3 关于endl
        • 2.4 关于精度控制
        • 2.5 效率提高
      • 3 缺省参数(默认参数)
        • 3.1 样例
        • 3.2 全缺省与半缺省
        • 3.3 缺省参数的意义
      • 4 函数重载
        • 4.1 函数重载的基本使用
        • 4.2 函数重载调用歧义

这里是oldking呐呐,感谢阅读口牙!先赞后看,养成习惯!
个人主页:oldking呐呐
专栏主页:深入CPP语法口牙


1 命名空间 – namespace

  • namespace是CPP中的一个关键字,namespace的出现是为了改善C语言命名冲突的问题,我们来举个例子
#include <stdio.h>
//#include <stdlib.h>
int rand = 0;int main()
{printf("%d\n", rand);return 0;
}
  • 以上代码中我们没有包含头文件stdlib.h,编译顺利通过

  • 但一旦我们包含头文件stdlib.h,编译会因为stdlib.h中包含有rand的定义而报错,也就是说C语言会有命名冲突的问题()
    请添加图片描述

  • 于是在CPP中我们引入了namespace的概念,尽可能地防止出现命名冲突的问题

  • 定义上,我们可以创建一个自己的命名空间,然后同事啥的又可以创建一个他自己的命名空间

  • 使用上,比方说我要使用自己的变量,就需要在变量名前加命名空间的名字和::(namespace's name::rand)

  • :::域作用限定符,

#include <stdio.h>
#include <stdlib.h>namespace oldkingnana
{int rand = 0;
}int main()
{printf("%d\n", oldkingnana::rand);return 0;
}
  • 命名空间的这个操作就像是厕所一样,厕所有我家厕所,也有同事家厕所,都叫厕所你说你要用厕所,我咋知道你要用谁家的厕所?于是就加一个前缀说明一下,要用谁家的厕所

  • 除了命名空间外,CPP其实还包括很多个不同的域

    • 局部域(小区的公共厕所):里面的变量只能在局部用
    • 全局域(市区的公共厕所):里面的变量哪儿都能用
    • 命名空间域(某个人家里的公共厕所):里面的变量申请了才能用
    • 类域(同样是某个人家里的公共厕所):里面的变量申请了都不一定能用
  • 各家各户都可以拥有自己的厕所这个操作说明不同域里头可以有同名字的变量,同一个域里面不能有同名字的变量

  • 不同的域之间会产生隔离,如果你想用其他域的变量,你得先写个前缀啥的

  • 举个例子(类域我们后面再考虑):

#include <stdio.h>
#include <stdlib.h>namespace oldkingnana
{int rand = 0;
}void fun()
{int rand = 1;printf("%d\n", rand);//局部域
}int main()
{printf("%d\n", oldkingnana::rand);//命名空间域printf("%p\n", rand);//全局域fun();return 0;
}
  • 我们知道访问变量,会优先查找局部的变量,再查找全局的变量,如果我们一定要在fun()函数里面,去访问全局的变量该怎么操作呢??
void fun()
{int rand = 1;printf("%d\n", rand);//局部域printf("%p\n", ::rand);//全局域
}
  • 如果::前面没有写任何类或者命名空间的名字,那就默认访问全局的变量

  • 域影响编译的时候查找变量的/函数/类型出处(声明/定义)的逻辑,有了域隔离之后,就能避免名字冲突的问题,局部域和全局域除了会影响编译查找逻辑之外,还会影响变量的生命周期,命名空间域和类域不影响变量的生命周期

  • 注意:命名空间域只能定义在全局,不能是局部
    请添加图片描述

  • 域里面可以包含函数,也可以包含结构,或者是类,使用方法也是同理即可,某某域里的某某变量/函数/结构/类

namespace oldkingnana
{int rand = 0;int Add(int x, int y){return x + y;}typedef struct my_struct{int x;int y;}my_struct;
}int main()
{printf("%d\n", oldkingnana::Add(1, 2));oldkingnana::my_struct My_Struct;//    (变量类型)       | (变量名)//命名空间的前缀是包括在变量类型里的return 0;
}
  • 其他要求:
    • namespace只能定义在全局,但它可以嵌套定义
    • 定义了多个命名空间会被认为是同一个命名空间
    • CPP标准库都放在一个叫做std(standard)的命名空间中
#include <iostream>namespace ok
{int WC = 0;namespace ok_person{int WC = 1;}
}namespace ok
{int WC1 = 3;
}int main()
{std::cout << ok::WC << ok::ok_person::WC << ok::WC1 << std::endl;return 0;
}
  • cout就放在<iostream>std的域中,在<iostream>我们能找到std开始的位置
    请添加图片描述
    请添加图片描述

  • 我们甚至能看到它引入了另一个文件<ostream>中的cout

  • 所以说如果我们想用cout,就需要说明一下用std标准库里头的cout(开发者自己都怕命名冲突的问题)

  • 输出结果
    请添加图片描述

  • 同名字的命名空间会合并(逻辑上),包括不同文件下同名字的命名空间一样会合并

  • Add.h

#pragma oncenamespace ok
{typedef int AddType;int Add(AddType x, AddType y);
}
  • Add.cpp
#include "Add.h"namespace ok
{int Add(AddType x, AddType y){return (int)(x + y);}
}
  • test.cpp
int main()
{std::cout << ok::Add(1, 2) << std::endl;return 0;
}

请添加图片描述

  • 比方说我自己写了个栈,放在Stack.hStack.cpp下,并且我不想有别人因为命名冲突影响代码运行,我把栈的所有代码都用oldkingnana这个命名空间封装了,如果后面我想添加队列到我的命名空间里,就不需要找到命名空间再往里头写,直接开一个新文件,叫Queue.hQueue.cpp即可,重新定义一个一模一样名字的命名空间即可

  • 编译查找一个变量的时候,默认情况下,会优先查找局部域,然后是全局域,但不会去查找命名空间域,所以一般对于命名空间的访问,有以下几种

    • 指定命名空间访问(推荐)(上面我们说过了用::,就不再提了)
    • using将命名空间的某个成员展开,项目中经常访问的成员且不存在冲突的成员比较推荐这种方式
    • 展开命名空间所有的成员(不推荐,风险较大,自己用在小工程倒是不错)
  • using展开单独的某个成员

using std::cout;
using std::endl;int main()
{cout << 1 << endl;return 0;
}
  • using展开整个命名空间(相当于是把命名空间的变量变成全局的了)
using namespace std;int main()
{cout << 1 << endl;return 0;
}

2 CPP的输入与输出(io)

2.1 输入输出流的一些规定
  • CPP引入了一个新的头文件<iostream>,我们在前文也见识过了,全称是"Input Output Stream",定义了标准输入输出对象

  • std::cinistream类对象,面向窄字符的标准输入流

  • std::coutostream类对象,面向窄字符的标准输出流

  • std::endl是一个函数,当他输入进流中的时候,相当于给流输入进一个换行符,并且刷新缓冲区

  • <<用于把内容输入进流中,>>用于把内容从流中输出

  • CPP输入输出不需要手动指定格式,只需要把内容扔到流里头就能输出出来,CPP会自动识别变量的类型(函数重载),甚至自定义对象也可以很好地输入输出,本质上

  • 注意:<<>>只能有两个操作数,意味着你不能这样写
    请添加图片描述

  • 以上的情况就是用了三个操作数,当然是不可以的了

2.2 实操一下
using std::cout;
using std::endl;
using std::cin;int main()
{int i = 0;int j = 0;cin >> i >> j;cout << i << j << endl;return 0;
}

请添加图片描述
请添加图片描述

  • 输入是同样的默认以空格和或者换行符间隔,和C同样的味道
2.3 关于endl
  • endl并非一个字符或者变量什么的,endl本质是一个函数,这个函数的调用过程非常复杂,过程相当于是put了一个"\n",涉及函数重载的一些内容
2.4 关于精度控制
  • CPP自己是带一套自己的精度控制逻辑的,目前来讲如果一定要控制精度,用原来C语言那套逻辑就行,CPP自己的需要用各种函数设置还是很没必要的
2.5 效率提高
  • 加这三句代码可以在某些竞赛中提高输出效率,复杂的咱后面的文章再提
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);

3 缺省参数(默认参数)

3.1 样例
#include <iostream>void fun(int i = 0)
{std::cout << i << std::endl;
}int main()
{fun();fun(10);return 0;
}

请添加图片描述

  • 其实本质上就是定义函数的时候为形参设置一个默认参数,当形参没有接收到实参的时候就使用默认值

  • 一般我们称这个默认参数为"缺省参数",当然直接叫默认参数也没问题,理解意思就行

  • 了解过一些python就很能理解了

3.2 全缺省与半缺省
  • 全缺省 – 每个参数都有缺省值
  • 半缺省 – 一部分参数有缺省值
//半缺省
void fun1(int a, int b = 2, int c = 3)
{std::cout << a << std::endl;std::cout << b << std::endl;std::cout << c << std::endl;
}//全缺省
void fun2(int a = 1, int b = 2, int c = 3)
{std::cout << a << std::endl;std::cout << b << std::endl;std::cout << c << std::endl;
}int main()
{fun1(1);fun1(1, 11);fun1(1, 11, 111);fun2();fun2(1);fun2(1, 11, 111);return 0;
}

请添加图片描述

  • CPP规定:半缺省必须从右向左连续缺省,不能间隔跳跃给缺省值
int fun1(int a, int b = 1, int c, int d = 1)
{return 0;
}
  • 这么干的话就过不了编译
    请添加图片描述

  • 当然,半缺省也不能不传值,毕竟叫半缺省嘛
    请添加图片描述

  • CPP规定:调用函数的时候,只能从左到右连续地传实参,不能跳越给实参
    请添加图片描述

  • CPP规定:函数声明和定义分离时,函数声明和定义不能同时给缺省参数,只能在声明时给缺省参数
    请添加图片描述

  • 如果声明有缺省参数,定义也有缺省参数,那到底应该用哪个??所以进行了这样的规定

//正确写法
int fun1(int a, int b = 0, int c = 0, int d = 0);int fun1(int a, int b, int c, int d)
{return 0;
}int main()
{//fun1(1, , 3);//fun1();return 0;
}
3.3 缺省参数的意义
  • 有时候我们写一个函数的时候,并不清楚以后需要传多大参数,这时候我们就可以用缺省参数
  • 比方说,我们初始化栈的时候,开辟空间的大小,写函数的时候其实是不知道的,我们此时加一个缺省参数来规定开辟空间的大小,一般情况下我们不需要传大小进去,默认给个16字节,除非数据量一开始就很大很大,此时就可以手动设置参数,就很方便,灵活,还能尽可能少的进行后期扩容

4 函数重载

4.1 函数重载的基本使用
  • CPP允许在同一个作用域中出现同名的函数,只需要这俩函数形参不同就行,类型不同或者个数不同,这表现出了函数的多态,使用上会更加灵活一些
  • 同样啊,了解过python之后恍然大悟啊
  • 调用的时候会根据实参自动匹配相对应的函数进行调用,老智能了!
int Add(int x, int y)
{return x + y;
}double Add(double x, double y)
{return x + y;
}double Add(double x, int y)
{return x + y;
}double Add(int x, double y)
{return 0;
}int main()
{cout << Add(1, 2) << endl;cout << Add(1.1, 2.2) << endl;cout << Add(1.1, 2) << endl;cout << Add(1, 2.2) << endl;return 0;
}
  • 同样实现一个加法函数,这样就不用担心参数类型对不上的问题了,还是非常方便的
    请添加图片描述

  • PS:仅返回值不同不能构成函数重载,因为调用的时候编译器依旧不知道你想调用哪个函数
    请添加图片描述

4.2 函数重载调用歧义
  • 以下情况下构成函数重载,但调用会出现错误,因为编译器认为你这俩函数调用起来好像都没问题
void fun()
{
}void fun(int x = 0)
{
}int main()
{fun();return 0;
}

请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/372669.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

记录一次MySql锁等待 (Lock wait timeout exceeded)异常

[TOC](记录一次MySql锁等待 (Lock wait timeout exceeded)异常) Java执行一个SQL查询未提交&#xff0c;遇到1205错误。 java.lang.Exception: ### Error updating database. Cause: java.sql.SQLException: Lock wait timeout exceeded; try restarting transactionCluster…

互联网应用主流框架整合之SpringCloud微服务治理

微服务架构理念 关于微服务的概念、理念及设计相关内容&#xff0c;并没有特别严格的边界和定义&#xff0c;某种意义上说&#xff0c;适合的就是最好的&#xff0c;在之前的文章中有过详细的阐述&#xff0c;微服务[v1.0.0][Spring生态概述]、微服务[设计与运行]、微服务[v1.…

SpringMVC--获取请求参数

1、通过的ServletAPI获取 只需要在控制器的方法的形参位置设置HTTPRequest request 类型的形参就i可以在控制器方法种使用request对象获取请求参数 RequestMapping("/servletAPI")public String getByServletAPI(HttpServletRequest request){HttpSession session…

JAVA集合Collection常用方法详解

一、Collection介绍 提到集合就不得不提一下数组&#xff0c;好多集合底层都是依赖于数组的实现。数组一旦初始化后&#xff0c;长度就确定了&#xff0c;存储数据对象不能达到动态扩展&#xff0c;其次数组存储元素不便于对数组进行添加、修改、删除操作&#xff0c;而且数组…

ubuntu关于docker部署 项目一站式教程

**假设已有ubuntu服务器并且登录root账号 ** **FinalShell中复制快捷键是 ****Ctrl+Shift+V** 卸载老版本docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker步骤 更新软件包sudo apt update sudo apt upgrade安装docker依赖sudo apt-get …

Ubuntu配置GitHub(第一次clone/push)

文章目录 1. 安装Git&检查连接2. 注册GitHub3. 生成&GitHub添加SSH3.1. 检查&删除已有id_rsa3.2. 生成SSH3.3. GitHub添加id_rsa.pub SSH3.4. 检查SSH 4. 继续开发可以参考参考 1. 安装Git&检查连接 安装 sudo apt-get install git检查SSH连接 ssh -T gitgi…

交通气象站:保障道路安全的智慧之眼

随着社会的快速发展&#xff0c;交通运输日益繁忙&#xff0c;道路安全成为公众关注的焦点。在这个背景下&#xff0c;交通气象站作为保障道路安全的重要设施&#xff0c;正发挥着越来越重要的作用。它们不仅为交通管理部门提供及时、准确的气象信息&#xff0c;也为广大驾驶员…

Mysql-01-主从搭建

一、安装Mysql 下载 https://downloads.mysql.com/archives/community/ 安装 注意顺序 tar -xvf mysql-8.0.38-1.el9.x86_64.rpm-bundle.tar rpm -ivh mysql-community-common-8.0.38-1.el9.x86_64.rpm rpm -ivh mysql-community-client-plugins-8.0.38-1.el9.x86_64.r…

【Proteus】按键的实现『⒉种』

&#x1f6a9; WRITE IN FRONT &#x1f6a9; &#x1f50e; 介绍&#xff1a;"謓泽"正在路上朝着"攻城狮"方向"前进四" &#x1f50e;&#x1f3c5; 荣誉&#xff1a;2021|2022年度博客之星物联网与嵌入式开发TOP5|TOP4、2021|2222年获评…

windows系统无法使用网络共享服务,设置防火墙入站规则解决

我们使用虚拟机的时候&#xff0c;已经配置好了网络&#xff0c;但是虚拟机和物理机就是无法通讯。可以使用关闭防火墙的方式解决这个问题&#xff0c;但是这个方法不是长久之计&#xff0c;非常不安全。那么&#xff0c;有什么其他的解决办法吗&#xff1f; 其中&#xff0c;p…

Redis基础教程(十八):Redis管道技术

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; &#x1f49d;&#x1f49…

Java基础-组件及事件处理(上)

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 目录 Swing 概述 MVC 架构 Swing 特点 控件 SWING UI 元素 JFrame SWING 容器 说明 常用方法 示例&a…

AE常用工具

目录 图形工具&#xff08;快捷键Q&#xff09; 选取工具&#xff08;快捷键V&#xff09; 抓手工具&#xff08;快捷键H或空格&#xff09; 放缩工具&#xff08;快捷键Z或滚动滑轮&#xff09; 图形工具&#xff08;快捷键Q&#xff09; 按住alt并点击&#xff0c;可切换…

Kafka系列之Kafka知识超强总结

一、Kafka简介 Kafka是什么 Kafka是一种高吞吐量的分布式发布订阅消息系统&#xff08;消息引擎系统&#xff09;&#xff0c;它可以处理消费者在网站中的所有动作流数据。 这种动作&#xff08;网页浏览&#xff0c; 搜索和其他用户的行动&#xff09;是在现代网络上的许多社…

设计模式之职责链模式(Chain of Responsibility Pattern)

1.概念 职责链模式&#xff08;Chain of Responsibility Pattern&#xff09;&#xff1a;避免将请求发送者与接收者耦合在一起&#xff0c;让多个对象都有机会接收请求&#xff0c;将这些对象连接成一条链&#xff0c;并且沿着这条链传递请求&#xff0c;直到有对象处理它为止…

「Pytorch」CopyPaste 数据增强

数据增广是提升模型泛化能力重要的手段之一&#xff0c;CopyPaste 是一种新颖的数据增强技巧&#xff0c;已经在目标检测和实例分割任务中验证了有效性。利用 CopyPaste&#xff0c;可以合成文本实例来平衡训练图像中的正负样本之间的比例。相比而言&#xff0c;传统图像旋转、…

HTML5文本标签、图像标签、超链接

一、文本样式标签 字体样式标签&#xff1a; 加粗&#xff1a;<strong>…</strong> 斜体&#xff1a; < em >…</ em> eg&#xff1a; <h3>徐志摩人物简介</h3> <p> <strong>1910</strong>年入杭州学堂<br/> &l…

java之循环练习题

思路分析&#xff1a; 代码&#xff1a; public static void main(String[] args) {int sum0;for (int i1;i<100;i){for (int j1;j<i;j) {sum j;}}System.out.println(sum);} 结果为&#xff1a;

uniapp上架到appstore遇到的问题

1、appstore在美国审核&#xff0c;需要把服务器接口的国外访问权限放开 2、登陆部分 a、审核时只能有密码登陆&#xff0c;可以通过接口响应参数将其他登陆方式暂时隐藏&#xff0c;审核成功后放开即可 b、需要有账号注销功能 3、使用照相机和相册功能时需要写清楚描述文案

制作问卷表单二维码的方法,扫码登记信息更快捷

为了更好地收集用户信息&#xff0c;现在很多场景下会使用生成二维码的方式&#xff0c;让用户可以扫码自行填写相关信息&#xff0c;从而提高获取信息的效率以及填写数据的便捷性。那么用于收集用户数据的表单二维码是如何生成的呢&#xff1f;其实方法很简单&#xff0c;现在…