文章目录
- 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 的 a
printf("%d\n",N1::a);
//访问 N1 的 a
🚩命名空间的合并:
同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中
一个工程中的 test.h 和 test.cpp 中两个 N1 会被合并成一个
//test.h
namespace N1
{
int a = 0;
}
//test.cpp
namespace 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语言不支持(编译器不支持)