如果函数的实参经常是同一个值, 可以考虑使用默认参数
函数重载、默认参数可能会产生冲突、二义性(建议优先选择使用默认参数)
原理:
C++代码
汇编代码:
备注:E8是call的指令,E8后面的一串是根据下一条指令算出来的,具体参见intel的汇编指令白皮书。
extern “C”
规则
被
extern
"C"
修饰的代码会按照C语言的方式去编译
如果函数同时有声明和实现,要让函数声明被extern "C"修饰,函数实现可以不修饰
有时也会在编写C语言代码中直接使用extern “C” ,这样就可以直接被C++调用
通过使用宏__cplusplus来区分C、C++环境
#pragma once
我们经常使用
#ifndef
、
#define
、
#endif
来防止头文件的内容被重复包含
◼
#pragma once
可以防止整个文件的内容被重复包含
◼
区别
#ifndef
、
#define
、
#endif
受C\C++标准的支持,不受编译器的任何限制
有些编译器不支持
#pragma once
(较老编译器不支持,如GCC 3.4版本之前),兼容性不够好
#ifndef
、
#define
、
#endif
可以针对一个文件中的部分代码,而
#pragma once
只能针对整个文件
内联函数(inline function)
规则
◼
使用
inline
修饰函数的声明或者实现,可以使其变成内联函数
建议声明和实现都增加
inline
修饰
◼
特点
编译器会将函数调用直接展开为函数体代码
可以减少函数调用的开销
会增大代码体积
◼
注意
尽量不要内联超过10行代码的函数
有些函数即使声明为
inline
,也不一定会被编译器内联,比如递归函数
debubg下不会内联,只有release下优化才会出现内联
VS窥探内联的本质
内联函数与宏
◼
内联函数和宏,都可以减少函数调用的开销
◼
对比宏,内联函数多了语法检测和函数特性
◼
思考以下代码的区别
#define
sum
(x) (x + x)
inline int
sum(
int
x
) {
return
x
+
x
; }
int
a = 10; sum(a++);
const
◼
const
是常量的意思,被其修饰的变量不可修改
如果修饰的是类、结构体(的指针),其成员也不可以更改
◼
以下5个指针分别是什么含义?
int 和const是可以替换的,两者位置互换效果一致!
◼
上面的指针问题可以用以下结论来解决:
const
修饰的是其右边的内容
解释如下:
demo如下:
引用(Reference)
规则
◼
在C语言中,使用指针(Pointer)可以间接获取、修改某个变量的值
◼
在C++中,使用引用(Reference)可以起到跟指针类似的功能
◼
注意点
引用相当于是变量的别名(基本数据类型、枚举、结构体、类、指针、数组等,都可以有引用)
对引用做计算,就是对引用所指向的变量做计算
在定义的时候就必须初始化,一旦指向了某个变量,就不可以再改变,“从一而终”
可以利用引用初始化另一个引用,相当于某个变量的多个别名
不存在【引用的引用、指向引用的指针、引用数组】
◼
引用存在的价值之一:比指针更安全、函数返回值可以被赋值
引用的本质
◼
引用的本质就是指针,只是编译器削弱了它的功能,所以引用就是弱化了的指针
指令代码一模一样
◼
一个引用占用一个指针的大小
◼
引用可以被
const
修饰,这样就无法通过引用修改数据了,可以称为常引用
const
必须写在&符号的左边,才能算是常引用
◼
const
引用的特点
可以指向临时数据(常量、表达式、函数返回值等)
可以指向不同类型的数据
作为函数参数时(
此规则也适用于
const
指针
)
✓
可以接受
const
和非
const
实参(非
const
引用,只能接受非
const
实参)
✓
可以跟非
const
引用构成重载
◼
当常引用指向了不同类型的数据时,会产生临时变量,即引用指向的并不是初始化时的那个变量
数组的引用
◼
常见的2种写法
汇编语言
AT&T汇编 vs Intel汇编
x64汇编 – 寄存器
◼
一般的规律
R开头的寄存器是64bit的,占8字节
E开头的寄存器是32bit的,占4字节
x64汇编 – 寄存器
x64汇编要点总结
◼
mov dest, src
将src的内容赋值给dest,类似于dest = src
◼
[ 地址值 ]
中括号[ ]里面放的都是内存地址
◼
word
是
2
字节,
dword
是
4
字节(double word),
qword
是
8
字节(quad word)
◼
call 函数地址
调用函数
◼
lea dest, [ 地址值 ]
将地址值赋值给dest,类似于dest = 地址值
◼
ret
函数返回
◼
xor op1, op2
将op1和op2异或的结果赋值给op1,类似于op1 = op1 ^ op2
◼
add op1, op2
类似于op1 = op1 + op2
◼
sub op1, op2
类似于op1 = op1 - op2
◼
inc op
自增,类似于op = op + 1
◼
dec op
自减,类似于op = op – 1
◼
jmp 内存地址
跳转到某个内存地址去执行代码
j开头的一般都是跳转,大多数是带条件的跳转,一般跟test、cmp等指令配合使用
◼
权威参考:Intel白皮书
https://software.intel.com/en-us/articles/intel-sdm
内联汇编
变量地址总结
◼ 一个变量的地址值,是它所有字节地址中的最小值