目录
编辑
第一个C++语言程序
一、命名空间
1.1 C++为什么会有命名空间
1.2 命名空间域
二、命名空间的使用
2.1 展开命名空间和using声明
2.2 展开命名空间的意义
2.3 命名空间的使用
2.3.1 使用using将命名空间中某个成员引入
2.3.2 命名空间中还可以再继续定义命名空间
三、记忆式理解C++的输入与输出
3.1 "<<"在C++中的两种意思
3.2 ">>"在C++中的两种意思
第一个C++语言程序
C++是在C的基础上,容纳进去了面向对象编程思想,并增加了许多有用的库,以及编程范式等,补充了C语言语法的不足。
C++兼容C。
#include<iostream>
using namespace std;int main()
{cout << "hello world" << endl;return 0;
}
一、命名空间
定义命名空间,需要使用namespace关键字,后面跟命名空间的名字,然后接一对{}即可。
1.1 C++为什么会有命名空间
有一个语法问题,是C语言解决不好的,例如:
#include<stdio.h>
//#include<stdlib.h>int rand = 10;int main()
{printf("hello world\n");printf("%d\n", rand);return 0;
}
上述程序虽然通过了,但是有一个问题,如果把#include<stdlib.h>这句代码放开,程序就报错了,报错显示rand重定义了。
这是因为,C语言中,全局变量可能存在命名冲突的问题。当包含了stdlib头文件以后,头文件展开,其中会有一个全局函数rand。而下边的程序中又定义了rand全局变量。C语言区分不开,于是就造成了命名冲突问题。
C++增加了解决方式,我们知道不同的域里可以定义同名变量。例如:
#include<stdio.h>int x = 0;int main()
{int x = 1;printf("hello world\n");printf("%d\n", x);printf("%d\n", ::x);return 0;
}
1.2 命名空间域
::表示域作用限定符,::左边什么都没给,默认为全局域。
域包括:
全局域、局部域、命名空间域、类域
基于上述结论,我们通过程序对命名空间域做进一步了解:命名空间也可定义函数和定义结构体。
#include<stdio.h>
#include<stdlib.h>namespace exp1
{int x = 0;int rand = 0;//定义函数int Add(int left, int right){return left + right;}//定义结构体struct Node{struct Node* next;int val;}
}
namespace exp2
{int x = 1;
}int main()
{printf("%d\n", exp1::x);// 0printf("%d\n", exp2::x);// 1printf("%p\n", rand); // 7A36F070printf("%d\n", exp1::rand);// 0printf("%d\n", exp1::Add(1, 2));// 3struct exp1::Node phead;return 0;
}
编译器的搜索原则:
- 不指定域:1.先去局部域;2.再去全局域
- 指定域:如果指定搜索域,则直接去指定域搜索。
二、命名空间的使用
2.1 展开命名空间和using声明
using namespace std;
指的是,之前被圈在命名空间中的未经指定命名空间指令访问的语句,通过using声明主动放到全局,使搜索的时候不需要特别指定完整的命名空间前缀,就可以被搜索到。
2.2 展开命名空间的意义
#include<iostream>
using namespace std;
#include - 将头文件的内容插入到该命令所在的位置,从而把头文件和当前源文件连接成一个源文件,这与复制粘贴的效果相同。
iostream - io相关的流的头文件
如果此处只有#include<iostream>,而命名空间std没有展开,即使包了上一行头文件,也用不了。因为cont、endl在iostream命名空间中还被std封起来了。
值得注意的是:std是所有C++库的命名空间。C++库中的头文件几乎是不带.h的。
#include<iostream>
using namespace std;int main()
{std::cout << ""hello world" << endl;cout << ""hello world" << endl;return 0;
}
命名空间域打开以后,相当于全局域,搜索顺序还是先局部域,再全局域。但命名空间域展开后还是有弊端的,如果命名有冲突就会失去作用。
2.3 命名空间的使用
2.3.1 使用using将命名空间中某个成员引入
#include<iostream>int main()
{int i = 0;std::cin >> i;std::cout << xxxxx << std::endl;std::cout << xxxxx << std::endl;std::cout << xxxxx << std::endl;std::cout << xxxxx << std::endl;return 0;
}
都要加std::会显得很麻烦,可采用使用using将命名空间中某个成员引入,将上述程序改写为:
#include<iostream>
using std :: cout;
using std :: endl;int main()
{int i = 0;std :: cin >> i;cout << "xxxxxx" << endl;cout << "xxxxxx" << endl;cout << "xxxxxx" << endl;cout << "xxxxxx" << endl;return 0;
}
2.3.2 命名空间中还可以再继续定义命名空间
为避免展开命名空间导致的命名冲突,命名空间中还可以再继续定义命名空间。
#include<iostream>
using std::cout;
using std::endl;namespace exp
{namespace zs{void Push(){cout << "zs" << endl;}}namespace ls{void Push(){cout << "ls" << endl;}}
}
int main()
{int i = 0;std::cin >> i;cout << "xxxxx" << endl;cout << "xxxxx" << endl;cout << "xxxxx" << endl;cout << "xxxxx" << endl;exp::zs::Push();exp::ls::Push();return 0;
}
展开头文件和展开命名空间的区别:
展开头文件:在编译的预处理阶段,编译器会把所有包含的头文件进行展开,把头文件中的内容拷贝过来,放在这里,编译器只会对.c和.cpp的文件编译,不会对.h文件进行编译,因为所有的.h定义的或声明的都是给其他地方用的。
展开命名空间:影响的是域的搜索规则,默认情况下,编译器只会在局部和全局域中搜索。
使用命名空间,可以做到3种搜索:指定搜索(加命名空间名称及作用域限定符,如std::cout)、公开搜索(使用using namespace 命名空间名称,如using namespace std)、公开某些内容搜索(使用using将命名空间中某个成员引入,如using std :: cout)。
三、记忆式理解C++的输入与输出
3.1 "<<"在C++中的两种意思
1. 左移;
int i = 1;
i = i << 1;
2. 流插入运算符。
与cout配合,cout标准输出对象(控制台)。与C语言不同C++可以自动识别类型。此外,也可以连续的流向cout中去。
cout:
- c - 代表控制台的缩写console
- cout - 把数据out到控制台中去
- cout << "hello world" - 字符串流向cout中去
cout << "hello world" << endl;
const char* str = "hello world";
char ch = '\n';
cout << str << i << "hello world" << ch;//比起C语言printf又有另一个特征
//C语言要指定对应的格式类型
peintf("%d %s %p\n", i, str, pi);
C++中的换行可用endl(endline),endl是全局变量,在某种程度上是等价于'\n'的。
3.2 ">>"在C++中的两种意思
1. 右移;
2. 流提取运算符。
与cin配合,cin标准输入对象(键盘)。即,在控制台里边,用键盘输入了一串字符,可以把该字符串提取到变量中。此外,同样可以提取一个,也可以连续的提取。
const char* str = "hello world";
cin >> i >> ch;
cout << str << i << ch;//相较于scanf
scanf("%d%c", &i, &ch);
printf("%d%c", &i, &ch);