欢迎来到C++
1、C++诞生的原因
由于"C++之父"Bjarne Stroustrup在研究中感觉到C语言的不足,他在原有C++的基础上,增加了一些内容(比如class[类] ),逐步形成了现在的主流语言C++。
2、关键字namespace
C++解决的问题之一,就是C语言中的命名冲突。
在C语言中,头文件<stdlib.h>包含了生成随机值函数rand(),所以以下代码运行时会报错:
c
#include<stdio.h>
#include<stdlib.h>
int rand = 10;
int main()
{
printf("%d\n", rand);
return 0;
}

这时,我们可以借助namespace ,namespace开辟了一个命名域。想要让系统进入指定的域,可以用域操作符::(两个冒号):
c
#include<stdio.h>
#include<stdlib.h>
namespace sound
{
int rand = 10;
int Add(int x, int y)
{
return x + y;
}
struct Node
{
int val;
struct Node* next;
};
}
int main()
{
printf("%d\n", sound::rand);
return 0;
}

namespace命名域需要取一个名字(sound),命名域内容需要用大括号({ }),使用域操作符时,将名字写在::的前面。
namespace (名字)
{
(声明的内容)
}
printf("%d\n", (域的名字,有名字就在对应域中查找,空白就是默认当前局部域-->全局域)::(对象、函数......));
namespace也可以声明定义函数、结构体等:
c
#include<stdio.h>
#include<stdlib.h>
namespace sound
{
int rand = 10;
int Add(int x, int y)
{
return x + y;
}
struct Node
{
int val;
struct Node* next;
};
}
int main()
{
printf("%d\n", sound::rand);
printf("%d\n", sound::Add(1, 2));
struct sound::Node node1;
return 0;
}

namespace也可以嵌套使用:
c
#include<stdio.h>
#include<stdlib.h>
namespace project
{
namespace A
{
int rand = 10;
int Add(int x, int y)
{
return x + y;
}
}
namespace B
{
int rand = 20;
int Add(int x, int y)
{
return (x + y)*10;
}
}
}
int main()
{
//namespace也可以嵌套使用
printf("%d\n", project::A::rand);
printf("%d\n", project::A::Add(1, 2));
printf("%d\n", project::B::rand);
printf("%d\n", project::B::Add(1, 2));
return 0;
}

多个文件,名字相同的namespace命名域,系统认为是同一个命名域,相当于合并。也就意味着我们可以在一个文件的namespace命名域中写上函数的声明,在另一个文件的namespace命名域中写上函数的定义,只要namespace命名域的名字相同,那么系统就会认为这个名字对应的命名域里同时有函数的声明、定义。
比如我们在之前数据结构的学习中,了解到栈 和队列 中,都有初始化 和入数据的操作。我们除了用"取不同名字"的方法,还可以用namespace命名域。这样一来即使操作函数的名字相同,由于是在不同域中查找,也就不会有命名冲突的情况发生。
C++的标准库,放在名字为std的命名空间中:
c
#include<algorithm>
int main()
{
int a[] = { 2,5,4,1,3 };
for (int i = 0; i < sizeof(a)/sizeof(a[0]); i++)
{
printf("%d ", a[i]);
}
printf("\n");
std::sort(a, a+5);
for (int i = 0; i < sizeof(a)/sizeof(a[0]); i++)
{
printf("%d ", a[i]);
}
printf("\n");
return 0;
}

这是C++标准库中的排序函数。
3、C++的输入输出
C++有区别于C语言的另一种输入输出方式。
iostream:in out stream,这是C++的输入输出库。
| 对象/函数 | 作用 |
|---|---|
| cout | ostream类的对象,包含在std中,面向窄字符的标准输出流 |
| cin | istream类的对象,包含在std中,面向窄字符的标准输入流 |
| endl | end line,函数,包含在std中,作用是换行,刷新缓冲区 |
| << | 与cout配合使用时,为流插入操作符,流插入操作符有自动识别功能,可以理解为识别数据,转换成字符串类型,然后打印在标准输出流(黑框)上 |
| ">>" | 与cin配合使用时,为流提取操作符,使用方法类似于scanf |
有了这些知识,我们就可以用C++的方式打印"Hello world":
c
#include<iostream>
using namespace std;
int main()
{
cout << "Hello world" << endl;
return 0;
}

我们也可以输出一些值:
c
#include<iostream>
int main()
{
int a = 100;
double b = 3.14;
char c = 'x';
std::cout << a << " " << b << " " << c << std::endl;
return 0;
}

我们也可以输入一些值:
c
#include<iostream>
int main()
{
int a = 0;
double b = 0.0;
std::cin >> a >> b;
std::cout << a << " " << b << std::endl;
return 0;
}

但如果我们输入的数据,类型不匹配,则会出错:

C++的输入输出,解决的是复杂数据的输入输出。C语言需要占位符%d、%s等,但是C++通过以上方式,可以直接输入输出。
4、关键字using
上面的代码中,我们不难发现,如果我们每次要调用std里面的的一些对象、函数等,总需要带着一个std::,这样有点不方便。能不能再简洁一点?
答案是使用using。
using的使用,底层逻辑就是使系统在查找对象时,如果从局部域到全局域还没有找到,就去指定的域中查找。我们可以形象地理解为using将指定的域展开了:
using namespace (域名);
c
#include<iostream>
using namespace std;
int main()
{
int a = 10;
cout << a << endl;
return 0;
}

我们可以"展开"域中所有的内容,也可以展开域中特定的内容。
using (域名)::(内容);
c
#include<iostream>
using std::cout;//展开了标准库中的cout
int main()
{
cout << "Hello world" << std::endl;
return 0;
}

但是,我们如果展开了某个特定内容,就不能再定义一个同名的变量,否则报错:
c
#include<iostream>
using std::cout;
int cout = 10;//此处定义了同名变量
int main()
{
cout << "Hello world" << std::endl;
return 0;
}

那么,using应该怎么使用?
在大项目中,往往不会使用using,而是直接使用 :: ,或者只展开经常用 且不会发生命名冲突的内容:
c
#include<iostream>
using std::cout;
using std::endl;
int main()
{
int a = 1000;
cout << a << endl;
return 0;
}

在个人练习等一些小项目中,若无需担心命名冲突的问题,可以全部展开:
比如上面的**用C++的方式打印"Hello world"**代码。