目录
D1概述、类与对象
一、C++发展历史和历史地位
1.1、C++的江湖地位
编程语言排行榜--》可以百度查看,最新语言排行榜。TIOBE排行榜是根据互联网上有经验的程序员、课程和第三方厂商的数量,并使用搜索引擎(如Google、Bing、Yahoo!)以及Wikipedia、Amazon、YouTube统计出排名数据,只是反映某个编程语言的热门程度,并不能说明一门编程语言好不好,或者一门语言所编写的代码数量多少。
1.2、C++之父
Bjarne Stroustrup(1950-) 本贾尼·斯特劳斯特卢普
1979:Cpre,为C语言增加类的机制
C++中加入类的语法,C的编译器是编译不通过,此时加入Cpre将将类的机制替换,
C的编译器就可以编译通过。
1983年:Bjarne 发布全新编程语言C with class,后来命名为C++
1985年:CFront1.0 编译器 <The C++ programming Language>
1.3、C++发展过程
*1987年,开源组织GNU 编译器支持C++
1990年,Borland C++ <BC> BC编译器 基本不用
1992年,Microsoft C++ <VC>
*1998年,ISO C++98 ,发布C++制定国际标准
2003年,对C++98标准修订,C++03
2011年,ISO C++11标准
2014年,ISO 对C++11做了部分扩展,及C++14
*2017年,C++17
C++编译器每三年发布一个新的版本
C和C++的关系
1. 首先二者不是对立竞争的关系
2. c++是完全兼容C的
3. 相反,通过学习C++可以学到更多的软件开发模式
4. C++,C的基础上加入了面向对象的程序思想,增加了很多新的特性,更方便更严谨
C++的升级
1. C++的使用更方便,可以在for循环中定义变量,并且在循环体中定义的变量生命周期仅限于这个循环体内
2. 对struct关键字做了升级
3. C++的语法规则更严格,严谨,C++中相同作用域下不可以定义多个同名的全局变量,C语言中,相同的全局变量会被链接到相同的内存地址,但是C++中严禁这样的二义性代码
4. C++中函数行参类型必须显示地声明
1.4、应用领域
1、游戏开发
2、科学计算
3、网络通信(ACE库,libev)
4、 robot system(机器人系统ROS)汽车无人驾驶
5、 QT GUI图形化界面的开发 QT跨平台
if(sys == win){
windows系统的接口
}else if(sys == mac){
mac系统的接口
} else if(sys == ubuntu){
ubuntu系统的接口
}
二、第一个C++代码
#include <iostream>
int main(int argc, char *argv[])
{
std::cout << "hello world!" << std::endl;
return 0;
}
//结果:
hello world!
2.1、C++文件扩展名
.cpp 常用 c plus plus
.cc
.C
.cxx
2.2、C++编译
// 常用
g++ ***.cpp // a.out(.elf)
// 链接标准C++的库
gcc ***.cpp -lstdc++
// 安装g++的编译器
sudo apt-get update 跟新源
sudo apt-get install -f 跟新依赖
sudo apt-get install g++
2.3、C++头文件标准库
1. C++标准的头文件特点:没有.h后缀
2. 在兼容原有的C的头文件的基础上做的改动是,去掉.h后缀,并在前面加一个字符c,如<stdio.h>变成了< cstdio >
#include <stdio.h>
#include <iostream>
i:input 输入
o:output 输出
stream:流
标准输入输出流
//C++中可以使用C语言中的标准输入输出函数
#include <stido.h>
#include <cstdio>
实现:
vi cstdio
文件中的内容为:
#include <stido.h>
2.4、输入输出
输入:cin 标准输入对象 从键盘输入
输出:cout 标准输出对象 显示到屏幕
endl: 结束
cout << "hello world" << endl;
输出“hello world”字符串到屏幕上,
int num = 10086;
cout << "num = " << num << endl;
级联形式的输出
int num;
char str[20]
cin >> str >> num;
scanf("%d\n", &num);
使用对象的好处,不需要考虑具体的数据类型。
2.5、std::
//cout cin endl都属于标准名字空间中的成员对象。
参考代码: 03first.cpp
#include <iostream>
int main(int argc, const char *argv[])
{
char name[20];
int age;
float salary;
std::cin >> name >> age >> salary;
std::cout << name << std::endl
<< age << std::endl
<< salary << std::endl;
return 0;
}
//输入:
liu 17 99
//结果:
liu
17
99
2.6、注释
// 注释的手段 查看代码01first.cpp
参考代码: 01first1.cpp
#include <iostream>
#include <cstdio>
#if 0
#define BUG(str1, str2) do{printf("%s\n", str1);\
printf("%s\n", str2);}while(0)
#else
#define BUG(str1, str2) printf("%s\n", str1);\
printf("%s\n", str2)
#endif
int main(int argc, const char *argv[])
{
int num = 10;
if(num > 5)
BUG("zhoukai","nozuonodie");
else
printf("qian nian wang ba\n");
return 0;
}
//结果:
zhoukai
nozuonodie
三、名字空间 namespace
3.1、为什么使用名字空间
1. C语言中 所有的全局标识符公用同一个作用域
2. C++中 为了避免命名冲突,使用命名空间将全局作用域划分为不同的区域
//C++主要用于大型项目的开发,多人共同完成一个项目,有可能会造成定义的全局变量或者全局函数的名字相同,编译器有可能会报错误,
//每个工程师将自己的定义的全局变量或者函数放到自己的名字空间中。
使用名字空间中的成员是需要:
名字空间名::成员名;
//cout cin endl 对象都属于std标准名字空间的成员
3.2、定义名字空间的语法格式
namespace 名字空间名{
全局变量;
全局的函数;
嵌套的名字空间;
}
3.3、使用名字空间中的成员
名字空间名::成员名;
//如:
std::cin
std::cout
// :: --> 作用域限定符
3.4、名字空间指令
using namespace 名字空间名;
名字控制指令后边的代码可以直接使用
名字空间中的所有成员,不需要加:"名字空间名::"
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int a;
cin >> a;
cout << a;
return 0;
}
3.5、名字空间中成员的声明
using 名字空间名::成员名;
名字空间中的某个成员在后边所有的代码都是可见
1. using 关键字
using namespace 命名空间;//使用指定命名空间中的全局的定义
using 命名空间::全局定义; //指定后面访问哪个命名空间中的定义
2. 访问特定的命名空间的全局定义
命名空间::全局定义;
//参考案例: 04namespace.cpp
#include <iostream>
using namespace std;
namespace name{
int age;
void print(void)
{
cout << age << endl;
}
}
int main(int argc, const char *argv[])
{
name::age = 1000;
name::print();
/* // 名字空间指令
using namespace name;
age = 10000;
print();
*/
// 名字空间成员的声明
// 常用于函数中
using name::age;
age = 10000;
name::print();
return 0;
}
//结果:
1000
10000
3.6、名字空间的嵌套
//注:名字空间的嵌套基本不用
eg:
namespace name1{
int num;
namespace name2{
int num;
namespace name3{
int num;
}
}
}
name1::num;
name1::name2::num;
name1::name2::name3::num;
3.7、无名名字空间
// 对于全局的变量或者函数没有指定任何的名字空间,
// 编译器默认会将这些全局变量和函数放到无名名字空间中。
无名名字空间中的成员访问:
::成员名;
常用于区分作用域。
参考案例: 05namespace.cpp
#include <iostream>
using namespace std;
int num = 10086;
void print()
{
int num = 10010;
cout << num << endl;
cout << ::num << endl;
}
int main(int argc, char *argv[])
{
print();
return 0;
}
//结果:
10010
10086
四、C++中的数据类型
C++中的语法完全兼容C语法、C中的基本数据类型C++中完全兼容。
4.1、结构体 struct
eg:
struct tea{
char name[20];
int age;
int salary;
};
1. struct中的成员可以包含函数
struct tea{
...
void show(){
函数体;
}
};
2. struct 中的函数依然是全局的函数,不占用任何的结构体的空间。
sizeof(struct tea); // 28
访问结构体中的成员函数。
结构体类型变量名.函数名();
结构体类型指针变量->函数名();
3. 定义结构体类型的变量是可以省略 struct 关键字。
tea t = {"zhoukai", 18, 20000};
4. 结构体中的成员函数可以直接访问结构体中的成员变量。
参考案例: 06struct.cpp
#include <iostream>
using namespace std;
// 声明结构体类型
struct Teacher{
char name[20];
int age;
int salary;
void show(){
// 结构体成员函数可以直接访问结构体中的成员
cout << "姓名:" << name << endl;
cout << "年龄:" << age << endl;
cout << "工资:" << salary << endl;
}
};
int main(int argc, char *argv[])
{
// 定义结构体类型变量省略struct关键字
Teacher tea = {"zhoukai", 18, 20000};
tea.show();
Teacher *tea_p = &tea;
tea_p->show();
return 0;
}
// 结果:
姓名:zhoukai
年龄:18
工资:20000
姓名:zhoukai
年龄:18
工资:20000
4.2、联合体 union
1. 定义联合体类型变量是可以省略union关键字
2. C++之父不建议在C++开发中使用联合体。
联合体多个成员共享一块内存空间,C++之父认为这样不安全。
4.3、枚举 enum (建议多用)
1> 定义枚举类型变量是可以省略enum关键字
2> 可以直接使用枚举中的成员,枚举中的成员表示一个常量
3> 可以使用枚举替换常量宏
#define SUCCESS 0
#define ERROE 1
#define FAILED 2
enum statues{
SUCCESS = 0,
ERROE ,
FAILED,
};
eg:
statues func(){
// 函数体
....
if ()
return SUCCESS;
else if()
return ERROE;
else if()
return FAILED;
}
参考案例:07enum.cpp
#include <iostream>
using namespace std;
enum statues{
success = 0,
failed,
error,
};
statues func(statues num);
int main(int argc, char *argv[])
{
cout << func(success) << endl;
return 0;
}
statues func(statues num) {
// goto 一般用于出错处理
// goto 只能在函数内实现跳转
statues retval;
if (num == 0) {
retval = num;
goto ret;
} else if (num == 1) {
retval = num;
goto ret;
} else if (num == 2) {
retval = num;
goto ret;
}
ret:
return retval;
}
//结果:
0
//例如1:
#include <iostream>
using namespace std;
enum leds_t{
RED = 0,
GREEN ,
BLUE,
};
/*
* 函数功能 :
* 参数:
* 0 - 红灯
* RED - 红灯
* 返回值:
* */
void led_on(leds_t leds)
{
switch(leds){
case RED:
cout << "RED" << endl;
break;
case GREEN:
cout << "GREEN" << endl;
break;
case BLUE:
cout << "BLUE" << endl;
break;
}
}
int main(int argc, char *argv[])
{
led_on(RED);
return 0;
}
//例如2:
#include <iostream>
using namespace std;
// 定义一个枚举类型 ,执行时分配空间 4个字节
typedef enum led{
RED = 0,
GREEN ,
BLUE,
}leds_t;
void led_on(leds_t leds){
}
int main(int argc, char *argv[])
{
// 1. 枚举类型中的成员可以直接使用
cout << RED << endl;
// 2. 定义枚举类型的变量,需要使用枚举类型中的成员进行初始化
leds_t leds = GREEN;
cout << leds << endl;
leds = BLUE; // 修改枚举类型的变量
cout << leds << endl;
// 使用C++的编译器会报错,类型不匹配
// 使用gcc的编译器,不一定会报错
// g++比gcc编译器检查数据类型更加的严格
leds = (leds_t)3; // 不建议这样使用
cout << leds << endl;
return 0;
}
五、bool类型
1. bool 类型属于 C++ 中的基本数据类型,字节大小为 1 字节
2. 在 c 语言中 bool 类型不属于基本类型
使用时需要加 <stdbool.h>
3. bool 类型可以接收任意的整形数,
非零表示 true 零表示 false
ture 为 1, false 为 0,
4. boolalpha //使用后以 true 或 false 字符串显示
noboolalpha //使用后以 1 或 0 int型显示
//例如:
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
// 直接使用
cout << "true = " << true << endl;
cout << "false = " << false << endl;
// 定义布尔类型的变量
bool onOff = 1000;
cout << onOff << endl;
// 直接输出true或false 而不是0或1
cout << boolalpha << endl;
cout << true << endl;
cout << false << endl;
cout << onOff << endl;
cout << noboolalpha << endl;
cout << true << endl;
cout << false << endl;
return 0;
}
六、string 字符串类型
6.1、string类型属于C++中的一个类 类型
class string { // 类 类型
成员;
};
struct string{ // 结构体 类型
};
6.2、C语言表示字符串的方式
"hello" 字符串常量
char *str1 = "hello"; 字符指针
char str2[] = "hello" 字符数组
char *str3 = str2;
char *str4 = (char *)malloc(20);
strcpy(str4, "hello");
C++中使用string定义字符串
string str1 = "hello";
string str2 = "world";
6.3、使用string定义字符串支持数学运算
string str3 = str1 + str2; // 拼接
str1 = str2;
算数运算
+
条件判断 返回真假
>、< 、>=、<= 、!=、==
赋值
=
6.4、string类中实现了很多的方法(成员函数),
class string { // 类 类型
public:
int length(); // 计算字符串的长度
int size(); // 计算字符串的长度
char *c_str(); // 转换成C格式字符串
};
重点内容总结:
1. C++代码的框架和编译
2. 名字空间
namespace 名字空间名 {
全局的成员;
}
名字空间名::成员名;
using namesapce 名字空间名;
using 名字空间名::成员名;
:: --> 作用域限定符
无名名字空间
3. struct enum bool string
string(使用class关键字声明的一个新的类型)
(类 类型)
size()
length()
c_str()
七、引用
C++中的定义引用(reference)类型变量
7.1、语法格式
<数据类型> &引用名字 = 引用目标;
int a = 10;
int &re_a = a;
本质:引用可以当成指针来用。
int *const p = &a;
本质:给一个变量起一个别名
//参考案例:01refer.cpp
#include <iostream>
using namespace std;
void swap(int &a, int &b){
a = a ^ b;
b = a ^ b;
a = a ^ b;
}
int main(int argc, const char *argv[])
{
// 定义引用类型的变量
int a = 0x12345678;
int &r = a;
cout << "&a = " << &a << endl;
cout << "&r = " << &r << endl;
// 引用的好处
int a1 = 100;
int b1 = 200;
swap(a1, b1);
cout << "a1=" << a1 << "b1=" << b1 << endl;
// 使用引用时注意事项
// int &rr; 定义引用时必须指定引用的目标
// 引用和引用目标类型一致
// char ch = 'a';
// int &rr = ch;
// 引用目标被指定不可以修改
int z = 10086;
int y = 10010;
int &rr = z;
rr = y;
cout << "&z = " << &z << endl;
cout << "&rr = " << &rr << endl;
cout << "&y = " << &y << endl;
cout << "z = " << z << endl;
// 常引用
int x = 1000;
const int &x_r = x;
//x_r = 2000;
x = 2000;
cout << "x_r = " << x_r << endl;
return 0;
}
//结果:
&a = 0x7fffdefc4124
&r = 0x7fffdefc4124
a1=200b1=100
&z = 0x7fffdefc4118
&rr = 0x7fffdefc4118
&y = 0x7fffdefc4114
z = 10010
x_r = 2000
7.2、引用的好处
节约内存的开销
void swap(int *a, int *b){
*a = *a ^ *b;
*b = *a ^ *b;
*a = *a ^ *b;
}
void swap(int &a, int &b){
a = a ^ b;
b = a ^ b;
a = a ^ b;
}
int a1 = 100;
int b1 = 200;
swap(a1, b1);
7.3、使用引用时注意事项
1> 定义引用类型变量时,必须指定引用的目录
int &r; // error
2> 引用的类型和引用目标的类型必须一致
char ch = 'a';
int &r = ch; // error
3> 引用的目标一旦被指定不可以被修改
int a = 100;
int b = 200;
int &r = a;
r = b; // 不是修改引用的目标,而是赋值
回顾指针:
int *const p;
int const *p;
const int *p;
//参考案例:01refer.cpp
7.4、常引用
使用const修饰的引用
int a = 1000;
int const &r = a;
const int &r = a;
int & const r = a; // 没有,报错
注意:
使用 const 修饰的引用,可以访问,但是不可以修改被引用变量的值
不可以通过引用类型的变量修改引用的目标
r = 2000; // error
可以通过引用目标的自身修改值
a = 2000;
7.5、引用类型的返回值
1. 返回引用时,不可以返回局部变量的引用
只能返回全局变量的引用或者使用static修饰的局部变量。
2. 引用类型的返回是一个左值。
返回类型 &函数名(形参表)
左值:既可以放到等号左边也可以放到等号右边。
变量
右值:只能放到等号右边。
常量
函数的返回值 func() = 1000;
数组名 arr[] arr = arr+1
算数运算的结果 a+b=c
为了避免在函数的外边修改函数内部的变量,
笔试题:引用和指针的区别? (重点掌握)
1. 引用的本质就是指针,C++开发中尽量使用引用
2. 可以先定义指针类型变量在进行初始化, (除 int *const p = &a)
定义引用类型的变量时,必须指定引用的目标
3. 可以定义指针的指针(二级指针)
不可以定义引用的引用(二级引用)
int a = 100;
int *p = &a;
int **pp = &p;
---------------------
int a = 100;
int &r = a; // OK
int &&rr = r; // error
4. 可以定义指针的引用,不可以定义引用的指针
int a = 100;
int *p = &a;
int* &r = p; // 指针类型的引用 OK
----------------
int a = 100;
int &r = a;
int& *p = &r; // 引用类型的指针 ERROR
5. 可以定义指针数组,不可以定义引用数组
int a = 100, b = 200;
int *arr[2] = {&a, &b}; // OK
---------------------
int a = 100, b = 200;
int &arr[2] = {a,b}; // ERROR
6. 可以定义数组指针,可以定义数组引用
int arr[2] = {100,200};
int (*arr_p)[2] = &arr; // OK
---------------------
int arr[2] = {100,200};
int (&arr_r)[2] = arr; // OK
arr_r[0] + 1
7. 可以定义指针函数,也可以定义引用函数
int *func_p();
int &func_r();
8. 可以定义函数指针,也可以定义函数引用
int add(int a, int b){return a+b;}
int (*func_p)(int a, int b);
func_p = add;
------------------------------
int add(int a, int b){return a+b;}
int (&func_r)(int a, int b) = add;
八、C++中的函数
8.1 函数的重载
1> 相同的作用域下,函数的名字相同,
函数的参数列表不同,跟函数的返回值没有关系。
这样的函数可以构成重载的关系 。
函数的参数列表不同:
1> 参数的个数不同
2> 参数的类型不同
2> 重载函数的调用
调用时根据传递的实参的类型不同,
或者实参个数的不同,自动调用匹配自己版本的重载函数。
//参考案例:03funcreload.cpp
#include <iostream>
using namespace std;
// 以下三个swap函数可以构成重载关系
void swap(int a, int b)
{
cout << "swap(int, int)" << endl;
a ^= b;
b ^= a;
a ^= b;
}
void swap(float a, float b)
{
cout << "swap(float, float)" << endl;
float tmp;
tmp = b;
b = a;
a = tmp;
}
void swap(int a, int b, int c)
{
cout << "swap(int, int, int)" << endl;
a = c;
a ^= b;
b ^= a;
a ^= b;
}
int main(int argc, const char *argv[])
{
int a = 100, b = 200;
swap(a, b);
float f1 = 3.14, f2 = 3.15;
swap(f1, f2);
int c = 300;
swap(a, b, c);
return 0;
}
//结果:
swap(int, int)
swap(float, float)
swap(int, int, int)
3> c++中可以实现函数重载的本质
预处理 -E
编译 -S
汇编 -c
链接 -C
swap(int, int)
_Z4swapii:
_Z4: 前缀
swap:函数名
ii: 形参类型的首字符
//参考 03funcreload.s文件
swap(int, int) -->
.LC0:
.string "swap(int, int)"
.text
.globl _Z4swapii
.type _Z4swapii, @function
_Z4swapii:
swap(float, float) -->
.LC1:
.string "swap(float, float)"
.text
.globl _Z4swapff
.type _Z4swapff, @function
_Z4swapff:
swap(int, int, int) -->
.LC2:
.string "swap(int, int, int)"
.text
.globl _Z4swapiii
.type _Z4swapiii, @function
_Z4swapiii:
8.2、函数的缺省参数
1> 定义函数时,可以给函数的形参指定一个缺省值
这样的函数叫做带有缺省参数的函数
int add(int a, int b = 200){}
2> 调用带缺省参数的函数时,如果传递了实参,
优先使用传递的实参,如果没有传递实参才会使用缺省值。
3> 缺省参数遵循靠右的原则,带有缺省值的参数,
写到形参表的最右边
int add(int a, int b = 200, int c){} // error
add(1000,2000);
4> 声明和定义分开写是,函数的参数的缺省值放到
函数的声明位置。
8.3、函数哑元参数
1> 在函数的列表中只有函数的类型,没有形参名,这样的参数叫做哑元参数。
int add(int a, int b = 200, char){}
2> 跟其他函数构成重载的关系
3> 代码的迭代升级
eg:
升级之前:
int bar(int num);
升级之后:
int bar(void); // 构成重载
int bar(int); // 函数体中代码完全一致。
调用:
bar(1000); // 1000此调用。
bar();
九、C++中的动态内存分配
- 动态内存分配
C语言:malloc/free
C++语言:new/delete
- 语法格式:
new / delete : 分配数据类型所占空间的大小
new [] / delete [] : 分配连续的空间
eg:
int *p = new int; // 分配4个字节空间
delete p;
p = NULL;
int *p = new int[10] // 分配连续的40个字节空间
delete[] p; // 中括号不可以省略
p = NULL;
//参考案例: 07new.cpp
#include <iostream>
using namespace std;
int main(int argc, const char *argv[])
{
int *p = new int;
*p = 10086;
cout << "p = " << p << endl;
cout << "*p = " << *p << endl;
delete p;
p = NULL;
int *arr_p = new int[10];
for(int i = 0;i<10;i++)
{
arr_p[i] = i;
}
for(int i = 0;i<10;i++)
{
cout << "arr_p[" << i << "] = " << arr_p[i] << endl;;
}
delete[] arr_p;
arr_p = NULL;
return 0;
}
//结果:
p = 0x1561e70
*p = 10086
arr_p[0] = 0
arr_p[1] = 1
arr_p[2] = 2
arr_p[3] = 3
arr_p[4] = 4
arr_p[5] = 5
arr_p[6] = 6
arr_p[7] = 7
arr_p[8] = 8
arr_p[9] = 9
- new的同时可以进行初始化
数据类型 *指针变量名 = new 数据类型(初始值);
数据类型 *指针变量名 = new 数据类型[index]{初始值列表};
//参考案例: 08new.cpp
#include <iostream>
using namespace std;
int main(int argc, const char *argv[])
{
int *p = new int(10086);
cout << "p = " << p << endl;
cout << "*p = " << *p << endl;
delete p;
p = NULL;
int *arr_p = new int[10]{1,2,3,4,5,6,7,8,9,10};
for(int i = 0;i<10;i++)
{
cout << "arr_p[" << i << "] = " << arr_p[i] << endl;;
}
delete[] arr_p;
arr_p = NULL;
return 0;
}
//结果:
p = 0x1344e70
*p = 10086
arr_p[0] = 1
arr_p[1] = 2
arr_p[2] = 3
arr_p[3] = 4
arr_p[4] = 5
arr_p[5] = 6
arr_p[6] = 7
arr_p[7] = 8
arr_p[8] = 9
arr_p[9] = 10
笔试题: new/delete 和malloc/free的异同点
相同点:都属于动态内存分配,在堆区分配空间
不同点:
1. malloc/free属于C语言中的标准函数
new/delete属于C++中的操作符
2. malloc只能用于分配空间,分配空间的初始值不确定。
new用于分配空间时,分配的空间初始值为0(未进行初始化)
3. malloc只能分配,不能初始化
new的同时可以进行初始化。
4. 在C++中尽量使用new/delete
不要使用malloc/free.
练习题:
自定义一个student的结构体类型,
使用new去分配空间。要求struct中包含成员变量和函数
class和struct的区别
1. 默认访问权限不同
class默认访问权限为private
struct默认访问权限为public
2. 类成员的作用域
1. 类成员的作用域都在类内,外部无法访问
2. 成员函数可以直接访问和调用成员变量
3. 类的外部可以通过public访问到类内的成员
4. 类成员的作用域与访问级别没有关系
5. struct默认访问权限为public
十. 内联函数
10.1 inline 关键字
1. 在C++中推荐使用内联函数替代宏代码片段
define MAX(a, b) (a)<(b)?(b):(a)
2. 使用方法
inline int max(int a, int b)
{
return a<b?b:a;
}
10.2 注意事项
- 内联函数的定义必须在函数调用前,inline必须跟着函数定义 ,否则编译器会忽略这个内敛请求
- 函数体中不能有循环语句
- 函数体篇幅不能过大
- 适用的场景,函数调用次数很多,代码量很小
10.3 内联函数和宏定义的区别
- 内联函数有函数的基本属性,有变量类型和作用域的检查
- 宏定义只是在预处理阶段进行字符串的替换,无法检查语法错误
- 内联函数的内敛请求有可能被编译器拒绝
浙公网安备 33010602011771号