初始C++(一)

news2024/11/24 1:33:32

文章目录

  • 前言
    • cout的用法
    • cin的用法
    • endl的用法
  • 一.命名空间
    • 1.:: (域作用限定符)
    • 2.命名空间定义
    • 3.命名空间的使用
    • 4.命名空间的一些其它使用
    • 5.全局展开
    • 6.部分展开
    • 二.缺省参数
      • 2.1全缺省
      • 2.2半缺省

前言

既然这篇文章叫初始C++,看我文章的应该和我一样,基本是个小白,对C++一窍不通。

所以这里对C++语法做一点点小的补充:

cout的用法

cout就相当于C语言的printf。如果你要输入什么值的话可以这样写:

cout << "hello world";
//加上一个<<,这叫流插入运算符
int i = 0;
cout << i;

和printf不同的是,printf函数在输入什么值时要表明输出值的类型:

printf("%s", "hello world");
int i = 0;
printf("%d", i);

cout具体为什么要这样写,可以先不用管,可以想象成一个叫"hello world"的字符串像水一样流到cout里面去,cout就是那个可以显示的黑框框。

cout还可以这样写:

int i = 10;
cout << "hello world" << i;

输出就是:
在这里插入图片描述

这就相当于C语言的:

int i = 0;
printf("%s%d", "hello world", i);

cin的用法

cin就像C语言的scanf函数。

int i = 0;
cin >> i;//>>是流提取运算符

这就像C语言的:

int i = 0;
scanf("%d", i);

特点和cout也差不多。可以不用考虑输入的变量是什么类型的。

endl的用法

endl就是C语言的换行符。

cout << "hello world" << endl;

这就相当于C语言中的:

printf("hello world\n");

上面这三个东西的用法暂且先理解这么多就行了。

一.命名空间

1.:: (域作用限定符)

在我们学习C语言的时候常常会接触域这个概念:全局域/局部域。向下面这个代码:

int a = 0;

void test1()
{
	int a = 1;
	printf("%d",a);
}

int main()
{
	test1();
	return 0;
}

这个printf打印的是什么呢?答案应该是1,虽然a这个变量在全局和局部都有定义,但这并不冲突。在test1这个函数里使用printf打印变量a时,局部变量的优先级会大于全局变量,也就是说在使用a这个变量时会优先在当前这个局部寻找a,如果找到了就打印,如果找不到就去全局域去找。

但是现在我有一个想法,局部和全局我虽然都定义了变量a,但是我想打印那个全局变量的变量a。C++在这里有一个方法,就是在变量前加上一个运算符::

int a = 0;

void test1()
{
	int a = 1;
	printf("%d",::a);
}

int main()
{
	test1();
	return 0;
}

在这里插入图片描述

现在printf打印的就是那个全局变量。

正常情况下,就是不加这个运算符时,优先会在局部域寻找。但是加上::这个运算符之后,它会到::左边那个域去找,看上面那个printf函数,发现**::左边什么都没有,也就是空,而空就代表全局域**,也就是说加上这个运算符的话,它会优先在全局域去寻找。自然结果打印的就是0.

2.命名空间定义

通过上面的研究,可以发现虽然有不同的域,但是在不同域里可以有相同的变量。现在有一个问题,在一个域里可不可以有相同的变量呢?

比如说在一个项目里,小A和小B在一起做一个项目,因为他们俩工作时不在一起,对方写的代码也不知道。可能就出现一种情况,小A和小B定义了一个相同名字的结构体变量。在他们的代码没有合在一起时,一点问题都没有,但是他们各自写的代码合在一起时发现出问题了,变量名字发生了重定义,而且更严重的是,这俩人都是个愣头青,都不想把自己的变量名改掉。

正是因为会出现这种在一个域里同时出现两种一样的变量的情况,所以C++里引入了命名空间的概念。

我先把小A和小B的代码分别写出来:

//小A
struct node
{
	struct node* next;
	int val;
};
//小B
struct node
{
	struct node* next;
	struct node* prev;
	int val;
};

这两个写的代码在自己电脑上运行没啥问题,但是合在一起的话:
在这里插入图片描述

就会有类型重定义的错误。

接下来,我们在小A和小B定义的变量外面加上这么一个东西:

namespace _A
{
	struct node
	{
		struct node* next;
		int val;
	};
}
namespace _B
{
	struct node
	{
		struct node* next;
		struct node* prev;
		int val;
	};
}

namespace 名称:这就是所谓的命名空间。命名空间其实就是一个域,是命名空间域,和全局域,局部域不同的是,它不会影响域里面变量的生命周期,只会影响里面变量的使用

要知道一个变量放在全局域里它的生命周期就是这个程序的生命周期,如果放在局部域中,这个变量的生命周期就是和它所在的那个区域有关了。所以和命名空间域不同的是,全局域和局部域会改变变量的生命周期,同时也会改变变量的使用
命名空间是在编译期间影响了查找的规则。

3.命名空间的使用

既然我们把这些变量都放在了各自的命名空间中,我们该如何使用呢?向下面这样写可以吗?

#include "A.h"
#include "B.h"

int main()
{
	struct node n;
	return 0;
}

答案当然不行,因为我说过,变量在使用时会优先在局部域去找,如果没找到就去全局域去找,如果全局域没有就会报错。编译器它默认不会到命名空间域里去寻找的。如果想用,就该用刚刚接触过的一个运算符::。这个运算符如果左边是空的话,说明优先去局部域里找,如果我们在左边加上一点东西:

#include "A.h"
#include "B.h"

int main()
{
	struct _A::node n;
	return 0;
}

这就说明我们要去_A这个域里面去找。而_A就是最开始小A自己定义的命名空间域。

现在我们就很好的解决在一个域里定义多个相同变量的问题了。

这里要注意一个细节_A::是加在node的前面,而不是struct的前面。因为struct只是一个结构体关键字,两个变量真正不同的是后面的node。

4.命名空间的一些其它使用

上面把命名空间的大概讲完了,但是小A,小B两个人心有灵犀,不小心把命名空间的名字也写成一样的了,这时候也没什么好的方法了,只能让他俩打一架,谁赢谁改名字~

在不同文件里定义的命名空间名字是一样的,编译器会自动把他们变成一个命名空间

命名空间是支持嵌套使用的。

像下面这个代码:

namespace _A
{
	struct node
	{
		struct node* next;
		int val;
	};
	namespace _AA
	{
		int min = 0;
	}
}

此时我们该如何访问这个变量min呢?可以这样写:

#include "A.h"
#include "B.h"

int main()
{
	//struct _A::node n;
	printf("%d", _A::_AA::min);
	return 0;
}

这个变量会先去_A这个命名空间里去找,找到之后再去_AA这个命名空间里去找,最终找到了变量min的定义。

这里不要写反了,代码从左到右开始寻找。不要写成:
printf(“%d”, _AA::_A::min);

5.全局展开

后来,小B因为没打过小A,离开了公司所以现在是小A一个人在做项目,但是小A的一些变量还放在命名空间中,又怕以后有人和他命名的变量又相同,所以他不想把自己定义的命名空间删掉,但是平时在用的时候,又非常的麻烦。所以在C++中又有一个叫全局展开的东西:

using namespace _A;

这里的_A就是你命名空间的名字。而这个全局展开的意思就是,

如果没有这个代码,在使用变量时只会到局部域,全局域去找,默认不会到命名空间域里去寻找。而加上这行代码的话,不仅会到全局域和局部域去找,还会跑到命名空间域里去找
所以说,你在有这行代码后,之后用到你命名空间里的变量时,该怎么写就怎么写,不用加其它东西。

虽然事情变简单了,但是不推荐这样写,命名空间域本来就是防止重定义而加的东西,你直接全局展开,这不就是做了很多无用功吗?所以一般你在做项目时,这句话最好不要写。但是平时在做练习,做题目的时候,这个有没有也无所谓,因为此时的代码量不会很大,想这些命名重定义的情况也基本不会发生。

一些注意事项:

  1. 全局展开的代码后面记得把分号带上,不要忘记了。
  2. 全局展开不要理解成把命名空间域直接删掉,而是在使用一些变量时多了一条寻找的路子,如果你在展开后还想在前面加上_A::这类的运算符也是没问题的。

不仅小A和小B两个人可能会发生命名冲突。你写的代码还有可能和标准库的命名发生冲突。所以C++使用的标准库也有一个自己的命名空间,名字叫做:std.

所以说我们平时可能会看到这个样子的代码:

#include <iostream>
int main()
{
	std::cout << "hello word" << std::endl;
	return 0;
}

这是因为cout,endl这俩东西本身是放在std这个命名空间里的,所以我们在使用的时候,前面要加上std::。

当然我们还会看到下面这种写法:

#include <iostream>
using namespace std;
int main()
{
	cout << "hello word" << endl;
	return 0;
}

这就是上面提到的全局展开,因为cout,endl一般会用很多次,每次前面加上std::会很麻烦,所以这里直接全局展开。

相同道理,全局展开std不推荐,我们平时在做练习,写一下小东西的时候展开就行了,在写一些大型项目时还是不要这样写了,C++库把代码放到命名空间中,就是为了上一层保险,你如果直接把这层保险直接删掉,还是挺不好的。

6.部分展开

有时候觉得全局展开有点太过分了,但是不展开,在写代码时又有点麻烦,有没有什么比较好的办法呢?当然,我们可以在写之前部分展开,就是把那些常用的展开,不常用的就正常去写。比如向下面这样:

#include <iostream>
//using namespace std;
using std::cout;
using std::endl;

int main()
{
	int i = 0;
	cout << "hello word" << endl;
	std::cin >> i;
	return 0;
}

这里就把常用的cout,endl展开就行,而没有展开的则正常去用。

二.缺省参数

2.1全缺省

我们平时再写函数时,可能会这样写:

#include <iostream>
using namespace std;

void test(int i)
{
	cout << i << endl;
}

int main()
{
	test(1);
	return 0;
}

就是test这个函数在使用时,需要传递一个参数,但如果我们不知到传啥或者忘记传的时候,此时系统就该报错了,所以C++在这里为我们新加了一个概念:缺省参数。现在我们可以把函数写成这样:

void test(int i = 10)
{
	cout << i << endl;
}

int main()
{
	test(1);
	test();
	return 0;
}

函数变量在写的时候,类似初始化。这样写有什么用途呢?首先看看没传参数和传参数时打印的结果是什么:
在这里插入图片描述

这说明了一个啥道理呢?在你传参数后,你传什么参数就打印什么参数,但是你需要传参时却没有传参,它打印的就是一个函数那里定义的值:10

这个10可以理解成一个备胎,在不需要你的时候嘞,你就是个空气。又因为函数test必须要有一个参数,所以在你没有传参的时候,这个备胎就可以排上用场了。

上面函数的备胎只有一个,但是备胎也可以有多个,海王嘛,多养了点鱼。

void test2(int a = 10, int b = 20, int c = 30)
{
	cout << "a:" << a << endl;
	cout << "b:" << b << endl;
	cout << "c:" << c << endl;
	cout << endl;
}

这时候我们在使用test2这个函数时也可以多样化传参:

void test2(int a = 10, int b = 20, int c = 30)
{
	cout << "a:" << a << endl;
	cout << "b:" << b << endl;
	cout << "c:" << c << endl;
	cout << endl;
}

int main()
{
	test2(1,2,3);
	test2(1, 2);
	test2(1);
	test2();
}

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

3个备胎,随便用哪个都是可以的。但是有一点要注意:使用缺省值,必须从右往左连续使用。意思就是不能向下面这样跳着传参:

	test2(, 2, );
	test2(, , 3);

而且在传参时顺序和函数那一块形参的顺序是相互对应的。就是说test2(1, 2)传给的是a,b两个参数而不是a,c两个参数。

2.2半缺省

和使用缺省值一样,函数那部分,也可以不用把所有备胎带在身上。比如这样写:

void test3(int a, int b = 20, int c = 30)
{
	cout << "a:" << a << endl;
	cout << "b:" << b << endl;
	cout << "c:" << c << endl;
	cout << endl;
}

void test4(int a, int b, int c = 30)
{
	cout << "a:" << a << endl;
	cout << "b:" << b << endl;
	cout << "c:" << c << endl;
	cout << endl;
}

和使用缺省值一样,半缺省也是要从右到左连续缺省。你不能这样写:

void test3(int a = 10, int b, int c = 30)
{
	cout << "a:" << a << endl;
	cout << "b:" << b << endl;
	cout << "c:" << c << endl;
	cout << endl;
}

void test4(int a = 10, int b = 20, int c)
{
	cout << "a:" << a << endl;
	cout << "b:" << b << endl;
	cout << "c:" << c << endl;
	cout << endl;
}

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

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

相关文章

React-Router6路由相关二(路由传参、编程式路由导航、路由相关hooks)(八)

系列文章目录 第一章&#xff1a;React基础知识&#xff08;React基本使用、JSX语法、React模块化与组件化&#xff09;&#xff08;一&#xff09; 第二章&#xff1a;React基础知识&#xff08;组件实例三大核心属性state、props、refs&#xff09;&#xff08;二&#xff0…

ffmpeg vs2017录制vp9格式的桌面视频

ffmpeg本身不支持vp8,vp9&#xff1b;若要支持&#xff0c;则需要自己事先编译好vpx库&#xff0c;然后在ffmpeg中显式支持vpx库。 windows下采用mingw编译器编译vpx&#xff1b;本人采取的是MSYS2&#xff0c;并且本人编译vpx和ffmpeg时&#xff0c;编译的都是静态库&#xf…

【云原生】在Ubuntu18/20上部署Kubernetes/k8s集群详细教程——亲测可用!!网上其他教程均有问题!

在Ubuntu18/20上部署Kubernetes/k8s详细教程一、设置Docker二、安装Kubernetes第 1 步&#xff1a;添加Kubernetes签名密钥第 2 步&#xff1a;添加软件存储库第 3 步&#xff1a;Kubernetes 安装工具三、部署 Kubernetes步骤 1&#xff1a;准备 Kubernetes 部署步骤 2&#xf…

怎么找回笔记本的数据?笔记本数据恢复,6个教程

“我不小心删除了笔记本电脑里面的重要数据&#xff0c;请问被误删的数据还可以恢复吗&#xff1f;如果可以恢复&#xff0c;我应该怎么恢复笔记本里面的数据&#xff1f;” 很多人在使用笔记本电脑的时候&#xff0c;经常误删一些数据&#xff0c;有时是工作文档&#xff0c;…

我是如何将同事的代码改成DDD风格的

DDD是领域驱动设计的简写。前段时间听群友说行业里少有DDD的代码案例&#xff0c;进而对DDD没有一个感性的认识。我想这是行业里普遍存在的现象吧。所以&#xff0c;就有了写此文的想法。文章标题说的是“同事的代码”&#xff0c;其实只是为了让此文更具传播&#xff0c;没别的…

组件的生命周期、vue2中使用axios、插槽

目录 一、组件的生命周期 1、什么是组件的生命周期 2、生命周期函数 3、生命周期的阶段划分 4、钩子函数 5、keep-alive组件 6、生命周期函数&#xff1a; 二、vue2中使用axios 1、axios&#xff1a;是一个基于Promise的网络请求库。既可以在node.js&#xff08;服务器…

【MySQL】1. 了解数据库以及MySQL安装

了解数据库和SQL什么是数据库为什么使用数据库MySQL下载,安装,配置客户端连接MySQL方法一方法二SQLSQL分类SQL的基本规则命名规则最后大家好, 我是路不停_。 上学期学校学习了MySQL之后,课后也没有做很多总结,加上课时紧凑,后续考试也是考前草草备考了一下. 最近读了本MySQL必知…

C 程序设计教程(03)—— C 语言的数据类型(一):基本数据类型

C 程序设计教程&#xff08;03&#xff09;—— C 语言的数据类型&#xff08;一&#xff09;&#xff1a;基本数据类型 一、数据类型简介 C 语言提供了丰富的数据类型&#xff0c;每一个常量和变量必须属于某一种数据类型。C 语言中的数据类型如下&#xff1a; &#xff08…

基础数学(八)——期末考试复习

文章目录考试要求考试内容简单复习插值拟合和回归数值积分直接法迭代法非线性方程求根微分方程数值解去年考题第一题&#xff0c;插值&#xff08;12分&#xff09;第二题&#xff0c;回归和拟合第三题&#xff0c;数值积分第四题&#xff0c;线性方程组求解第五题&#xff0c;…

MGRE实验配置(华为)

华为ENSP的MGRE实验&#xff1a; 建立好拓扑图 之后就是对各个路由器的配置&#xff1a; R2配置&#xff1a; int s3/0/0 link-protocol hdlc 更改接口为hdlc认证 ip address 12.1.1.2 24 int lo0 ip add 2.2.2.2 24 int s3/0/1 [r2-Serial3/0/1]ip address 23.1.1.2 24 [r2-Se…

【ML】 基本概念

ML 基本概念1. different types of functions2. how to find the function - training data3. unseen during training4. Back to ML Framework4.1 Step1: function with unknown4.2 Step2: define loss from training data4.3 step3: optimization4.4 其他4.4.1 Sigmoid → Re…

基础算法(五)——双指针算法

双指针算法 介绍 双指针算法分为两大类&#xff1a; 两个指针指向两个不同序列&#xff0c;用两个指针维护某一种逻辑&#xff0c;例如归并排序 两个指针指向一个序列&#xff0c;即用两个指针维护一段区间&#xff0c;例如快排 核心思想&#xff1a; 若能证明出题目存在…

Linux工具学习之【vim】

✨个人主页&#xff1a; Yohifo &#x1f389;所属专栏&#xff1a; Linux学习之旅 &#x1f38a;每篇一句&#xff1a; 图片来源 &#x1f383;操作环境&#xff1a; CentOS 7.6 阿里云远程服务器 Whatever is worth doing is worth doing well. 任何值得去做的事情&#xff0…

springboot垃圾分类查询管理系统

1.介绍 垃圾分类查询管理系统&#xff0c;对不懂的垃圾进行查询进行分类并可以预约上门回收垃圾。 让用户自己分类垃圾&#xff0c; 按国家标准自己分类&#xff0c; 然后在网上提交订单&#xff0c; 专门有人负责回收&#xff0c; 统一回收到垃圾处理站&#xff0c; 然后工人…

Renesas 3 --烧写

1.烧录Boot程序 1.1&#xff0c;连接RESET_OUT, TOOL0, GND到板子。 1.2&#xff0c;上电后烧录器上指示灯亮&#xff08;假如不亮&#xff0c;重新上电烧录器&#xff09; 1.3&#xff0c;用Renesas flash programmer来烧写软件&#xff08;新建项目&#xff0c;然后保存项目…

RAW怎么转为JPG?这些转换技巧值得收藏

相信大多数的人&#xff0c;出去外面游玩时都喜欢使用相机来拍照&#xff0c;但是大多数相机拍出来的照片都是RAW格式&#xff0c;图片传到电脑时&#xff0c;会因为格式的不兼容而导致无法查看&#xff0c;这个时候我们就需要把图片的格式进行转换&#xff0c;例如我们将其转换…

Day850.GuardedSuspension模式 -Java 性能调优实战

GuardedSuspension模式 Hi&#xff0c;我是阿昌&#xff0c;今天学习记录的是关于GuardedSuspension模式的内容。 小灰工作中遇到一个问题&#xff0c;开发了一个 Web 项目&#xff1a;Web 版的文件浏览器&#xff0c;通过它用户可以在浏览器里查看服务器上的目录和文件。 这…

(原创)Flow数据流的使用

前言 这篇文章主要介绍Flow的一些基础使用方法 同时介绍如何用Flow请求网络数据 下面开始&#xff01; 什么是Flow Flow翻译过来&#xff0c;是“流”的意思 举例说明&#xff0c;在大自然中&#xff0c;常见的如水流 是从高往低流动的 那么在计算机世界里&#xff0c;所谓的…

loss盘点: asl loss (Asymmetric Loss) 代码解析详细版

1. BCE公式部分 可以简单浏览下这篇博客的文章&#xff1a; https://blog.csdn.net/qq_14845119/article/details/114121003 这是多分类 经典 BCELossBCELossBCELoss 公式 L−yL−(1−y)L−L -y L_{} - (1-y) L_{-} L−yL​−(1−y)L−​ 其中&#xff0c;L/−L_{/-}L/−​…

Docker保姆级学习教程

文章目录1、什么是Docker1.1、容器技术1.2、容器与虚拟机比较1.3、Docker特点1、更高效的利用系统资源2、更快速的启动时间3、一致的运行环境4、持续支付和部署5、更轻松的迁移6、更轻松的维护和扩展2、Docker组件学习2.1、Docker客户端和服务器2.2、Docker镜像2.3、Registry&a…