目录
1.C++ 的发展历史(简单了解即可)
1.1 C++ 的诞生与早期发展(1979-1985)
1.2 标准化进程与C++98(1989-1998)
1.3 C++03与TR1(2003-2005)
1.4 现代C++:C++11/14/17/20(2011至今)
1.5 未来展望:C++23及以后
2. C++ 的第一个程序
3.命名空间
3.1 namespace 的价值
3.2 namespace 的定义
3.3 命名空间使用 using
4. C++ 的输出与输入函数 (cout、endl、cin)
5. 缺省参数
6. 函数重载
7. 引用
7.1 引用的概念和定义
7.2 引用的特性
7.3 引用的使用
7.4 const 与引用
7.5 指针于引用的关系
8. inline
9. nullptr
1.C++ 的发展历史(简单了解即可)
C++的起源可以追溯到1979年,当时Bjarne Stroustrup(本贾尼·斯特劳斯特卢普,这个翻译的名字不 同的地⽅可能有差异)在⻉尔实验室从事计算机科学和软件⼯程的研究⼯作。⾯对项⽬中复杂的软件开 发任务,特别是模拟和操作系统的开发⼯作,他感受到了现有语⾔(如C语⾔)在表达能⼒、可维护性 和可扩展性⽅⾯的不⾜。
1983年,Bjarne Stroustrup在C语⾔的基础上添加了⾯向对象编程的特性,设计出了C++语⾔的雏形, 此时的C++已经有了类、封装、继承等核⼼概念,为后来的⾯向对象编程奠定了基础。这⼀年该语⾔被正式命名为C++。
在随后的⼏年中,C++在学术界和⼯业界的应⽤逐渐增多。⼀些⼤学和研究所开始将C++作为教学和研 究的⾸选语⾔,⽽⼀些公司也开始在产品开发中尝试使⽤C++。这⼀时期,C++的标准库和模板等特性也得到了进⼀步的完善和发展。
C++的标准化⼯作于1989年开始,并成⽴了⼀个ANSI和ISO(International Standards Organization)国际标准化组织的联合标准化委员会。1994年标准化委员会提出了第⼀个标准化草 案。在该草案中,委员会在保持斯特劳斯特卢普最初定义的所有特征的同时,还增加了部分新征。
在完成C++标准化的第⼀个草案后不久,STL(Standard Template Library)是惠普实验室开发的⼀系列软件的统称。它是由Alexander Stepanov、Meng Lee和David R Musser在惠普实验室⼯作时所开发出来的。在通过了标准化第⼀个草案之后,联合标准化委员会投票并通过了将STL包含到C++标准中的提议。STL对C++的扩展超出C++的最初定义范围。虽然在标准中增加STL是个很重要的决定,但也因此延缓了C++标准化的进程。
1997年11⽉14⽇,联合标准化委员会通过了该标准的最终草案。1998年,C++的ANSI/IS0标准被投⼊使⽤。
1.1 C++ 的诞生与早期发展(1979-1985)
1979年,Bjarne Stroustrup在贝尔实验室开始开发一种名为“C with Classes”的语言,旨在为C语言增加面向对象编程的特性。这一时期的C++主要关注类、封装、继承等核心概念,为后来的面向对象编程奠定了基础。
1983年,该语言正式更名为C++,其中“++”是C语言中的自增运算符,象征着对C语言的改进和扩展。同年,第一个C++编译器Cfront发布,它能够将C++代码转换为C代码,然后使用C编译器进行编译。
1.2 标准化进程与C++98(1989-1998)
1989年,ANSI和ISO联合成立了C++标准化委员会,开始制定C++语言标准。经过多年的讨论和修订,第一个国际标准C++98于1998年正式发布。
C++98标准引入了标准模板库(STL),这是一个包含容器、算法和迭代器的强大库,极大地提高了C++的编程效率和代码复用性。STL的加入使得C++成为一门真正支持泛型编程的语言。
1.3 C++03与TR1(2003-2005)
2003年,ISO发布了C++03标准,这主要是对C++98的一个技术修正版本,修复了一些已知问题,但没有引入重要的新特性。
2005年,技术报告TR1(Technical Report 1)发布,为C++标准库引入了许多新组件,如智能指针、正则表达式库、随机数生成器等,这些特性后来被纳入C++11标准。
1.4 现代C++:C++11/14/17/20(2011至今)
C++11(2011):被称为“现代C++”的开端,引入了自动类型推导(auto)、范围for循环、lambda表达式、右值引用、移动语义、智能指针(unique_ptr、shared_ptr)、并发支持等革命性特性。
C++14(2014):作为C++11的小幅更新,主要完善了C++11的特性,如泛型lambda、变量模板、二进制字面量等。
C++17(2017):引入了结构化绑定、if constexpr、折叠表达式、文件系统库等特性,进一步简化了现代C++编程。
C++20(2020):引入了概念(Concepts)、协程(Coroutines)、范围(Ranges)、模块(Modules)等重大特性,标志着C++进入了新的发展阶段。
1.5 未来展望:C++23及以后
C++23标准正在制定中,预计将引入更多改进和新特性。C++标准委员会继续致力于提高语言的安全性、性能和易用性,同时保持与现有代码的兼容性。
从最初的“C with Classes”到现在的现代C++,这门语言已经走过了40多年的发展历程。它不断适应新的编程范式和技术需求,在系统编程、游戏开发、高性能计算、嵌入式系统等领域仍然保持着强大的生命力。
2. C++ 的第一个程序
在学习C语言,输出都是以printf 来进行经行输出操作的
//test.cpp #inclulde <stdio.h> int main() { printf("hello world\n"); return 0; }但在C++程序里更多都会使用<iostream>库函数内的cout endl
//test.cpp #include <iostream> using namespace std; int main() { cout << "hello world\n" << endl; return 0; }3.命名空间
3.1 namespace 的价值
在C语言程序中,在编程的时候会出现一些声明类型的同名报错的情况,在大型的程序中出现同名的情况会更多。
#include <stdio.h> #include <stdlib.h> int rand = 10; int main() { printf("%d",rand); return 0; }所有为了防止出现类型的同名等情况,c++系统引入namespace 就是为了更好的解决这样的问题。
3.2 namespace 的定义
定义命名空间,需要使用到namespace 关键字,后面跟命名空间名字,让后接{},{}中就是命名空间的成员,命名空间中就可以定义变量/函数等等。
namespace 本质是定义出一个域,这样的域互不影响,不同的域可以定义相同名字的变量。
C++中域有函数局部域,全局域,命名空间域,类域;域影响的是编译时语法查找⼀个变量/函数/ 类型出处(声明或定义)的逻辑,所有有了域隔离,名字冲突就解决了。局部域和全局域除了会影响 编译查找逻辑,还会影响变量的⽣命周期,命名空间域和类域不影响变量⽣命周期。
namespace 只能定义在全局,也可以嵌套。
大型项目多个文件多定义相同的命名空间编译器只会认为是一个命名空间,不会影响。
C++ 的标准库都放置在一个std (standdard)的命名空间中。
#include <stdio.h> #include <stdlib.h> namespace a { int rand = 10; int Add(int a,int b) { return a + b; } } int main() { printf("%d\n",rand); printf("%d\n",a::rand); printf("%d\n",a::Add(10,2)); return 0; }3.3 命名空间使用 using
一般命名空间的内容不能被直接使用到会默认在全局进行寻找,命名空间内的内容是不会主动寻找的,在一些代码中就会报错。
使用命名空间的变量/函数 有三种方式:
(1),使用“::”指定命名空间访问,项目推荐这种方式(最安全)
(2),使用using 将命名空间的某个成员经行张开,容易报错(比较不安全)
(3),使用using 将命名空间全部张开,推荐日常写代码,项目最不可以使用的(最不安全)
#include <iostream> using namespace std; namespace pit { int a=10; int b=20; } //张开部分命名空间 using pit::a; int main() { cout << a << endl; return 0; } //张开整个命名空间 using namespace pit; int main() { cout << a << " " << b << endl; return 0; }4. C++ 的输出与输入函数 (cout、endl、cin)
<iostream> 库简介
<iostream> 是 C++ 标准库中用于处理输入输出的头文件,其名称是Input Output Stream的缩写。它定义了标准的输入、输出流对象,是 C++ 进行控制台 I/O 操作的基础。
主要包含以下三个预定义对象:
- std::cout:标准输出流对象,通常关联到控制台(屏幕),用于输出数据。
- std::cin:标准输入流对象,通常关联到键盘,用于从控制台读取数据。
- std::endl:输出换行符并刷新输出缓冲区。
基本用法示例
#include <iostream> int main() { int age; std::string name; // 使用 cout 输出提示信息 std::cout << "请输入您的姓名: "; // 使用 cin 读取用户输入的字符串 std::cin >> name; std::cout << "请输入您的年龄: "; std::cin >> age; // 使用 cout 输出结果,endl 用于换行 std::cout << "您好," << name << "!您今年 " << age << " 岁。" << std::endl; return 0; }注意事项
- 使用
std::cout和std::cin时,通常需要包含<iostream>头文件。 - 为了简化代码,可以使用
using namespace std;来省略std::前缀,但在大型项目中不建议这样做,以避免命名冲突。 std::endl不仅输出换行,还会刷新缓冲区,这在需要立即显示输出时很有用,但频繁使用可能影响性能。- 对于简单的换行,也可以使用转义字符
'\n',如std::cout << "Hello\n";。
与 C 语言 printf/scanf 的区别
C++ 的cout/cin是类型安全的,编译器会在编译时检查类型是否匹配,而 C 语言的printf/scanf依赖于格式字符串,类型不匹配可能导致运行时错误。
总结:<iostream>库函数的输出与输入方式比<stdio.h>更加灵活。
5. 缺省参数
缺省参数就是函数在没有传参的时候可以进行提前预设好的默认值进行。
#include <iostream> using namespace std; int fun(int a = 10,int b = 20) { return a + b; } int main() { cout << fun() << endl; return 0; }可以看到函数fun 并没有进行传参但代码依然执行,没有传参的内容会用,默认的数值代替,有参数就优先用传参内容,但不能像 fun(,40) 的操作,带缺省的函数调用,C++ 规定必须从左到右一次给实参,不能跳跃传给实参。
全缺省就是全部形参给缺省值,半缺省就是部分形参给缺省值。C++规定半缺省参数必须从右往左依次连续缺省,不能间隔跳跃给缺省值。
建议在需要写入缺省参数和非缺省参数的函数中,缺省参数都统一在最右边。
函数声明和定义分离时,缺省参数不能在函数声明和定义中同时出现,规定必须函数声明给缺省值。
// .h 声明 void func(int a = 10); // .cpp 定义,形参不带默认值 void func(int a) { cout << a; }6. 函数重载
在C++ 中可以支持在相同的域多个相同名字的函数,前提是函数传参不相同(参数类型不同,参数数量不同,参数顺序不同),但尽量不要使用缺省参数,要使用要确保不会出现函数雷同的情况。
正常情况:
int Add(int left, int right); double Add(double left, double right); void f(); void f(int a); void f(int a, char b); void f(char b, int a);报错情况:
void fun() { //... } void fun(int a=10) { //... } // 返回值不同不能作为重载条件,因为调⽤时也⽆法区分 //void fxx() //{} // //int fxx() //{ // return 0; //}7. 引用
7.1 引用的概念和定义
引用类似指针,但不是指针,功能类似给变量改名字,编译器不会开辟空间,会与原来的变量的空间共享空间,所有变量内容更改,就会一起更改内容。
类型& 引用别名=引用对象;
引用的功能只是在为了防止引入太多的运算符,而被发明的。
#include <iostream> using namespace std; int main() { int a = 10; int& A = a; int& AA = a; cout << a << endl; cout << A << endl; AA--; cout << a << endl; cout << A << endl; cout << AA << endl; return 0; }7.2 引用的特性
- 引用一定需要初始化;
- 一个变量可以有多个引用;
- 引用一旦被初始化,就本办法更改;
7.3 引用的使用
- C++ 引用多用于传参、作返回值:减少拷贝提效,修改引用会同步修改原对象。
- 引用传参和指针传参作用相近,引用书写更简便。
- 引用返回值场景复杂,后续面向对象章节再细讲。
- 引用与指针功能部分重叠、各有优势,无法完全替代;C++ 引用一经定义不能更换绑定对象,和 Java 引用有本质区别。
- 部分数据结构教材会用 C++ 引用代替 C 指针简化代码,没学过引用容易看不懂。
#include <iostream> using namespace std; void Swap(int& a, int& b) { int tmp = a; a = b; b = tmp; } int main() { int a = 10; int b = 20; Swap(a, b); cout << a << endl; cout << b << endl; return 0; }7.4 const 与引用
回顾:const 可以让对象内容不可可以改变,就是一个限制,防止进行更改。
- 引用要引用一个const 的对象就需要用const 进行应用,const 引用也可以引用普遍对象,因为对象的访问权限只能缩小,不能放大。
- 可以不需要注意类型,int& rb = 3*a;double d=13.32;int& rb=b;这些一下场景下次a*3的和结果存在在一个临时变中的,这些临时变量在C++中都具有常性(就是类似常量一样,例如:8这个常量,没办法改变8的大小,8就是8)所以这里就触发权限放大,必须使用const的常引用才可以。
- 临时对象:编译器为存放表达式结果创建的无名对象。
7.5 指针于引用的关系
指针与引用功能重叠、各有特性,无法互相替代:
- 引用是变量别名,不额外开辟内存;指针存地址,单独占用空间。
- 引用定义时必须初始化,指针语法允许不初始化。
- 引用绑定对象后无法更换,指针可随意修改指向。
- 引用直接访问原变量,指针需解引用访问。
- sizeof:引用得到原变量大小,指针固定为 4/8 字节(32/64 位)。
- 指针易产生空、野指针,引用使用更安全。
8. inline
每次函数的调用都需要,计算机都需要开辟空间,调用太多就会导致计算机内存不足的情况,而inline 类似define 的功能把对于的内容在编译的时,虽然运行内存下降,但这样会导致原本的代码行数成几何倍数的增加,到这这个项目的大小变大,所以inline 只适合个给一些短小的函数使用。
inline int add(int& a, int& b) { return a + b; } int main() { int a = 10; int b = 20; int c = add(a, b); cout << c << endl; return 0; }9. nullptr
NULL 实际ishi一个宏。在传统的C头文件(stddef.h)中,可以看到代码:
#ifndef NULL #ifdef __cplusplus #define NULL 0 #else #define NULL ((void *)0) #endif #endif- NULL 可能是数字 0 或 void空指针,会产生歧义:传 NULL 易匹配 int 重载而非指针重载,强转 voidNULL 还会报错。
- C++11 新增 nullptr 关键字,仅能转为各类指针,无法转整数,完美解决空指针类型混淆问题。
感谢观看!!!
悠仁さん