目录
一、什么是C++
C++ 是一种广泛使用的通用编程语言,它是在 C 语言的基础上发展而来的,首次由 Bjarne Stroustrup 在贝尔实验室于 1979 年开始设计和实现。C++ 提供了面向对象编程(OOP)、泛型编程和过程化编程等多种编程范式的支持。
1.1 、历史背景
C++ 的设计初衷是为了增强 C 语言的功能性,同时保持与 C 的兼容性。
最初被称为 "C with Classes",后来改名为 C++。
1983 年,C++ 名称正式确立,其中 ++ 表示递增操作符,意味着它是 C 的扩展
1.2、特性
面向对象: C++ 支持类、对象、继承、封装、多态等 OOP 概念。
1.3、C++发展史
阶段 | 内容 |
C with classes | 类及派生类、公有和私有成员、类的构造和析构、友元、内联函数、赋值运算符重载等 |
C++1.0 | 添加虚函数概念,函数和运算符重载,引用、常量等 |
C++2.0 | 更加完善支持面向对象,新增保护成员、多重继承、对象的初始化、抽象类、静态成员以及const成员函数 |
C++3.0 | 进一步完善,引入模板,解决多重继承产生的二义性问题和相应构造和析构的处理 |
C++98 | C++标准第一个版本,绝大多数编译器都支持,得到了国际标准化组织(ISO)和美国标准化协会认可,以模板方式重写C++标准库,引入了STL(标准模板库) |
C++03 | C++标准第二个版本,语言特性无大改变,主要:修订错误、减少多异性 |
C++05 | C++标准委员会发布了一份计数报告(Technical Report,TR1),正式更名C++0x,即:计划在本世纪第一个10年的某个时间发布 |
C++11 | 增加了许多特性,使得C++更像一种新语言,比如:正则表达式、基于范围for循环、auto关键字、新容器、列表初始化、标准线程库等 |
C++14 | 对C++11的扩展,主要是修复C++11中漏洞以及改进,比如:泛型的lambda表达式,auto的返回值类型推导,二进制字面常量等 |
C++17 | 在C++11上做了一些小幅改进,增加了19个新特性,比如:static_assert()的文本信息可选,Fold表达式用于可变的模板,if和switch语句中的初始化器等 |
C++20 | 自C++11以来最大的发行版,引入了许多新的特性,比如:模块(Modules)、协程(Coroutines)、范围(Ranges)、概念(Constraints)等重大特性,还有对已有特性的更新:比如Lambda支持模板、范围for支持初始化等 |
二、C++关键字
三、C++命名空间
在C++中,命名空间(namespace)是一种将全局作用域中的标识符组织起来的方法。它可以帮助避免命名冲突,并且可以用来将相关的类型和函数组织在一起。
3.1、namespace的定义
namespace(命名空间)是一种封装标识符(如变量名、函数名、类名等)的方式,它可以将相关的标识符组织在一起,以避免命名冲突。命名空间的定义使用namespace关键字后跟一个唯一的名称(即命名空间的标识符)和一对花括号{},其中包含了该命名空间内的所有成员。
名空间定义的基本语法:
namespace namespace_name {
// 命名空间内的声明和定义
// 可以包括变量、函数、类、枚举等
}
示例:
假设我们有两个不同的库或代码模块,它们都定义了一个名为print的函数,但这两个函数的功能和用途完全不同。为了避免命名冲突,我们可以将这两个函数分别放在不同的命名空间中。
#include <iostream>
// 库A
namespace A {
void print() {
std::cout << "A" << std::endl;
}
}
// 库B
namespace B {
void print() {
std::cout << "B" << std::endl;
}
}
// 主函数
int main() {
A::print(); // 调用库A(命名空间A)的print函数
B::print(); // 调用库B(命名空间B)的print函数
return 0;
}
四、C++的输入和输出
C++主要通过 <iostream> 头文件中的类和对象来实现。如 std::cin 用于输入,std::cout 和 std::cerr 用于输出。一般般日常练习中我们可以using namespace std,实际项目开发中不建议using namespace std。
例:
#include <iostream>
// 在这里使用using namespace std;,以便在main函数中直接使用cin和cout
using namespace std;
int main() {
int number;
cout << "请输入数字: ";
cin >> number;
cout << "输入的数字为: " << number << endl;
return 0;
}
五、缺省参数
在C++中,缺省参数(也称为默认参数)允许在声明或定义函数时为函数的某些或全部参数指定一个默认值。当调用该函数时,如果调用者没有为这些参数提供实参,则自动使用这些参数的默认值。缺省参数分为全缺省和半缺省两种形式。
缺省参数允许在函数声明时为某些参数指定默认值。当调用函数时,如果没有为这些具有默认值的参数提供实参,那么将自动使用这些默认值。
#include <iostream>
#include <assert.h>
using namespace std;
void Func(int a = 0)
{
cout << a << endl;
}
int main()
{
Func(); // 没有传参时,使⽤参数的默认值
Func(10); // 传参时,使⽤指定的实参
return 0;
}
5.1、全缺省参数:
指的是函数的所有参数都给出了默认值。在调用这样的函数时,你可以不传递任何参数,此时函数将使用所有参数的默认值。
#include<iosteram>
using namespace std;
// 全缺省
void Func1(int a = 10, int b = 20, int c = 30)
{
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl << endl;
int main()
{
Func1();
Func1(1);
Func1(1, 2);
Func1(1, 2, 3);
return 0;
}
输出结果:
5.2、半缺省参数:
指的是函数的部分参数给出了默认值,而另一部分没有。在使用半缺省参数时,必须从右向左依次给出默认值,不能跳跃式地给出默认值。这是因为在函数调用时,参数的匹配是从左到右进行的,编译器需要知道哪些参数被省略了以便使用相应的默认值。
#include <iostream>
using namespace std;
void Func2(int a, int b = 10, int c = 20)
{
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl << endl;
}
int main()
{
Func2(100);
Func2(100, 200);
Func2(100, 200, 300);
return 0;
}
输出结果:
5.3、调用带缺省参数的函数:
当调用带缺省参数的函数时,C++规定必须从左到右依次给出实参,不能跳跃给出。也就是说,如果函数的前几个参数有默认值,而你只想为后面的参数提供实参,那么你必须显式地给出前面所有没有默认值的参数的实参,或者至少给出到你想开始提供实参的那个参数之前的所有参数的实参。
5.4、函数声明和定义中的缺省参数:
当函数的声明和定义分离时(即函数声明在头文件中,而定义在源文件中),C++规定缺省参数只能在函数声明中给出,而不能在函数定义中给出。这是因为编译器在编译时需要使用这些默认值,而这些默认值必须在编译时就已经确定。如果在函数定义中也给出了缺省参数,那么编译器可能会因为声明和定义中的缺省值不一致而感到困惑,从而导致编译错误。因此,最佳实践是在函数声明中指定缺省参数,并在函数定义中省略这些参数的默认值。