C++函数
函数
为什么要使用函数
已经有main函数,为什么还要自定义函数?:“避免重复制造轮子”,提高开发效率
函数的定义
函数的设计方法:先确定函数的功能、确定函数的参数、是否需要参数,参数的个数,参数的类型、确定函数的返回值:是否需要返回值,返回值的类型、确定函数名: 函数名一定要顾名思义。函数名的命名方法, 和变量名相同
函数的调用和声明
实参和形参:函数调用时, 实参的值, 传递给形参。即, 形参被赋值为实参.
函数声明
函数声明\函数定义\函数调用的顺序
函数参数的传递方式
调用函数时,形参被赋值为对应的实参,实参本身不会受到函数的影响!
数组作为函数参数
#include <iostream>
#include <Windows.h>
using namespace std;void scorePrint(int score[], int n)
{for (int i=0; i<n; i++) { cout << "第" << i+1 << "门成绩 : " << score[i] << endl;}
}
//每个成绩加5分
void scoreAdd(int score[], int n, int val)
{for (int i=0; i<n; i++) {score[i] += val;}
}int main(void) {
int score[3] = {60, 70, 80};
scorePrint(score, 3);
scoreAdd(score, 3, 5);
scorePrint(score, 3);
system("pause");
return 0;
}
默认参数
注意: C语言不支持函数的默认参数!
//每个成绩加5分
// 默认参数, 只能出现在参数列表的最后, 即默认参数后面, 不能有普通参数
void scoreAdd2(int score[], int n, int val=5)
{for (int i=0; i<n; i++) {score[i] += val;}
}
函数的重载(同名不同命)
C++可以使用同名函数[重载函数]实现功能类似的多个不同函数.
int add(int a, int b)
{cout << "调用add版本1" << endl;return a +b;
}float add(float a, float b)
{cout << "调用add版本3" << endl;return a+b;
}
函数名重载:函数名相同,但是,,函数的参数(形参)绝不相同:参数个数不同、或参数个数相同, 但是参数的类型不同。只有返回类型不同,不能构成函数重载;只有形参变量名不同, 不能构成函数重载。
注意: C语言不支持函数重载
函数的栈空间
要避免栈空间溢出。当调用一个函数时,就会在栈空间,为这个函数,分配一块内存区域,这块内存区域,专门给这个函数使用。这块内存区域,就叫做“栈帧”。
#include <iostream>
#include <Windows.h>void test(void)
{
//运行时将因为栈帧空间溢出,而崩溃char buff[2000000]; std::cout << (int)buff[sizeof(buff) - 1] <<std::endl;
}int main(void)
{test();system("pause");return 0;
}
内联函数(极速调用)
函数的作用:避免重复制造轮子。(避免重复多次写相同的代码)
函数的缺点:每调用一次函数,就会为这个函数分配一个“栈”,在计算机底层做很多准备工作(保护原来的执行环境,切换到新的执行环境)。有一定的“时间开销”
解决方案:使用内联函数
内联函数:当编译器在编译时, 如果遇到内联函数,就会直接将整个函数体的代码插入”调用处”,就相当于内联函数的函数体, 在调用处被重写了一次。以避免函数调用的开销, 获得更快的时间。
内联函数的缺点:使调用内联函数的程序,变得“臃肿”,消耗调用函数的“栈”空间。
内联函数的用法:
inline int add(int a, int b)
{return a + b;
}
内联函数的使用场合:
1)内联函数中的代码应该只是很简单、执行很快的几条语句。
2)这个函数的使用频度非常高,比如在一个循环中被千万次地使用。
递归函数(多重梦境)
定义:在函数的内部,直接或者间接的调用自己。
要点:再定义递归函数时,一定要确定一个“结束条件”!!!
使用场合:处理一些特别复杂的问题,难以直接解决。但是,可以有办法把这个问题变得更简单(转换成一个更简单的问题)。
设计递归函数的要点:把问题拆解成问题本身, 但是拆解后的问题的”规模”更小, 或者难度更低。
经典实例:斐波那契数列、汉诺塔问题
递归函数的缺点:性能很低!!!实际开发中, 极少使用!还有可能会导致堆栈空间被多重递归消耗掉,导致程序崩掉。
递归函数的调用过程: