学习要求:1.关键词 (先大致看看哪些学过 不让你背下来 就让你看看)2.命名空间
3.输入输出(cin&cout)4. 缺省参数
5.函数重载 6. 引用 7. 内联函数
8. auto关键字 还有for-each(新用法) 9.nullptr的引入
warning: 以下的参考使用vs2022的编译器。
目录
一.关键字
warning: 这里仅供观看 不过多叙述了,建议:你可以看看哪些没见过的留个印象。 如图1-1
二.命名空间
1.命名空间中的引入呢:是祖师爷为了解决c语言中经常出现的命名问题,所以命名空间(域:具有限定作用的)出现了: namespace
2.命名空间的定义
3.命名空间的使用方法
三.输入输出 cin&cout
四.缺省参数 (oi说白了就是。。。)
1. 定义
2. 缺省参数几种类型
五.函数重载 (终于到这了 我挺不容易的点个赞呗)
1. 定义
2. 注意点
3. 扩展
六.引用 (太好了 救世主来了 )
1. 定义
2. 使用
3. 具体实例
4.效率对比
5. 区别与指针
七.内联函数
1. 来源
2. 定义和使用
wanring:
八.auto和for-each的用法
九.nullptr指针的引入
一.关键字
warning: 这里仅供观看 不过多叙述了,建议:你可以看看哪些没见过的留个印象。 如图1-1

二.命名空间
1.命名空间中的引入呢:是祖师爷为了解决c语言中经常出现的命名问题,所以命名空间(域:具有限定作用的)出现了: namespace


2.命名空间的定义
// 比如我现在开发一个项目使用到的函数啊 数据啊 都是要只是这一个项目里面的 那我就
//单独给这个项目开辟一个空间 用这个特定的项目也只用这块空间
// 假设这个项目是描述一个猴子山的
namespace Project1 {// 猴子总数量int money_num = 999;// 在这个项目中可以定义函数 void fun(){;///}// 命名空间中还可以嵌套空间 而且这两个空间依然是独立 但是访问。。 namespace Project2 {// pig int pig_num = 888;void fun() {printf("这里是pig_project");}}}//补充 不同文件下都有同名的 namespace 最后编译器会整合到认为是同一个空间
如 test.h test.c 下面你都有命名空间 namespace 但是内容不一样 但是依然会。。
3.命名空间的使用方法
namespace N1{int Add(int x, int y) {return x + y;}int a1 = 999;int a2 = 888;
}// :: 作用域操作符
using N1::a2;// 使用using+空间名称+:: + 变量名 拿出来变量
int main()
{// 这里我要拿出来a1 a2 然后使用其中的函数并打印出结果int a1 = N1::a1;// 命名空间加上其中的变量名 int a2 = N1::a2;printf("%d",N1::Add(a1,a2));return 0;
}
值得注意的是还有一方法 就是直接展开这个全部的空间:
namespace N1 {int Add(int x, int y) {return x + y;}int a1 = 999;int a2 = 888;
}
using namespace N1;// using namespace+空间名 直接展开空间内的全部 int main()
{printf("%d", Add(a1, a2));return 0;
}
这个方法好处明显但是坏处更明显 就是空间之间没有那么独立了。 因为全部被展开了。
但是话又说回来 : 我们为了方便学习 我们一般会之间展开标准库:为了使用其中的输入输出函数 ,哈哈哈 !
三.输入输出 cin&cout
#include<iostream> // 记住这是你跨入c++大门的第一步 以后再也不用c中的stdio.h了 哈哈哈
using namespace std; // 展开这个标准库空间 要用到 里面的输入输出 int main()
{cout << "hello world" << endl;cout << "hello world" << "";return 0;
}
输出结果:
int main()
{/*cout << "hello world" << endl;cout << "hello world" << "";*/float pi;int a;int b;cin >> pi;cin >> a >> b;cout << pi << " " << a << " " << b << " ";return 0;
}


四.缺省参数 (oi说白了就是。。。)
1. 定义
void fun1(int x = 100)
{cout << x << endl;}int main()
{fun1();fun1(521);return 0;
}

2. 缺省参数几种类型
//全缺省参数
void Func(int a = 10, int b = 20, int c = 30)
{cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl;
}//半缺省参数 // oi 注意啊 别乱搞这里的半缺省就是有一个不是缺省参数的家伙就叫半缺省
void Func(int a, int b = 10, int c = 20)
{cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl;
}
细节决定成败 来我们copy一下别人的:
五.函数重载 (终于到这了 我挺不容易的点个赞呗)
1. 定义
// 1、参数类型不同
int Add(int left, int right)
{cout << "int Add(int left, int right)" << endl;return left + right;
}
double Add(double left, double right)
{cout << "double Add(double left, double right)" << endl;return left + right;
}
// 2、参数个数不同
void f()
{cout << "f()" << endl;
}
void f(int a){cout << "f(int a)" << endl;
}
// 3、参数类型顺序不同
void f(int a, char b)
{cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{cout << "f(char b, int a)" << endl;
}
int main()
{Add(10, 20);Add(10.1, 20.2);f();f(10);f(10, 'a');f('a', 10);return 0;
}
oi: 震惊 只学过c语言的同学包的 挖去 你这这这 怎么都一样的函数名调用哦 会不会出问题哦 编译器不报错我吃。
包的: 这里啊 下面构成函数重载 :函数名相同的情况下: 1.形参个数不同 2.形参类型不同3.形参类型顺序不同
有个小可爱问我 (其实我自己就是这个小可爱):你你你 形参名字不一样怎么办 形参名字有什么鬼用 重要的是类型 比如 void fun(int x ,int y) void fun (int y, int x) 作为一个标准的好孩子 都知道这两家伙是一个人 不能构成函数重载
:------- 相同的名字 可以不同的人
2. 注意点
void fun(int x, int y = 1, int z) {;
}void fun(int x, int y, int z) {;
}
有人问 (我问)你你你 我可是缺省参数, 那咋了 你缺省参数那咋了 跟我函数有什么关系 我关注的几个点里面不包括你的缺省参数所以别管他们两不构成重载函数
3. 扩展



六.引用 (太好了 救世主来了 )
1. 定义

int a = 10;
int&ra = a;
2. 使用
4. 注意不能引用常变量(如被const修饰的变量 ) 跟常量
&前面对应的是引用的数据类型
void TestConstRef()
{const int a = 10;//int& ra = a; // 该语句编译时会出错,a为常量const int& ra = a;// int& b = 10; // 该语句编译时会出错,b为常量const int& b = 10;double d = 12.34;//int& rd = d; // 该语句编译时会出错,类型不同const int& rd = d;
}
牛刀小试: 思考下面为什么报错
答案 (因为 NULL空 被认为是常量0啊 当然不能被引用,或者说 逻辑上 空是不能被改变的不能被引用)
3. 具体实例
//做参数
void Swap(int& left, int& right)
{int temp = left;left = right;right = temp;
}
//做返回值 int& Count()
{static int n = 0;n++;// ...return n;
}int& Add(int a, int b)
{int c = a + b;return c;
}
int main()
{int& ret = Add(1, 2);Add(3, 4);cout << "Add(1, 2) is :" << ret << endl;return 0;
}
4.效率对比

5. 区别与指针
七.内联函数
1. 来源
// 宏的使用
// 宏变量
#define N 100
// 宏函数 写一个add
#define Add (x,y) ((x)+(y))
这里忘记的孩子,感觉去搜一下宏函数 宏变量的使用方法吧
宏的优点: 1.可读性 2. 复用性 3. 提高代码运行效率 (如函数调用时减少开销代价 )
缺点也挺明显的: 1. 不可以调试错误 2. 没有类型错误检查
所以c++ 出来了一个叫 内联函数的家伙 :
2. 定义和使用
内联函数是对于: 1. 非递归 2. 规模较小的 3. 调用频繁的函数 编译器会直接在当前运行代码的位置直接展开该函数减小函数调用的开销
inline int add(int x,int y)
{int b = x+y;
return b;
}
在这类函数的前面加上inline
这是一种用空间换时间的思路 但是如果过于大的调用 可能会导致代码膨胀 使得文件很大 所以编译器其实对于内联函数用不用是有自己的思路的: 一般来说 3-4行的代码吧 他可能会内联
wanring:
这里最容易犯错误的地方就是内
inline int add (int x,int y);int add(int x,int y){return x+y;}
联函数的声明和定义不要分离: 这里在调用的时候 会出现链接错误 因为声明inline直接被展开了后面函数调用的时候找不到函数地址了 就调用不了函数了 ;所以请注意内联函数:声明和定义一定要在同一地方不要分离了;
八.auto和for-each的用法
auto 这家伙
int main()
{int x = 10;auto a = &x;// 这个auto的声明 auto 是int*auto* b = &x;// 这里auto 识别出是int型 auto& c = x;// 类似 auto这里是 int型cout << typeid(a).name() << endl;cout << typeid(b).name() << endl;cout << typeid(c).name() << endl;*a = 20;*b = 30;c = 40;return 0;
}
void TestAuto()
{auto a = 1, b = 2; auto c = 3, d = 4.0; // 该行代码会编译失败,因为c和d的初始化表达式类型不同
}
// 此处代码编译失败,auto不能作为形参类型,因为编译器无法对a的实际类型进行推导
void TestAuto(auto a)
{}
void TestAuto()
{int a[] = {1,2,3};auto b[] = {4,5,6};
}
比
每个 auto
声明都是独立进行类型推断的
for -each 输出每一个成员内容
void TestFor()
{
int array[] = { 1, 2, 3, 4, 5 };
for(auto& e : array)e *= 2;
for(auto e : array)cout << e << " ";
return 0;
}
这上面 如果你要改变其中的内容 你可以用引用 注意这里呢auto自动的变量类型是数组的元素类型
值得注意的是java中也有类似的语法。
九.nullptr指针的引入
void f(int)
{cout<<"f(int)"<<endl;
}
void f(int*)
{cout<<"f(int*)"<<endl;
}
int main()
{f(0);f(NULL);f((int*)NULL);return 0;
}
这个代码中你以为F(NULL) 会调用 f(int*) 然而是 f(int ) 那是因为 在底层中 NULL其实是一个宏变量 值为 0 有的编译器下是 (void*)
但是吧 为了兼容以前的版本正确含义应该是 (void*)类型的 的空指针 所以 创建了一个新的关键字 nullptr 类型为void*