1 #include2 using namespace std; 3 4 5 int main() { 6 7 cout << "hello world" << endl; 8 return 0; 9 } ~
这里的 using namespace std;
是展开C++标准模板库,不展开我们需要指定
#includeint main() { std::cout << "hello world" << std::endl; return 0; }
这是指定的写法,C++的命名空间可以解决命名冲突的问题,所以练习的时候展开没有什么影响,项目的时候还是不建议的!
cout and endl用的比较平凡,但是我们又不想全部展开or指定
#includeusing std::cout; using std::endl; int main() { cout << "hello world" << endl; return 0; }
单独指定命名空间的内容
命名空间的定义
#include2 #include 3 using namespace std; 4 5 namespace N { 6 7 void test() { 8 cout << "hello world" < //模板 12 void swap(T& a, T& b) { 13 cout << "void swap(T& a, T& b)" << endl; 14 T tmp = a; 15 a = b; 16 b = tmp; 17 } 18 } 19 20 21 void test() { 22 cout <<"hello C++" << endl; 23 } 24 25 26 int main() { 27 28 N::test(); 29 test(); 30 int a = 10; 31 int b = 11; 32 N::swap(a, b); 33 34 return 0; 35 }
hello world hello C++ void swap(T& a, T& b)
这是执行结果,一个test是全局域,一个是我们定的命名空间域,可以有效的避免命名冲突
命名空间里可以嵌套命名空间,一个命名空间就定义了一个新的作用域
缺省参数是声明或定义函数时为函数的参数指定一个默认值。在调用该函数时,如果没有指定实参则采用该默认值,否则使用指定的实参
如果声明和定义分开,建议在声明给缺省参数
1 #include2 using namespace std; 3 4 //给了a缺省参数 5 void test(int a = 10) { 6 cout << a << endl; 7 } 8 9 10 int main() { 11 12 test(); 13 return 0; 14 }
输出结果
[zt@VM-4-8-centos C++dir]$ ./a.out 10缺省值必须是常量或者全局变量
缺省参数分类
- 全缺省参数
1 #include2 using namespace std; 3 4 5 void test(int a = 10, int b = 20, int c = 30) { 6 cout << a << endl; 7 cout << b << endl; 8 cout << c << endl; 9 10 } 11 12 13 int main() { 14 15 test(); 16 return 0; 17 }
执行结果
[zt@VM-4-8-centos C++dir]$ ./a.out 10 20 30
有好多种使用方法这个比较简单我就不想列举了
2.半缺省参数
注意
- 半缺省参数必须从右往左依次来给出,不能间隔着给
- 缺省参数不能在函数声明和定义中同时出现
void TestFunc(int a, int b = 10, int c = 20)
{
cout<<"a = "<
testFunc(1);
return 0;
}
[zt@VM-4-8-centos C++dir]$ ./a.out a = 1 b = 10 c = 20函数重载
概念:
函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的
形参列表(参数个数 或 类型 或 顺序)必须不同,常用来处理实现功能类似数据类型不同的问题
C++可以函数重载的是函数名修饰规则带来的
推荐一篇大佬写的函数重载,非常棒:
吴秦大佬写的函数重载
引用详细推荐:大佬的博客
内联函数概念:
以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数压栈的开销,内联函数提升程序运行的效率
auto特性:
- inline是一种以空间换时间的做法,省去调用函数额开销。所以代码很长或者有循环/递归的函数不适宜使用作为内联函数。
- inline对于编译器而言只是一个建议,编译器会自动优化,如果定义为inline的函数体内有循环/递归等等,编译器优化时会忽略掉内联。
- inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址了,链接就会找不到
auto声明的变量必须由编译器在编译时期推导而得
在一些地方auto可以提高代码的阅读,一些迭代器写起来比较麻烦如:map/set, unordered_map/unordered_set写起来用auto就会非常爽
int main() {//std命名空间没有展开
std::unordered_map un_map;
std::unordered_map::iterator it = un_map.begin();
auto ait = un_map.begin();
return 0;
}
这个时候的auto就很舒服
注意:
使用auto定义变量时必须对其进行初始化,在编译阶段编译器需要根据初始化表达式来推导auto的实际类型。因此auto并非是一种“类型”的声明,而是一个类型声明时的“占位符”,编译器在编译期会将auto替换为变量实际的类型
auto的使用细则
- auto与指针和引用结合起来使用 用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&
- 在同一行定义多个变量
当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量
void TestAuto()
{
auto a = 1, b = 2;
auto c = 3, d = 4.0; // 该行代码会编译失败,因为c和d的初始化表达式类型不同
}
nullptrauto不能推导的场景
1.auto不能作为函数的参数类型
2.auto不能直接声明数组
NULL实际是一个宏,在传统的C头文件(stddef.h)中,可以看到如下代码
在大多数情况下NUll和nullptr是一样的,但是在:
#includeusing namespace std; void f(int* a) { cout << "int*" << endl; } void f(int a) { cout << "int" << endl; } int main() { f(nullptr); f(NULL); return 0; }
函数的重载会搞错



