大话cpp一个程序实现C到C++的过渡(头文件命名空间以及标准输入输出)
Posted 白龙码~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了大话cpp一个程序实现C到C++的过渡(头文件命名空间以及标准输入输出)相关的知识,希望对你有一定的参考价值。
Part I、前言
C++,又名C Plus Plus,是一门集合了C语言语法又增添了新鲜元素的高级编程语言。
Plus,有优势,好处的意思。相信大家在学习C语言时有许多痛苦的地方,不过在C++中,某些痛苦可能会得以缓解。
但是,不要以为C++是一门相较C更加简单的语言。当然,也无需害怕,我们慢慢来。
开始之前推荐一个官方的C++文档查询网站:C++ Reference,相信在大家今后的学习之路上有所需要。【ps:网站是纯英文的,但是使用了相对简单的语法和词汇,相信在百度的帮助下大家都能读懂】
Part II、解剖第一个C++程序
#include <iostream>
using namespace std;
int main()
{
cout << "Hello World!" << endl;
return 0;
}
或许大家乍一看这个会比较陌生,我们先切换到C语言模式:
#include <stdio.h>
int main()
{
printf("Hello World!\\n");
return 0;
}
现在开始从两段代码的第一行找不同——
1、头文件不同
不同的语言有不同的库想必大家都非常好理解,但是注意,这里还有个不同之处就是:C++官方自带的头文件它没有.h后缀!。
值得一提的是,起初的C++头文件还是带上.h后缀的,但是自从C++标准化之后,标准委员会就规定了,C++的标准库都不带.h后缀,此外,由于C++是包含C的,而C的官方头文件都是带上.h后缀的,因此,C++额外规定,C语言原本的头文件在去掉.h后缀的同时还要加上“c”前缀,比如:
<stdlib.h>变成了<cstdlib>,不过在大多数编译器中,比如博主使用的VS2019,写成stdlib.h还是可以识别的。
但是话说回来,如果我们自己写头文件的话,必须有.h后缀!
2、命名空间
相信大多数C++萌新刚入手这款语言时都会很疑惑:为什么我们在写代码之前,包个头文件之后还要再加上一句using namespace std
呢?
存在即为合理,想知道为什么必须有,那不妨试试如果没有它会怎么样。
我们可以看到,程序编译错误了,并且错误信息是:
为什么cout和endl都变成了未声明的标识符了呢?
这里就不得不提一下C++里命名空间的概念。
我们可以试想一下这样的一个情形:假如一个学校有两人同名,他们都叫张伟,但是好在他们一个在1班,一个在2班。那么如果有一天,其中一个张伟被通报批评了,那么广播里会怎么说?张伟因为隔着栅栏买鸡排然后…,那么请问那个无辜的张伟会怎么想?委屈死了对不对。因此广播里应该这么说:高二1班张伟同学,因为隔着栅栏买鸡排然后…
加上一个高二1班的限定,那么我们就能锁定目标了,这里的高二1班就是一个命名空间标识符。
命名空间怎么定义呢?如下所示
namespace class1
{
char name[] = "张伟";
}
namespace class2
{
char name[] = "张伟";
}
关键词namespace + 命名空间标识符 + 一对花括号
这,就是我们新建的两个命名空间了。
那我要访问1班的张伟该怎么办呢?
命名空间 + 两个冒号 + 你要访问的东西的名字
如果在C语言中,我们想在一个地方定义两个同名的变量可以吗?
int main()
{
char name[] = "张伟";
char name[] = "张伟";
return 0;
}
显然不可以,因为它们都是处在main函数这个作用域中的局部变量!
但是这种情况就可以:
int main()
{
char name[] = "张伟";
{
char name[] = "张伟";
}
return 0;
}
或者是这样:
int main()
{
char name[] = "张伟";
if (char name[] = "张伟")
{
}
return 0;
}
这里的if可以换成for/while…
为什么这样就可以了呢?因为尽管它们有相同的标识符name,但是它们处在不同的作用域当中。比如,第二个name是仅属于if语句中的,超出这个if作用域,它的生命周期就结束了,不可再被访问。
换句话说,if/while这些它们都自带一个大括号{}【ps:有时候不写只是因为可以省略】,而这些大括号连带着if/while,其实就形成了一个独立的作用域了,我们可以称之为大括号作用域。
类似于这里,命名空间本质上就是开辟了一块独立于外界的大括号作用域,在不同的作用域自然可以定义相同标识符的变量。但是不同的是,命名空间给这些大括号作用域起了一个名字,比如我们之前写的class1,class2。
关于命名空间的补充:
-
命名空间的成员
命名空间里不仅可以有一些变量,还可以存在函数以及后期我们要学的类… -
双冒号::
::是一个域操作符,作用域+域操作符就可以访问这个域中的东西。 -
命名空间可以嵌套定义
比如:
namespace class2
{
namespace team1
{
char name[] = "张伟";
}
}
张伟是高二2班第1组的一员。
而访问他就需要这样写: class2::team1::name
- 同名的命名空间可以合并
比如:
namespace n
{
void foo()
{
;
}
}
namespace n
{
int x;
}
尽管分开定义,但是它们在编译过后会被编译器合并到同一个命名空间中
此外,我们需要知道的是,C++标准库中的所有变量、函数等等标识符都是定义在std这个命名空间中的,正是由于同名的命名空间可以合并,所以尽管这些标识符定义在不同的头文件中,到最后都可以通过std::来访问。
- using关键字
正是由于标准库所有的中标识符都是定义在std命名空间的,所以我们才需要写上using namespace std;
这句话意味着,我要将std这个命名空间的东西展开,接下来我要使用的标识符如果没有特殊标注,那么都将是std里的。
但是这也带来一个问题,如果将std里的标识符全部展开了,那么如果我们定义一个与std里同名的东西,那就会发生冲突了,比如说:
namespace class1
{
char name[] = "张伟";
}
namespace class2
{
char name[] = "张伟";
}
using namespace class1;
using namespace class2;
int main()
{
std::cout << name;
return 0;
}
我们将class1和class2两个命名空间都展开了,那么我们再输出name就会出问题:
因为name存在于两个命名空间中,那应该cout class1::name呢还是class2::name呢?这是个未知数,也成功地把编译器搞晕了。
学到这里我们就能知道使用命名空间里成员的方式了:
1、直接用using namespace 把整个命名空间展开
但是这种方法很容易造成不同命名空间里成员间的冲突。
2、使用域操作符::来指明某个标识符所在的命名空间
但是这种方法太麻烦了,如果某个标识符很常用,那每次都要指明它的命名空间了。
于是,C++标准又提供了一个折中的方法:using + 命名空间::标识符
比如:
using std::cout;
using std::endl;
int main()
{
cout << "Hello World!" << endl;
return 0;
}
这里相当于,我们仅仅展开了cout和endl两个常用的标识符,造成冲突的几率非常非常小,因此是比较推荐的一个方式。
【补充:对于这种方式,我们无需指明标识符的类型,只需要写出标识符即可,比如:】
namespace n
{
void foo()
{
;
}
}
using n::foo;
实际我们在工程中也会遇到这样的问题,对于不同人负责的部分,它们可能会存在相同的标识符,因此,命名空间是十分有必要的。
3、标准输入输出
在C语言中,输出我们使用printf函数,输入我们使用scanf函数,而这里我们可以看到,C++的输出使用的是cout加上一个左移操作符<<。它究竟是什么呢?是函数吗?大家需要明确的是,它不是函数,而是一个对象。在一开始的学习中我们不需要作深入的了解,只需要了解它的相关使用即可。
首先是C++里的标准输出:cout以及<<。
cout是定义在标准库iostream里的,因此我们在开头要包含这个头文件,正如我们使用printf要包含stdio.h一样。
与printf最大的不同就是,cout的使用无需指明输出变量的格式化形式。
比如,对于int a = 10;
C语言需要这样输出:printf("%d",a);
而C++可以直接写成cout << a;
也就是说,cout可以直接帮我们推演出a的形式。
但是cout也有一个弊端:有时候非常麻烦。
比如,对于int a = 10, b = 20
,
C语言输出可以是:printf("a = %d, b = %d",a,b);
而使用cout就必须写成cout << "a = " << a << "," << "b = " << b;
很明显,使用cout会麻烦很多。那么对于这种情况,由于C++是包含C的,我们完全可以使用printf这种更简便的方式输出。
C++里的标准输入:cin以及>>
对于int a;
我们想从控制台读取一个数
对于C语言,可以使用scanf("%d", &a);
而对于C++,我们可以这样写:cin >> a;
二者最大的不同就是:cin无需指明a的格式化输入形式,此外还不需要写取地址符号&。
如果想读取多个数,比如int a, b, c;
那么可以写成:cin >> a >> b >> c;
与scanf相同的是,如果遇到空白符,比如空格、Tab、回车,cin会停止读取。
所以,我们需要在键盘上敲出:1空白符2空白符3空白符,然后就可以对abc分别赋值1、2、3了。
其实C++的输入输出的方式跟C语言差不了太多,大家下去用本地IDE自行摸索一下即可掌握基本的方式。
Part III、第一阶段小结
第一阶段的C++学习到这里就结束了。这些对于大家应该难度不大吧?
如果有问题,可以在评论区指出,也希望大家能给博主一些建议!
ps:【大话cpp】系列还在持续更新,欢迎大家关注,有新文章会第一时间推送!
以上是关于大话cpp一个程序实现C到C++的过渡(头文件命名空间以及标准输入输出)的主要内容,如果未能解决你的问题,请参考以下文章