🥲c++基础 ——输入输出和命名空间
<作者:丘比特,大梦想,日期:2023.4.8>
常用输入输出头文件
具体:
cstdio
因为c++的库是兼容c语言的库函数的,所以对应的C语言库也可以进行引用头文件,只不过需要注意的是,在使用的时候要注意在前边加上c去掉.h
iostream
常用的输入流cin和cout,大部分数据类型都可以直接输入输出,只不过速度相较于scanf和printf较慢
%c会读空格,但是cin会过滤空格因为遇到空格就停。值得注意的点:
保留几位小数输出??(尽量使用c++方法)。
(得写好多好多)
using namespace std;的意思??
(就是在std这个内存空间中进行调用的,因为在std这个命名空间基本上包含了我们常用的库函数名。)
(命名空间:用于避免在大工程中变量名和函数名,相互冲突,所以,就要产生命名空间的问题,因为命名空间的出现使得只要在不同的命名空间,即使是同名的变量和函数也不会冲突。)
数据类型范围及大小
数据类型 数据大小 数据范围 int 四个字节 -2147483648~2147483647 float 四个字节 小数点后六到七位(1.235e2) double 八个字节 小数点后15-16位 bool 一个字节 false / true(因为使用char实现的) char 一个字节 -128~127 long long 8byte -2 ^ 63 ~ 2 ^63 - 1 long long double 12 ~ 16 18 ~ 19 byte
常用ascii码:
加权平均数:
命名空间
相信就算就算经过了我上述的解释,大家对命名空间仍然是,不知所云。下面就让我们结合一些实例来说明,命名空间的作用,和具体的概念。写较多C语言程序的小伙伴可能会遇到类似下面这种情况:
亦或者是当你写项目的时候,把库中的头文件一引用,发现你定义的变量或者函数名下面有一些莫名其妙的报错。那这是因为什么呢?
我们仔细查看报错信息就会发现,就比如图示这段程序:通过报错我们可以得知,好像是我们头文件中有对rand这个名字的定义了,所以我们在定义就会产生重定义的错误。
这时就有聪明的同学就会问了:难道我用C语言写个项目还要把C语言的库中的函数名,全都记住??就我现在的知识面当你在全局定义函数或者是变量的时候,你就要对你所包含的头文件有一定的了解,并且有意识的去避免,这种问题的发生。
难道很早之前的程序员没被这种问题所困扰么??答案是肯定的,这其中有一个大佬就烦透了c语言这种性质,自己动手丰衣足食,我们的祖师爷,c++之父——Bjarne Stroustrup
就在C语言的基础上,创造了兼容c语言的c++。
他所提供的关于冲突的解决办法就是我们今天提到的——命名空间,那他是怎么来解决这种情况的呢?下面让我们结合实例来进行相应的讲解:
可以看到的是,我把原来在全局的变量rand放到了一个类似于结构体的形式空间中,这样它就不会报错了。
可是那个类似于结构体的东西到底是什么呢??
说到这,我们关于c++的第一个关键字就出现了namespace,像我上边的用法就是自定义一个属于自己的命名空间这里边不仅可以存放变量,函数,结构体 ,类,对象……
那它避免冲突的主要原理就是,巧妙的利用了域这个概念。
关于这个域的概念,我们在学习C语言的时候其实就接触过。那时候我们说的是作用域,其实是等同的。那时我们了解到的,全局变量和局部变量定义互不干涉就是这个作用域和我们当时提到的生命周期起到的作用。就比如下面这段程序:
#include<stdlib.h>//这段程序是可以通过编译的,原因是编译器对于变量,函数等需要自定义名称的符号 //一般来说编译器遵循以下搜寻规则:局部域 > 全局域 int a = 0; int main() { int a = 0; return 0; }
而对于命名空间也是类似的原理,相当于,它圈了一块带有独立于全局的地方叫命名空间,其中包含的变量只能在这块空间活动,即仅限于在这块空间活动即——命名空间域。所以,编译器在一般情况没有权限,进入这个地方查找,所以不会造成二义性。那我们在局部变量,全局变量,命名空间内存在的变量同名的时候,我们应该如何指定调用呢?我们可以参考下面的代码:
#include<stdio.h>
namespace lly
{
int a = 3;//命名空间域的变量
}
int a = 0;//全局域的变量
int main()
{
int a = 3;
//局部域的变量
//访问全局域
printf("%d",::a);
//访问局部域
printf("%d",a);
//访问
return 0;
}
这时可以看到我引入了一个新的操作符:::
这个操作符的名字是域限定操作符,这个操作符可以指定编译器到对应的域进行查找,下面是一些规则:
符号语句 | 含义 |
---|---|
(啥也不加或者是空格):: 变量/函数名 | 在全局域进行符号的寻找 |
命名空间 :: 变量/函数名 | 在命名空间域进行寻找 |
直接调用函数或者是变量 | 搜索顺序:局部域 > 全局域 > 命名空间域 |
在第三个表格中我加入了命名空间域的顺序,看似于我上文的内容有一定的冲突,不是说编译器一般不对命名空间进行相应的访问么?的确,但是除了上文的对命名空间的指定访问之外,还有一种可以达到我最后的顺序,那便是命名空间的展开,下面我们结合样例,来看看吧。
#include<stdio.h>
namespace hehe;
{
int a = 0;
}
using namespace hehe;
//这个语句就是对我之前定义的命名空间进行相应的展开。
//但是展开后有一个弊端那就是,展开后就会变成全局域的内容了这样本来是为了避免命名冲突的命名空间好像就被破坏了
//所以说尽量不要在大项目对命名空间进行展开
int a = 0;//因为命名空间的展开所以就会产生变量冲突的问题了。
可见,命名空间在大项目中的访问还是用指定访问的好。当时如果你实在觉得这样写代码太麻烦了你可以只对你常用的函数变量等进行展开就可以了,c++也是支持这样的语法的。
#include<cstdio>
#include<iostream>
using std::cout;//在使用这个部分展开的语法的时候要明白以下几点,首先你要关于你要展开的这个函数结构体,在你所包含的头文件里存在
//而且还要保证你展开的这个函数在这个命名空间里。
所以说这个命名空间,用好了是个代码利器,用不好,反而会影响自己的代码效率。
命名空间的嵌套
当然如同是for语句之类的,命名空间也是可以嵌套的,就比如你家,你家房子占的地方就是最外层的命名空间,而你的卧室就是你在命名空间中自己划分的命名空间。所以说命名空间中也可以继续进行命名。这时就会有人问了,这种套娃的操作在实际的项目工程中真的会有用么??所谓存在即合理,下面我将用图示进行讲解:
如图所见,这种机制在实际的应用开发中并不在少数,所以最好是老老实实的记住最好。
现在我们在转头看这个语句using namespace std;
相信又有了新的理解,对于后边这个命名空间名称,在后续的c++学习中,会多次遇到,这个命名空间std
是库函数和stl的命名空间,所以我们调用库中的函数或者是容器等,都少不得了这个空间。相信很多同学在写c++程序的时候都会来上一套固定格式头文件再加上这个语句。可是在编写项目的时候,还是尽量少用的好。
后序
路漫漫其修远兮,吾将上下而求索,愿每个人都能键盘敲烂年薪三十万。
次遇到,这个命名空间std
是库函数和stl的命名空间,所以我们调用库中的函数或者是容器等,都少不得了这个空间。相信很多同学在写c++程序的时候都会来上一套固定格式头文件再加上这个语句。可是在编写项目的时候,还是尽量少用的好。
后序
路漫漫其修远兮,吾将上下而求索,愿每个人都能键盘敲烂年薪三十万。