初识c++(命名空间,缺省参数,函数重载)

一、命名空间

1、namespace的意义

在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全

局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名

冲突或名字污染,namespac关键字的出现就是针对这种问题的。

c语言项目类似下面程序这样的命名冲突是普遍存在的问题,C++引入namespac就是为了更好的解决

这样的问题:(因为我们设置的变量rand和stdlib.h中的rand函数冲突所以报错)

#include <stdio.h>
#include <stdlib.h>
int rand = 10;
int main()
{// 编译报错:error C2365: “rand”: 重定义;以前的定义是“函数”printf("%d\n", rand);return 0;
}

2、namespace的定义

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

即为命名空间的成员。命名空间中可以定义变量/函数/类型等。(注意{}后不跟“;”)

2、namespace本质是定义出⼀个域,这个域跟全局域各自独立,不同的域可以定义同名变量,所以下

面的rand不在冲突了。

#include<iostream>
#include <stdio.h>
#include <stdlib.h>
namespace tmp
{int rand = 0;
}
int main()
{printf("%d\n", rand);return 0;
}

3、C++中域有函数局部域,全局域,命名空间域,类域;域影响的是编译时语法查找⼀个变量/函数/

类型出处(声明或定义)的逻辑,所有有了域隔离,名字冲突就解决了。局部域和全局域除了会影响

编译查找逻辑,还会影响变量的声明周期,命名空间域和类域不影响变量声明周期。

4、namespace只能定义在全局,当然他还可以嵌套定义。

#include<iostream>
#include <stdio.h>
#include <stdlib.h>
namespace tmp
{int rand = 0;namespace tmp1{int Add(int left, int right){return left + right;}struct Node{struct Node* next;int val;};}}
int main()
{printf("%d\n", rand);return 0;
}

5、项目工程中多文件中定义的同名namespace会认为是⼀个namespace,不会冲突。

test.c文件

#include<iostream>
#include <stdio.h>
#include <stdlib.h>
#include"test.h"
namespace tmp
{int rand = 0;namespace tmp1{int Add(int left, int right){return left + right;}struct Node{struct Node* next;int val;};}}
int main()
{printf("%d\n", tmp::d);return 0;
}

test.h文件

#pragma once
namespace tmp
{int d = 0;
}

可以发现在.c文件中可以使用tmp空间中的d变量 。

6、C++标准库都放在⼀个叫std(standard)的命名空间中。

7、如果想使用全局域中的变量我们可以这么操作:

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

这样printf先打印的是3。

3、命名空间的使用

编译查找⼀个变量的声明/定义时,默认只会在局部或者全局查找,不会到命名空间里面去查找。所以

下面程序会编译报错。

namespace tmp
{int d = 0;namespace tmp1{int Add(int left, int right){return left + right;}struct Node{struct Node* next;int val;};}
}
int main()
{int a = 0;printf("%d\n", d);//未定义标识符dreturn 0;
}

所以我们要使用命名空间中定义的变量/函数,有三种方式:

1、指定命名空间访问,项目中推荐这种方式。

tmp::d

2、using将命名空间中某个成员展开,项目中经常访问的不存在冲突的成员推荐这种方式。

namespace tmp
{int d = 0;namespace tmp1{int Add(int left, int right){return left + right;}struct Node{struct Node* next;int val;};}
}
using tmp::d;
int main()
{int a = 0;printf("%d\n", d);//未定义标识符dreturn 0;
}

3、展开命名空间中全部成员,项目不推荐,冲突风险很大,日常小练习程序为了方便推荐使用。

namespace tmp
{int d = 0;namespace tmp1{int Add(int left, int right){return left + right;}struct Node{struct Node* next;int val;};}
}
using namespace tmp;
int main()
{int a = 0;printf("%d\n", d);//未定义标识符dreturn 0;
}

二、输入和输出

1、 是 Input Output Stream 的缩写,是标准的输入、输出流库,定义了标准的输入、输

出对象。

2、std::cin 是 istream 类的对象,它主要面向窄字符(narrow characters (of type char))的标准输

入流。

3、std::cout 是 ostream 类的对象,它主要面向窄字符的标准输出流。

4、std::endl 是⼀个函数,流插入输出时,相当于插入⼀个换行字符加刷新缓冲区。

5、<<是流插入运算符,>>是流提取运算符。(C语言还用这两个运算符做位运算左移/右移)

6、使用C++输入输出更方便,不需要像printf/scanf输入输出时那样,需要手动指定格式,C**++的输入**

输出可以自动识别变量类型(本质是通过函数重载实现的),其实最重要的是C++的流能更好的支持自定义

类型对象输入和输出。

#include<iostream>
#include <stdio.h>
#include <stdlib.h>
namespace tmp
{int a = 0;double b = 0.0;char c = '0';namespace tmp1{int Add(int left, int right){return left + right;}struct Node{struct Node* next;int val;};}
}
using namespace tmp;
using namespace std;
int main()
{cin >> a >> b >> c;cout << a << b << c;return 0;
}

7、cout/cin/endl等都属于C++标准库,C++标准库都放在⼀个叫std(standard)的命名空间中,所以要

通过命名空间的使用方式去用他们。

8、⼀般日常练习中我们可以using namespace std,实际项目开发中不建议using namespace std。

三、 缺省参数

1、缺省参数的定义以及规定

缺省参数是声明或定义函数时为函数的参数指定⼀个缺省值。在调用该函数时,如果没有指定实参

则采用该形参的缺省值,否则使用指定的实参,缺省参数分为全缺省和半缺省参数。(有些地方把

缺省参数也叫默认参数)。

全缺省就是全部形参给缺省值,半缺省就是部分形参给缺省值。C++规定半缺省参数必须从右往左

依次连续缺省,不能间隔跳跃给缺省值。

带缺省参数的函数调用,C++规定必须从左到右依次给实参,不能跳跃给实参。

函数声明和定义分离时,缺省参数不能在函数声明和定义中同时出现,规定必须函数声明给缺省

值。

#include <iostream>
using namespace std;
void Func(int a = 0)
{cout << a << endl;
}
int main()
{Func(); // 没有传参时,使⽤参数的默认值Func(10); // 传参时,使⽤指定的实参return 0;
}

在这里插入图片描述

2、全缺省和半缺省

#include <iostream>
using namespace std;
// 全缺省
void Func1(int a = 10, int b = 20, int c = 30)
{cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl << endl;
}
// 半缺省
void Func2(int a, int b = 10, int c = 20)
{cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl << endl;
}
int main()
{Func1();Func1(1);Func1(1, 2);Func1(1, 2, 3);Func2(100);Func2(100, 200);Func2(100, 200, 300);return 0;
}

半缺省不能这么写:

void Func2(int a = 10, int b, int c = 20)
{cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl << endl;
}
//或者
void Func2(int a = 10, int b, int c)
{cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl << endl;
}

必须严格遵守:

半缺省参数必须从右往左依次连续缺省,不能间隔跳跃给缺省值。

3、缺省参数的实际应用

我们在没有学c++之前我们实现栈的初始化以及插人时我们是这么写的:

typedef int STDataType;
typedef struct Stack
{STDataType* a;int top;int capacity;
}ST;
// 栈顶
void STInit(ST* ps, int n)
{assert(ps);ps->a = (STDataType*)malloc(n * sizeof(STDataType));ps->top = 0;ps->capacity = n;
}
void STPush(ST* ps, STDataType x)
{assert(ps);// 满了, 扩容if (ps->top == ps->capacity){printf("扩容\n");int newcapacity = ps->capacity == 0 ? 4 : ps->capacity* 2;STDataType* tmp = (STDataType*)realloc(ps->a,newcapacity * sizeof(STDataType));if (tmp == NULL){perror("realloc fail");return;}ps->a = tmp;ps->capacity = newcapacity;}ps->a[ps->top] = x;ps->top++;
}

如果我们要插入100个数据则就需要不断的扩容,有效率的损耗,但是我们在学习了缺省参数后我们可以这么写:

// 栈顶
void STInit(ST* ps, int n = 4)
{assert(ps);ps->a = (STDataType*)malloc(n * sizeof(STDataType));ps->top = 0;ps->capacity = n;
}
void STPush(ST* ps, STDataType x)
{assert(ps);// 满了, 扩容if (ps->top == ps->capacity){printf("扩容\n");int newcapacity = ps->capacity == 0 ? 4 : ps->capacity* 2;STDataType* tmp = (STDataType*)realloc(ps->a,newcapacity * sizeof(STDataType));if (tmp == NULL){perror("realloc fail");return;}ps->a = tmp;ps->capacity = newcapacity;}ps->a[ps->top] = x;ps->top++;
}
int main()
{ST a;STInit(&a, 100);//这里不传100也可以,因为规定必须从左到右依次给实参,不能跳跃给实参。刚好和缺省参数确定位置互补for (int i = 0; i < 100; i++){STPush(&a, i);}return 0;
}

这样就有效避免了重复开辟空间的问题。

四、函数重载

C++支持持在同⼀作用域中出现同名函数,但是要求这些同名函数的形参不同,可以是参数个数不同或者

类型不同。这样C++函数调用就表现出了多态行为,使用更灵活。(但是返回值不同不能作为重载条件,

因为调用时也无法区分,如果返回值和参数类型或者个数同时变化则也为重载条件)。

1、参数类型不同

#include<iostream>
using namespace std;
// 1、参数类型不同
int Add(int left, int right)
{cout << "int Add(int left, int right)" << endl;return left + right;
}
double Add(double left, double right)
{cout << "double Add(double left, double right)" << endl;return left + right;
}

2、参数个数不同

// 2、参数个数不同
void f()
{cout << "f()" << endl;
}
void f(int a)
{cout << "f(int a)" << endl;
}

特别的如果上面的用缺省参数那么在不传参数调用时就会报错,编译器不知道调用谁

// 下⾯两个函数构成重载
// f()但是调⽤时,会报错,存在歧义,编译器不知道调⽤谁
void f1()
{cout << "f()" << endl;
}
void f1(int a = 10)
{cout << "f(int a)" << endl;
}

3、参数顺序不同(实际上就是参数类型不同)

// 3、参数类型顺序不同
void f(int a, char b)
{cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{cout << "f(char b, int a)" << endl;
}
#include<iostream>
using namespace std;
// 1、参数类型不同
int Add(int left, int right)
{cout << "int Add(int left, int right)" << endl;return left + right;
}
double Add(double left, double right)
{cout << "double Add(double left, double right)" << endl;return left + right;
}
// 2、参数个数不同
void f()
{cout << "f()" << endl;
}
void f(int a)
{cout << "f(int a)" << endl;
}
void f(int a, char b)
{cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{cout << "f(char b, int a)" << endl;
}
int main()
{Add(10, 20);Add(10.1, 20.2);f();f(10);f(10, 'a');f('a', 10);return 0;
}
`#include<iostream>
using namespace std;
// 1、参数类型不同
int Add(int left, int right)
{cout << "int Add(int left, int right)" << endl;return left + right;
}
double Add(double left, double right)
{cout << "double Add(double left, double right)" << endl;return left + right;
}
// 2、参数个数不同
void f()
{cout << "f()" << endl;
}
void f(int a)
{cout << "f(int a)" << endl;
}
void f(int a, char b)
{cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{cout << "f(char b, int a)" << endl;
}
int main()
{Add(10, 20);Add(10.1, 20.2);f();f(10);f(10, 'a');f('a', 10);return 0;
}``

结果:
在这里插入图片描述

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

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

相关文章

世界商用飞机机型大全-使用Java抓取FlightAware后的答案

目录 前言 一、数据说明 1、实时航班飞机机型数据 2、网页结构分析 二、使用Java进行信息抓取 1、定义页面PageVO对象 2、爬取属性定义 3、启动信息抓取组件 三、成果分析 1、商业飞行的飞机机型的种类 2、飞机种类排名前十名 3、航班数排名后十名 4、看中国国产大飞…

你真的会信息收集嘛,4k字渗透测试信息收集10大技巧

前言 在渗透测试中&#xff0c;信息收集是非常关键的一步&#xff0c;它为后续的漏洞发现和利用提供了重要的基础。以下是非常详细的信息收集方式&#xff1a; 一、被动信息收集 被动信息收集是指在不与目标系统直接交互的情况下&#xff0c;通过公开渠道获取目标系统的相关…

基于51单片机的四路抢答器Protues仿真设计

一、设计背景 近年来随着科技的飞速发展&#xff0c;单片机的应用正在不断的走向深入。本文阐述了基于51单片机的八路抢答器设计。本设计中&#xff0c;51单片机充当了核心控制器的角色&#xff0c;通过IO口与各个功能模块相连接。按键模块负责检测参与者的抢答动作&#xff0c…

力扣-贪心算法4

406.根据身高重建队列 406. 根据身高重建队列 题目 假设有打乱顺序的一群人站成一个队列&#xff0c;数组 people 表示队列中一些人的属性&#xff08;不一定按顺序&#xff09;。每个 people[i] [hi, ki] 表示第 i 个人的身高为 hi &#xff0c;前面 正好 有 ki 个身高大于或…

MyBatis的简介与使用

Mybatis JDBC操作数据库的缺点 存在大量的冗余代码。手工创建 Connection、Statement 等&#xff0c;效率低下。手工将结果集封装成实体对象。查询效率低&#xff0c;没有对数据访问进行优化。 Mybatis框架 简介 MyBatis 本是 apache 的一个开源项目 iBatis, 2010年这个项目由…

imx6ull/linux应用编程学习(14) MQTT基础知识

什么是mqtt&#xff1f; 与HTTP 协议一样&#xff0c; MQTT 协议也是应用层协议&#xff0c;工作在 TCP/IP 四层模型中的最上层&#xff08;应用层&#xff09;&#xff0c;构建于 TCP/IP协议上。 MQTT 最大优点在于&#xff0c;可以以极少的代码和有限的带宽&#xff0c;为连接…

网络资源模板--Android Studio 外卖点餐App

目录 一、项目演示 二、项目测试环境 三、项目详情 四、完整的项目源码 原创外卖点餐&#xff1a;基于Android studio 实现外卖(点)订餐系统 非原创奶茶点餐&#xff1a;网络资源模板--基于 Android Studio 实现的奶茶点餐App报告 一、项目演示 网络资源模板--基于Android …

在AvaotaA1全志T527开发板上使用AvaotaOS 部署 Docker 服务

Docker 是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中&#xff0c;然后发布到任何流行的 Linux或Windows操作系统的机器上&#xff0c;也可以实现虚拟化。容器是完全使用沙箱机制&#xff0c;相互之间不会有任何接口。 准备…

信息技术课上的纪律秘诀:营造有序学习环境

信息技术课是学生们探索数字世界的乐园&#xff0c;但同时也是课堂纪律管理的挑战场。电脑、网络、游戏等元素可能分散学生的注意力&#xff0c;影响学习效果。本文将分享一些有效的策略&#xff0c;帮助教师在信息技术课上维持课堂纪律&#xff0c;确保教学活动顺利进行。 制…

几何建模基础-样条曲线和样条曲面介绍

1.概念介绍 1.1 样条曲线的来源 样条的英语单词spline来源于可变形的样条工具&#xff0c;那是一种在造船和工程制图时用来画出光滑形状的工具&#xff1a;富有弹性的均匀细木条/金属条/有机玻璃条&#xff0c;它围绕着按指定位置放置的重物或者压铁做弹性弯曲&#xff0c;以…

基于LangChain的RAG开发教程(二)

v1.0官方文档&#xff1a;https://python.langchain.com/v0.1/docs/get_started/introduction/ 最新文档&#xff1a;https://python.langchain.com/v0.2/docs/introduction/ LangChain是一个能够利用大语言模型&#xff08;LLM&#xff0c;Large Language Model&#xff09;能…

植物大战僵尸融合嫁接版 MAC 版本下载安装详细教程

继植物大战僵尸杂交版火了之后&#xff0c;PVZ改版可谓是百花齐放&#xff0c;最近又有一个非常好玩的模式被开发出来了&#xff0c;他们称为《植物大战僵尸融合嫁接版》 该版本并没有对植物卡牌做改动&#xff0c;而是可以将任意两种植物叠放到一起进行融合&#xff0c;产生新…

思路打开!腾讯造了10亿个角色,驱动数据合成!7B模型效果打爆了

世界由形形色色的角色构成&#xff0c;每个角色都拥有独特的知识、经验、兴趣、个性和职业&#xff0c;他们共同制造了丰富多元的知识与文化。 所谓术业有专攻&#xff0c;比如AI科学家专注于构建LLMs,医务工作者们共建庞大的医学知识库&#xff0c;数学家们则偏爱数学公式与定…

数据分析与挖掘实战案例-电商产品评论数据情感分析

数据分析与挖掘实战案例-电商产品评论数据情感分析 文章目录 数据分析与挖掘实战案例-电商产品评论数据情感分析1. 背景与挖掘目标2. 分析方法与过程2.1 评论预处理1. 评论去重2. 数据清洗 2.2 评论分词1. 分词、词性标注、去除停用词2. 提取含名词的评论3. 绘制词云查看分词效…

昇思25天学习打卡营第12天 | LLM原理和实践:MindNLP ChatGLM-6B StreamChat

1. MindNLP ChatGLM-6B StreamChat 本案例基于MindNLP和ChatGLM-6B实现一个聊天应用。 ChatGLM-6B应该是国内第一个发布的可以在消费级显卡上进行推理部署的国产开源大模型&#xff0c;2023年3月就发布了。我在23年6月份的时候就在自己的笔记本电脑上部署测试过&#xff0c;当…

UI自动化测试框架:PO 模式+数据驱动(超详细)

1. PO 设计模式简介 什么是 PO 模式&#xff1f; PO&#xff08;PageObject&#xff09;设计模式将某个页面的所有元素对象定位和对元素对象的操作封装成一个 Page 类&#xff0c;并以页面为单位来写测试用例&#xff0c;实现页面对象和测试用例的分离。 PO 模式的设计思想与…

Python学习中进行条件判断(if, else, elif)

条件判断是编程中必不可少的一部分&#xff0c;它让程序可以根据不同的条件执行不同的代码块。在Python中&#xff0c;主要使用if、elif和else语句来实现条件判断。 基本语法 在Python中&#xff0c;条件判断的基本语法如下&#xff1a; if condition:# 当condition为True时…

NCCL 中的一些辅助debug 知识点

1&#xff0c;调试nccl 启动kernel的方法 ncclLaunchKernel cuLaunchKernelEx ncclStrongStreamLaunchKernel cudaLaunchKernel ncclLaunchOneRank cudaLaunchKernel 在 nccl lib 中&#xff0c;不存在使用<<<grid, block,,>>> 这种类似方式启…

算法题型归类整理及同类题型解法思路总结(持续更新)

1、最优路线 通用思路 1、递归 #案例1-最优路测路线 题目描述 评估一个网络的信号质量&#xff0c;其中一个做法是将网络划分为栅格&#xff0c;然后对每个栅格的信号质量计算。 路测的时候&#xff0c;希望选择一条信号最好的路线&#xff08;彼此相连的栅格集合&#x…

12种增强Python代码的函数式编程技术

前言 什么是函数式编程&#xff1f; 一句话总结&#xff1a;函数式编程(functional programming)是一种编程范式&#xff0c;之外还有面向对象&#xff08;OOP&#xff09;、面向过程、逻辑式编程等。 函数式编程是一种高度抽象的编程范式&#xff0c;它倡导使用纯函数&#x…