1.函数默认值参数:在函数声明或者定义的时候,给定参数默认值,如果实参传递时,不给该形参传递,则会按照该默认值传参
2.函数参数的默认值是在编译期(把代码翻译成指令)生成指令的时候,直接生成入参指令
3.函数参数的默认值只能传递常量。为什么不能传递变量?
int data = 10; int fun(int a,int b,int data)//错误,变量在编译时期是不能获取到真实值,只有在运行时期可以拿到变量的值 { cout<<a<<endl; cout<<b<<endl; cout<<c<<endl; return 0; } int main() { fun(1,2); }
4.函数在默认值赋值时,只能从右往左依次赋值
int fun(int a,int b,int c = 20)//函数定义 { cout<<a<<endl; cout<<b<<endl; cout<<c<<endl; return 0; } int fun(int a,int b = 10,int c);//函数声明 //此处注意:无论在函数定义或者是函数声明时,都可以为默认值参数赋值 int main() { fun(1); } /*运行结果 1 10 20 */
5.函数的默认值参数在同一作用域只能复制一次,不能重复赋值
int fun(int a,int b,int c = 20) { cout<<a<<endl; cout<<b<<endl; cout<<c<<endl; return 0; } int fun(int a,int b,int c = 30);//错误 int main() { fun(1,2); } //结果崩溃
6.因为函数参数的默认值是在编译期带入的,所以函数参数的默认值只在本文件内生效
1.在调用内联函数时,会在调用点展开。
2.在debug(测试版本)版本中,内联函数与普通函数调用方式一致,在release(发行版本)版本,会在调用点展开--------编译时期展开
3.由于内联函数在编译时期展开,编译期无法获取变量的值,而递归函数的终止条件一定需要有变量参与。所以递归函数不可能被处理成内联函数
4.为什么要有内联函数?看一看正常函数的调用你就知道了。正常函数调用:(1)传参 (2)call fun( 3)开辟栈帧 (4)返回值返回 (5)栈帧回退 (6)参数清除 这六个步骤开销太大了。
5.inline只是对系统的建议,建议将函数处理成内联函数
6.四种函数的比较
函数 | |
---|---|
宏函数 #define sum(a,b){a+b}; | 1.预编译时期在调用点展开 2.无法调试 3.没有类型安全校验 4.没有栈帧的开辟 5.单文件可见 6.不生成符号 |
static函数 | 1.不展开 2.可以调试 3.有类型安全校验 4.有栈帧的开辟 5.单文件可见 6.生成local符号 |
内联函数 | 1.debug版本不展开,release版本在调用点展开 2.可以调试 3.有类型安全校验 4.在debug版本有栈帧开辟,release版本无栈帧开辟 5.单文件可见 6.debug版本生成local符号,release版本不生成符号 |
普通函数 | 1.不展开 2.可以调试 3.有类型安全校验 4.有栈帧开辟 5.多文件可见 6.生成global符号 |
7.为什么release版本不生成符号?因为release版本在编译时就已经展开了
8.为什么debug版本生成local符号?因为在release发行版本中要展开,防止找不见函数
我们所写的代码中有两种东西 1.数据 2.指令
1.数据:只有全局变量和静态变量是数据,所有的数据都可以生成符号
2.指令:指令中只有函数名可以生成符号
3.符号:分为(1)全局符号global(2)局部符号local:只有在本文件可以用
int data1;//是数据,生成全局符号 static int data2;//是数据,生成局部符号,只在本文件可见 int main() { static int data3;//是数据 int data4; //不是数据,是指令 } //为什么会生成符号?我认为原因可能是这些变量或者函数需要唯一标识
4.inline在debug版本中生成的local的符号,如果处理为内联之后,在release版本中不生成函数,直接在调用点展开
5.在一个函数中,如果只有函数的声明,编译时生成的是“UND”未定义符号,编译时如果找到此函数的定义,则摆脱“UND”符号