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

news2024/10/3 8:27:48

目录

      • 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 once

namespace 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.coloradmin.cn/o/1912317.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

产品原型设计:从概念到实现的完整指南

如果你是一位产品经理&#xff0c;那么你一定会和原型图打交道&#xff0c;产品原型是产品设计方案和底层逻辑的可视化表达&#xff0c;需要完整清晰地表达出产品目的及需求&#xff0c;在整个产品创造的过程中发挥着不可或缺的作用。而对于一些刚入行的产品经理来说&#xff0…

Docker学习笔记(三)Dockerfile

一、什么是Dockerfile Dockerfile 是一个用于自动化构建 Docker 镜像的文本文件&#xff0c;其中包含了从一个基础镜像开始&#xff0c;到最终形成所需定制镜像的所有指令集。这个文件中的每一条指令都对应着构建镜像过程中的一个步骤或一层&#xff0c;指导 Docker 如何安装软…

tk 文本生成器

import random import tkinter as tk import ttkbootstrap as ttk from tkinter import messagebox import pyperclipdef wenben_run():def generate_text(original_text, length):# 去掉原始文本中的换行符和空格original_text original_text.replace(\n, )original_text or…

【文档智能】LACE:帮你自动生成文档布局的方法浅尝

前言 往期很多文章都介绍了【文档智能】上布局识别&#xff08;版式分析&#xff09;的技术思路&#xff0c;版式分析是通过对文档版式进行布局识别&#xff0c;识别文档中的元素类型的过程。这次来看看一个有趣的思路&#xff0c;通过已有的元素类型&#xff0c;来生成可控的…

解决安卓tv 蓝牙遥控器配对后输入法弹不出来的问题

t972在蓝牙配对后,自带的LatinIME 输入法会出现弹不出来的现象。 经过分析,主要为蓝牙的kl 文件适配存在问题。解决如下: 1.新建 kl文件Vendor_2b54_Product_1600.kl 放到 /vendor/usr/keylayout/下 内容: #for bl remote add by jason 20240709 key 113 VOLUME_MUTE …

【RAG KG】GraphRAG开源:查询聚焦摘要的图RAG方法

前言 传统的 RAG 方法在处理针对整个文本语料库的全局性问题时存在不足&#xff0c;例如查询&#xff1a;“数据中的前 5 个主题是什么&#xff1f;” 对于此类问题&#xff0c;是因为这类问题本质上是查询聚焦的摘要&#xff08;Query-Focused Summarization, QFS&#xff09…

FL Studio 24.1.1.4234 (Windows) / 24.1.1.3884 (Mac OS X)

FL Studio 24.1.1.4234 (Windows) / 24.1.1.3884 (Mac OS X) 主页多媒体音频编辑FL Studio 24.1.1.4234 (Windows) / 24.1.1.3884... FL Studio 图标 FL Studio&#xff08;前身为 FruityLoops&#xff09;是一款功能强大的音乐制作环境或数字音频工作站&#xff08;DAW&#x…

用于视频生成的扩散模型

学习自https://lilianweng.github.io/posts/2024-04-12-diffusion-video/ 文章目录 3D UNet和DiTVDMImagen VideoSora 调整图像模型生成视频Make-A-Video&#xff08;对视频数据微调&#xff09;Tune-A-VideoGen-1视频 LDMSVD稳定视频扩散 免训练Text2Video-ZeroControlVideo 参…

鸿蒙开发:Universal Keystore Kit(密钥管理服务)【密钥协商(ArkTS)】

密钥协商(ArkTS) 以协商密钥类型为X25519 256&#xff0c;并密钥仅在HUKS内使用为例&#xff0c;完成密钥协商。 开发步骤 生成密钥 设备A、设备B各自生成一个非对称密钥&#xff0c;具体请参考[密钥生成]或[密钥导入]。 密钥生成时&#xff0c;可指定参数HUKS_TAG_DERIVE…

STL--栈(stack)

stack 栈是一种只在一端(栈顶)进行数据插入(入栈)和删除(出栈)的数据结构,它满足后进先出(LIFO)的特性。 使用push(入栈)将数据放入stack,使用pop(出栈)将元素从容器中移除。 使用stack,必须包含头文件: #include<stack>在头文件中,class stack定义如下: namespace std…

前端面试题32(浅谈前端热部署)

前端热部署&#xff08;Hot Deployment&#xff09;是指在开发过程中&#xff0c;当开发者修改了前端代码后&#xff0c;这些修改能够立即反映到正在运行的前端应用上&#xff0c;而无需重新启动整个应用或服务器。这种能力极大地提高了开发效率&#xff0c;因为开发者可以即时…

算法学习笔记(8.2)-动态规划入门进阶

目录 问题判断: 问题求解步骤&#xff1a; 图例&#xff1a; 解析&#xff1a; 方法一&#xff1a;暴力搜索 实现代码如下所示&#xff1a; 解析&#xff1a; 方法二&#xff1a;记忆化搜索 代码示例&#xff1a; 解析&#xff1a; 方法三&#xff1a;动态规划 空间…

如何在JetBrains中写Codeforce?

目录 前言 正文 leetcode 个人喜好 参考资料 具体操作步骤 尾声 &#x1f52d; Hi,I’m Pleasure1234&#x1f331; I’m currently learning Vue.js,SpringBoot,Computer Security and so on.&#x1f46f; I’m studying in University of Nottingham Ningbo China&#x1f4…

硬件:CPU和GPU

一、CPU与GPU 二、提升CPU利用率&#xff1a;计组学过的 1、超线程一般是给不一样的任务的计算使用&#xff0c;而非在计算密集型工作中 2、Cpu一次可以计算一个线程&#xff0c;而gpu有多少个绿点一次就能计算多少个线程&#xff0c;Gpu比cpu快是因为gpu它的核多&#xff0c;…

如何在 PostgreSQL 中确保数据的异地备份安全性?

文章目录 一、备份策略1. 全量备份与增量备份相结合2. 定义合理的备份周期3. 选择合适的备份时间 二、加密备份数据1. 使用 PostgreSQL 的内置加密功能2. 使用第三方加密工具 三、安全的传输方式1. SSH 隧道2. SFTP3. VPN 连接 四、异地存储的安全性1. 云存储服务2. 内部存储设…

RK3568------Openharmony 4.0-Release WIFI/BT模组适配

RK3568------Openharmony 4.0-Release WIFI/BT模组(ap6236)适配 文章目录 RK3568------Openharmony 4.0-Release WIFI/BT模组(ap6236)适配前言一、驱动移植二、设备树配置三 、内核配置四、遇到的问题五、效果展示总结 前言 随着RK3568适配工作的推进&#xff0c;整体适配工作…

泛微E9开发 控制日期浏览按钮的可选日期范围

控制日期浏览按钮的可选日期范围 1、需求说明2、实现方法3、扩展知识点控制日期浏览按钮的可选日期范围格式参数说明演示 1、需求说明 控制日期浏览按钮的可选日期范围为2024/07/01~2024/07/31&#xff0c;如下图所示 2. 控制日期浏览按钮的可选日期范围在当前时间的前一周~当…

【基于R语言群体遗传学】-13-群体差异量化-Fst

在前几篇博客中&#xff0c;我们深度学习讨论了适应性进化的问题&#xff0c;从本篇博客开始&#xff0c;我们关注群体差异的问题&#xff0c;建议大家可以先看之前的博客&#xff1a;群体遗传学_tRNA做科研的博客-CSDN博客 一些新名词 Meta-population:An interconnected gro…

4:表单和通用视图

表单和通用视图 1、编写一个简单的表单&#xff08;1&#xff09;更新polls/detail.html文件 使其包含一个html < form > 元素&#xff08;2&#xff09;创建一个Django视图来处理提交的数据&#xff08;3&#xff09;当有人对 Question 进行投票后&#xff0c;vote()视图…

Proteus + Keil单片机仿真教程(五)多位LED数码管的静态显示

Proteus + Keil单片机仿真教程(五)多位LED数码管 上一章节讲解了单个数码管的静态和动态显示,这一章节将对多个数码管的静态显示进行学习,本章节主要难点: 1.锁存器的理解和使用; 2.多个数码管的接线封装方式; 3.Proteus 快速接头的使用。 第一个多位数码管示例 元件…