前言
C++是Bjarne Stroustrup在20世纪80年代发明并实现的,作为C语言的增强版出现,所以C++是兼容C语言的。
1998年,国际标准组织颁布了C++的第一个国际标准ISO/IEC 14882:1998,目前最新标准为ISO/IEC 14882:2020。IOS/IEC 14882通称ISO C++。ISO C++主要包含了核心语言和标准库的规则。
操作系统和编译器
操作系统:MacOS Ventura 13.2.1
编译器:CLion
第一个C++程序
- 由于C++是C语言的增强版,兼容C语言。和C语言相同,C++的程序入口也是main函数。
int main()
{
return 0;
}
C++的输入和输出
需要注意的是C++语言没有定义任何用于输入或输出的语句,而是包含了一个广泛的标准库,该库提供了输入和输出等众多功能。
C++中最常使用的输入输出标准库是iostream
。
如上图所示,cin
是标准输入流,对应c语言中的scanf
,cout
是标准输出流,对应C语言中的printf
。
使用代码演示:
#include <iostream> // 包含头文件
int main()
{
std::cout << "输入两个整数:"; // 输出
int num1, num2 = 0;
std::cin >> num1 >> num2; // 输入
std::cout << num1 << "+" << num2 << "=" << num1 + num2 << std::endl;
return 0;
}
值得注意的是,在使用cin
和cout
的时候,前面都要加上std::
,这表示cout
和cin
都在名为std
的命名空间中定义。命名空间可以让我们避免命名和库中相同的名字。标准库定义的所欲名称都在std
命名空间中。
上述代码的执行结果:
cerr
是错误标准输出流,clog
是日志标准输出流。
Hello World
让我们用C++语法来打印Hello World。
#include <iostream>
int main()
{
std::cout << "Hello World" << std::endl;
return 0;
}
若每次输入输出都需要写std::
有些太麻烦了,因此可以使用using namespace
引入命名空间。
#include <iostream>
using namespace std;
int main()
{
cout << "Hello World" << endl;
return 0;
}
缺省参数
缺省参数是函数在声明或定义时,为函数的参数指定一个缺省值,在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。
#include <iostream>
using namespace std;
void PrintNum(int n = 4) // 缺省参数
{
cout << n << endl;
}
int main()
{
PrintNum();
cout << endl;
PrintNum(12); // 传递实参,打印实参值
return 0;
}
如上代码,指定缺省参数是4,在调用第一个PrintNum()
,没有实参,因此打印为缺省参数值。调用第二个PrintNum()
,指定实参12,因此打印为12。
- 需要注意的是,C语言不支持缺省参数。
函数重载
C语言中,想要写一个两数相加函数,需要不同函数名写很多个功能类似的函数,如:
int AddInt(int x, int y)
{
return x + y;
}
double AddDouble(double x, double y)
{
return x + y;
}
这样不容易管理,也很麻烦。因此C++改良了这一点,支持了函数重载。
函数重载的定义:函数名相同,形式参数个数(类型、顺序)不同构成重载。
// 形式参数类型不同
int Add(int x, int y)
{
return x + y;
}
double Add(double x, double y)
{
return x + y;
}
// 形式参数个数不同
int Add(int x, int y)
{
return x + y;
}
int Add(int x, int y, int z)
{
return x + y + z;
}
// 形式参数顺序不同
double Add(int x, double y)
{
return x + y;
}
double Add(double y, int x)
{
return x + y;
}
C++支持函数重载而C语言不支持的原因
C/C++的程序要运行起来,都需要经历预处理、编译、汇编、链接这几个阶段。
C语言中,汇编阶段生成的xxx.o
文件中,存在符号表,符号表中包含各个函数的函数名,重载函数会在符号表中名字冲突。而C++在函数命名时,不止是为函数名命名,还包含参数类型和数量及顺序,可以做到区分,所以C++支持函数重载。
引用
引用就像是为一个变量起别名,编译器不会为引用变量开辟空间,而是和引用的变量公用一块空间。
#include <iostream>
using namespace std;
int main()
{
int a = 7;
int& ra = a;
cout << &a << endl;
cout << &ra << endl;
return 0;
}
- 引用在定义时必须初始化。
- 一个变量可以有多个引用。
- 引用一但引用一个实体,再不能引用其他实体。
在以前,我们使用C语言写一个两数交换的函数,需要使用传址调用,因为形参的改变,不影响实参。而现在有了引用,不再需要传址调用。
#include <iostream>
using namespace std;
void Swap(int& ra, int& rb)
{
int tmp = ra;
ra = rb;
rb = tmp;
}
int main()
{
int a = 10;
int b = 5;
cout << "before: a=" << a << ",b=" << b << endl;
Swap(a, b);
cout << "after: a=" << a << ",b=" << b << endl;
return 0;
}
引用和指针的不同
- 引用在概念上是一个变量的别名,指针是存储变量地址的。
- 引用在定义时必须初始化,指针没有要求。
- 引用在初始化时引用一个实体后,不能再引用其他实体,指针可以指向任意同类型实体。
- 没有NULL引用,但有NULL指针。
- 在
sizeof
中含义不同,引用的结果为引用类型的大小,指针在32位下始终是4字节,64位下始终是8字节。 - 引用自加为引用的实体自增1,指针自加是指针向后偏移一个类型大小。
- 有多级指针,但没有多级引用。
- 指针需要显示解引用,引用编译器会自己处理。
- 引用比指针使用起来相对更安全。