文章目录
1.前言1.1 什么是C++1.2 C++的发展1.3 C++的重要性1.4 如何学习C++1.5 C++要学什么 2. C语言过渡到C++(上)2.1 域2.1.1 命名空间2.1.1.1 定义2.1.1.2 作用域限定符2.1.1.3 使用 2.1.2 域的使用优先级 2.2 输入及输出2.2.1 std 命名空间及自定义命名空间2.2.2 .C++输入&输出 2.3 缺省参数2.3.1 全缺省2.3.2 半缺省2.3.3 函数声明和定义中的缺省参数 希望读者们多多三连支持小编会继续更新你们的鼓励就是我前进的动力!
走过了C语言的道路,终于迎来了C++的学习之旅,在经历面向过程的不断打磨,相信大家积累了不少的代码基础了,即将到来的是面向对象的语言——C++,C++的知识点稍显杂碎,或许在初步的学习会感觉到举步艰难,但是阳光总在风雨后,打好基础学到 stl 库的时候就会发现别样的彩虹!??
1.前言
1.1 什么是C++
C++ 是一种高级编程语言,它在 C 语言的基础上发展而来的面向对象的语言,C++ 最初是由丹麦计算机科学家本贾尼・斯特劳斯特卢普(Bjarne Stroustrup)在 20 世纪 80 年代初期开发的,当时,C 语言已经在系统编程等领域广泛应用,但对于大型软件项目的开发,缺乏一些如代码复用、数据抽象等方便的机制,简单来说就是对一些自定义类型的完善,C++ 应运而生,它增加了类和对象等面向对象的概念,使得程序可以更好地组织和维护
1.2 C++的发展
语言的开发都是在原先基础上增加新的语法规则,而不是删掉过去的语法规则,不然会导致以前编程环境下的代码都无法运行(python除外),于是在C语言的基础上进行扩展,增加了类的机制,称之为C with classes
刚开始是每五年更新一次语法规则,但随着生产力的需要,加快了语法规则的更新,变为三年
现在主流使用还是C++98和C++11,所有不用追求最新
重点将C++98和C++11掌握好,随着对C++理解不断加深,有时间可以去琢磨下更新的特性
1.3 C++的重要性
图片计算机语言排名来自TIOBE编程语言社区
2024年7月最新的排行榜
近几年 C++ 的上涨趋势还是比较明显的,虽然说还比不上 python 泛用性强大,但是 C++作为常年排名前几的语言,学习起来还是特别有价值的
就拿现在发展较?的人工智能来说,大家首先想到的就是 python ,认为学习人工智能就要学习python,这个是误区,python 中库比较丰富,使用 python 可以快速搭建神经网络、填入参数导入数据就可以开始训练模型了,但人工智能背后深度学习算法等核心还是用 C++ 写的
1.4 如何学习C++
首先不要把 C++ 学会当成一个短期目标,而是一个长期目标,要精通这门语言还是需要花费很久的时间的
?1. 写博客总结
?2. 画思维导图整理思路
?3. 深入C++后,借鉴大佬的书刊或文章
?4. 多刷题!多刷题!多刷题!重要的事情说三遍
1.5 C++要学什么
C++ 的重点可以大致分为封装、多态、继承
其中重点学习:
?C++的基本语法
?STL库
?高阶的数据结构
2. C语言过渡到C++(上)
那么接下来正式开始C++内容的学习,但在学习前要先介绍一些知识点便于过渡到 C++ 的重点内容——类与对象
2.1 域
域可以理解为一个围栏,把这些代码给围起来,分为全局域、局部域、类域、命名空间域
这里重点介绍一下命名空间
2.1.1 命名空间
C语言中经常会出现命名冲突的现象,变量或函数的名字不能相同,但是在处理项目的时候,不可能互相去确认各自的文件中有没有出现命名冲突的现象,所以引入了命名空间域的概念
2.1.1.1 定义
在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突,使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的
using namespace std//表示打开标准库命名空间 std
每个命名空间都是封锁的,只有打开了才能使用里面的变量及函数,这解释为什么域可以防止命名冲突的原因
定义命名空间,需要使用到 namespace 关键字,后面跟命名空间的名字,然后接一对{ }即可,{ }中即为命名空间的成员
namespace bit{ // 命名空间中可以定义变量/函数/类型 int rand = 10; int Add(int left, int right) { return left + right; } struct Node { struct Node* next; int val; };}
值得注意的是:在 { } 后和结构体不一样,不用加;
2.1.1.2 作用域限定符
:: 是作用域解析运算符,它用于明确指定变量、函数或类型所属的作用域。这个作用域可以是全局作用域、类作用域(后面介绍)或者命名空间作用域
?访问全局域:
int a = 0;int main(){int a = 1;printf("%d\n",a);printf("%d\n",::a);return 0;}
这里打印出来是 0 和 1,作用域解析运算符前面是空的就表示访问全局域的 a
?访问命名空间域:
namespace N{int a = 0;}int main(){int a = 1;printf("%d\n",a);printf("%d\n",N::a);return 0;}
这里打印出来是 0 和 1 ,作用域解析运算符前面是命名空间的名字就表示访问命名空间域的 a
2.1.1.3 使用
?命名空间的嵌套:
namespace N1{int a = 0;int b;int Add(int left, int right) { return left + right; }namespace N2 { int a = 1; int c; int d; int Sub(int left, int right) { return left - right; } }}
这里命名空间 N1 里又嵌套了一个命名空间 N2,这两个命名空间也可以定义同名变量
printf("%d\n",N1::N2::a);//访问 N2 的 aprintf("%d\n",N1::a);//访问 N1 的 a
?命名空间的合并:
同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中
一个工程中的 test.h 和 test.cpp 中两个 N1 会被合并成一个
//test.hnamespace N1{int a = 0;}//test.cppnamespace N1{int b = 1;}
这两个命名空间会合并,直接把它们两个当成同一个空间使用就行了
2.1.2 域的使用优先级
优先级:局部域 → 全局域 → 命名空间域
?局部域和全局域:
int a = 0;int main(){int a = 2;printf("%d\n",a);return 0;}
这里输出 2 ,局部域优先
?命名空间域:
//int a = 0;namesapce N{int a = 1;}using namespace N;int main(){//int a = 2;printf("%d\n",a);return 0;}
这里输出 1 ,只有在打开命名空间域 or 指定访问命名空间域
才能访问里面的 a ,打开命名空间域相当于把里面的 a 暴露在全局域里了,所以此时 int a = 0 仍然存在的话会造成命名冲突
2.2 输入及输出
2.2.1 std 命名空间及自定义命名空间
一般 C++ 编译器都自带了一些命名空间,这些命名空间里都存放了一些供我们使用的函数,比如 std 命名空间里有 STL 库和 C++ 标准库
但这些不足以满足项目开发使用,所以还有些程序员自定义的命名空间
?值得注意的是:在项目开发的时候,直接展开命名空间会有风险,我们的定义如果跟库重名就报错了,所以一般用作用域限定符访问自己想用的,但是在学习语法的时候我们一般不会出现这种问题,为了方便使用直接展开就好了
2.2.2 .C++输入&输出
在老版本编译器,如:VC6.0,没有命名空间的概念,引用库头文件还是包含 .h 的,但是随着命名空间的引入,为了和 C 语言区分,引用库头文件写成 #include < iostream >,就是把 .h 去掉了,该头文件包含了输入输出
eg:
#include<iostream>// std是C++标准库的命名空间名,C++将标准库的定义实现都放到这个命名空间中using namespace std;int main(){ cin >> a;cout << "Hello world!!!" << endl;cout << a << endl;// endl 为换行符,相当于 \n ,但 \n 在字符串中使用return 0;}
?1. 使用cout标准输出对象(控制台)和cin标准输入对象(键盘)时,必须包含< iostream >头文件以及按命名空间使用方法使用std
?2. cout和cin是全局的流对象,endl是特殊的C++符号,表示换行输出,他们都包含在包含< iostream >头文件中
?3. <<是流插入运算符,>>是流提取运算符
?4. 使用C++输入输出更方便,不需要像printf/scanf输入输出时那样,需要手动控制格式,C++的输入输出可以自动识别变量类型
2.3 缺省参数
缺省参数是指在函数声明或定义时为参数指定一个默认值。当调用函数时,如果没有为这个带有缺省参数的参数提供实际的值,函数就会使用默认值
2.3.1 全缺省
void Func(int a = 10, int b = 20, int c = 30) { cout<<"a = "<<a<<endl; cout<<"b = "<<b<<endl; cout<<"c = "<<c<<endl; }int main(){Func1();Func2(1,2,3);return 0;}
Func1 为10、20、30,Func2 为1、2、3
• 没有传参时,如果函数在传参的时候无法确定要传的参数的值时,可以使用参数的默认值暂时代替
• 传参时,使用指定的实参
2.3.2 半缺省
void Func(int a = 10, int b = 20, int c = 30) { cout<<"a = "<<a<<endl; cout<<"b = "<<b<<endl; cout<<"c = "<<c<<endl; }int main(){Func1(1);Func2(1,2);Func3(1,2,3);return 0;}
Func1 为1、20、30;Func2 为1、2、30;Func3 为1、2、3
?值得注意的是:传参必须从左往右传;缺省参数必须从右向左依次设置,也就是说,一个参数如果有缺省值,那么它右边的所有参数都必须有缺省值
2.3.3 函数声明和定义中的缺省参数
//test.h void Func(int a = 10); //test.cpp void Func(int a = 20) {} // 注意:如果生命与定义位置同时出现,恰巧两个位置提供的值不同,那编译器就无法确定到底该用那个缺省值
所以一般把缺省值放在声明,这样在编译过程中能让程序知道有个默认值能够初始化,在链接阶段才会知道有个能够使用的默认值。放在定义的时候编译阶段就会报错
?值得注意的是:缺省值必须是常量或者全局变量,且C语言不支持(编译器不支持)