#1. C++关键字
C++总计63个关键字,C语言32个关键字,C++兼容%99的C语言,只有极少部分在C++中不可使用,后面我们会提到,关键字没有必要现在全部知道,后面可以慢慢学。
#2. 命名空间
首先我们通过几个C语言代码引入。
假如说我们今天引入一个<stdlib.h>头文件,里面有一个函数叫做rand()
#include <stdio.h> #include <stdlib.h> int rand = 0; int main() { printf("%d", rand); return 0; }
首先我们知道stdlib头文件展开后,rand函数就也在全局出来了,于是和我们定义的rand就命名冲突了,如果说我们定义在主函数中,那么就是局部优先,不会冲突。
#include <stdio.h> #include <stdlib.h> int main() { int rand = 0; printf("%d", rand); return 0; }
那么我们如何去避免命名冲突这种情况发生?很遗憾,C语言无法避免,于是C++里解决了这个问题,他引入了命名空间,命名空间里变量和函数的生命周期还是全局,但是如果不展开或者使用域作用限定符,那么命名空间里的一系列变量和函数都无法使用,看例子:
域作用限定符 ::
一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中
#include <iostream> using namespace std; namespace jj_jntm { int a = 0; int Add(int x = 0, int y = 0) { return x + y; } void COUT() { int x = a; cout << x << endl; } } int main() { int a = 1; cout << a << endl; cout << jj_jntm::a << endl; cout << jj_jntm::Add(1, 2) << endl; a = 2; //外面的a改变不会影响命名空间里的a,两者是独立的。 jj_jntm::COUT(); //只有命名空间里的a改动时,命名空间里调用的该a才会改变 jj_jntm::a = 3; jj_jntm::COUT(); return 0; }
命名空间还可以嵌套。
#include <iostream> using namespace std; namespace jj_jntm { int a = 0; int Add(int x = 0, int y = 0) { return x + y; } void COUT() { int x = a; cout << x << endl; } namespace basketball { int kk = 0; } } int main() { cout << jj_jntm::basketball::kk << endl; return 0; }
同一个工程允许命名空间的名字相同,因为编译器最后会将他们合成一个命名空间。
使用using将命名空间中某个成员引入
#include <iostream> using namespace std; namespace jj_jntm { int a = 0; int Add(int x = 0, int y = 0) { return x + y; } void COUT() { int x = a; cout << x << endl; } namespace basketball { int kk = 0; } } using jj_jntm::a; using jj_jntm::COUT; int main() { int a = 9; COUT(); //cout << jj_jntm::basketball::kk << endl; return 0; }
为什么呢?我们使用using展开部分命名空间,但是这与头文件展开完全是不同的,using仅仅是允许编译器进入namspace里对其进行搜索,我们不展开的时候,或者不指定的时候,编译器默认不会进去搜索的。
所以我们展开a和COUT,意思就是允许编译器在命名空间里去寻找了,而后定义的a赋值9不会影响到命名空间里的a,因为他是重新定义了一个局部变量。
这个就是在主函数中找不到a,我们就去全局找,又因为我们展开了a,所以可以在命名空间里找到a,于是命名空间里的a被修改为了6。
使用using namespace 命名空间名称 引入(展开到全局)
#include <iostream> using namespace std; namespace jj_jntm { int a = 0; int Add(int x = 0, int y = 0) { return x + y; } void COUT() { int x = a; cout << x << endl; } namespace basketball { int kk = 0; } } using namespace jj_jntm; int main() { int a = 3; cout << Add(a, 2) << endl; cout << Add(jj_jntm::a, 2) << endl; COUT(); //cout << jj_jntm::basketball::kk << endl; return 0; }
#3. C++输入&输出
使用cout标准输出对象(控制台)和cin标准输入对象(键盘)时,必须包含< iostream >头文件
输入:std::cin
输出:std::cout
换行:std:endl
>> << 可以看做流向。
#include <iostream> using std::cout; using std::cin; int main() { int a = 0; //从键盘输入数据流入a中 std::cin >> a; //a先流出到屏幕上,而后是换行符 std::cout << a << std::endl; int b = 0; cin >> b; cout << b << std::endl; return 0; }
当然,我们最好是能在输入前有个提示。
#4. 缺省参数
缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实 参则采用该形参的缺省值,否则使用指定的实参
我们来看代码:
#include <iostream> using std::cout; using std::cin; using std::endl; int Add(int a = 0, int b = 0) { return a + b; } int main() { cout << Add(1, 1) << endl; cout << Add() << endl; cout << Add(1) << endl; return 0; }
值得注意的是,实参必须从左向右给,缺省值必须从右向左缺。
int Add(int a = 1, int b = 2, int c = 3) { return a + b + c; } int main() { cout << Add() << endl; cout << Add(2) << endl; cout << Add(2,3) << endl; cout << Add(2, 3, 4) << endl; return 0; }
你也许会有疑问,我能不能跳着给实参,或者跳着缺省?
那么如果是这样,我怎么能知道这个2是传给b的还是传给c的,也就是说,1和2有一个是传给b的,那剩下的那个是给哪个缺省值呢?无法区分。
另外,如果函数的声明和定义不在同一个文件,而我们又想给函数缺省值,那么就给在声明,不可同时给。
这显然不可以,所以不能同时给,就是为了避免这样的情况。
至于说我难道不能给定义吗?一定要给声明?好好好,我写了一个函数,但是不给你源码,只给你用,给你个接口,你说我缺省在定义里,你怎么知道这个函数该不该缺省,所以说写在声明里。