Hi!我是Duoni!
目录
初入C++,对Duoni来说也算是进入到一个新的学习阶段啦!
同样的,为表虔诚,入门仪式不能丢了!
- #include
-
- int main()
- {
- std::cout << "Hello C++" << std::endl;
- return 0;
- }
其实仔细一看,除了主函数式一样外,其他的表达式、关键字和头文件都发生了改变,看来接下来是一场“恶战”。不过学C++嘛,还是得笑着学!
以此为原点,向下刨根问底!
在这,我想试着打印一个全局变量rand的值,那么程序会成功吗?
- #include
-
- int rand = 0;
- int main()
- {
- printf("%d\n", rand);
- return 0;
- }
显然,结果是不尽人意的。编译器给出了错误警报。
那么提醒中rand为什么被重定义了?它不是应该是我们创建的一个全局变量吗?
究其根本:
printf在执行时,它所用到的参数会默认先在局部域中寻找。如果找不到,那么他便会进入全局域中搜寻。
结果它好生幸苦的来到全局变量中,却发现了有两个rand变量名:第一个是在头文件中的rand关键字,第二个是全局变量中的rand,两个名字一样,printf函数并不知道该选用谁,于是便发出了:重定义报错。
这是一个命名错误,那若非要用头文件中的关键字作为变量名该怎么处理捏?
- #include
-
- namespace Dt
- {
- int rand = 0;
- }
-
- int main()
- {
- printf("%d\n", rand);
- return 0;
- }
参照报错,那我们就在主函数外再建立一个域,包含着rand,这回应该不能出错叭?
tips:namespace是指命名空间,可用于定义局部命名。
怎么打印显示的是一组长码呢?
其实,尽管将rand重新存放在一个局域中,但printf还是无法访问到它。
相反,printf所访问的是头文件中的rand关键字,这一串长码就是其关键字的地址。
- #include
-
- namespace Dt
- {
- int rand = 0;
- }
-
- int main()
- {
- printf("%d\n", Dt::rand);
- return 0;
- }
那么如何让printf去访问局域中的rand呢?
其实很简单,这里只要在prntf参数前标上空间名就能解决。
这就好比:购物时要填写自己的收货地址,这样才能将或准确无误的给你送到。
局部展开:using namespace XXX(局域名)
- namespace Dt//创建命名空间
- {
- int head = 0;
- int tail = 0;
- }
-
- using namespace Dt;//展开局部命名空间
-
- int main()
- {
- printf("%d %d\n", head, tail);
- return 0;
- }
意义:这种做法是较好的命名使用习惯。
在项目中,多多少少会出现命名的争端,用这种局部展开的方式,可以保证即使他人与你命名相撞,也不影响你的程序运转,因为有指定的命名域。
全局展开:using namespace std:
标准库命名空间:std(是指标准输入\输出标准库的命名空间)
意义:全局展开命名空间意味着将库中所有的关键字进行展开,这种做法可能夹杂着危险,也存在着效率上的减弱。
指定展开:using std(不指定命名空间)::XXX(关键字)
意义:可展开命名空间中的指定关键字。项目中最常用的方法是:局部展开+指定展开。
- using std::cout;
- using std::endl;
-
- int main()
- {
- cout << "Hello C++" << endl;
- cout << "Hello C++" << endl;
- cout << "Hello C++" << endl;
- cout << "Hello C++" << endl;
- cout << "Hello C++" << endl;
- return 0;
- }
这么一搭配,命名安全性UP!UP!UP!
在C语言中,标准输入与标准输出是:printf与scanf函数。
C++虽然继承了C的近乎所有特性,但还是对此进行了优化,但具体优化了哪些呢?
我们移步向后看。
cin标准输入是istream类型的对象,而istream类则含与iostream的标准库中。
cin的优化:自动辨认数据类型输入
输入运算符">>":它接收cin的类istream在键盘上所读取到的数据,然后再将数据赋值给变量对象。(只能搭配cin使用)
- int main()
- {
- int val_i;
- double val_d;
- std::cin >> val_i >> val_d;//输入
- printf("val_i = %d val_d = %lf\n", val_i, val_d);
- return 0;
- }
cin优化了scanf的格式化输入的规则,通过封装实现了数据类型的自动识别。
这项优化着实让很多伙伴解放了双手!
cout标准输出是ostream类型的对象,而ostream类则含与iostream的标准库中。
cout的优化:自动识别数据类型输出
输出运算符"<<":运算符将对象的值写入到ostream类中,也可以理解为直接打印显示。(只能搭配cout使用)
endl操纵符:endl通常是在一个输出表达式的尾部出现,它的功能体现与'\n'的换行没有差异,都具有结束当前行的功能。
- int main()
- {
- int val_i;
- double val_d;
- std::cin >> val_i >> val_d;//输入99 3.14
- std::cout << val_i << " " << val_d << std::endl;//打印
- return 0;
- }
tips:虽然具有自动识别类型的优化,但个人觉得还是C语言的格式化输入输出比较好用。
如果说优化后的输入输出流是自动挡,那么老版的格式化输入输出流就是自动挡!
附:输入输出流待深入后继续更文。
早期,因为标准库将所有的功能都集中在全局域中实现,故使用时只需要在声明库的时候加上后缀“.h”即可。
后期,语言引入了std命名空间概念,以及为了与C语言头文件进行区分,也为了能够正确的使用命名空间,所以C++语法规定头文件后缀不加.h。
除了一些老编译器外,我们现在几乎看不到C++中带.h的头文件声明了。
文章到这就结束了!如果喜欢就关注Duoni叭!