1.函数定义模板:返回类型 函数名 (参数1,参数2,参数3······){函数体内容及参数}
void sort(int *array){} void(返回类型)sort(函数名称)(int *array)(函数参数){函数体}
2.函数声明
1)为什么要有申明?
因为计算机是从主函数从上到下执行的,如果函数定义在使用之前,自然不需要定义,因为计算机已经识别了函数,但如果没有,计算机就会报”无法解析的外部命令“的错误,但是在工程和编写大的程序时这样的方法就不现实了,这样会严重影响函数的可读性,函数的申明就是为了让计算机提前识别函数。
2)函数声明的格式(以前面函数为例,放在使用之前)
void sort(int* array);
3.函数栈帧的建立与销毁,接下来先理解示范代码
#include<stdio.h> int Add(int a, int b) { return a + b; } int main() { int a, b; scanf("%d%d", &a, &b); int c = Add(a, b); return 0; }
1)函数名其实是地址,函数只有一份,在计算机运行到这里的时候它就会通过地址找到函数,但是在它进入函数是还要有几个操作,首先保存当前运行的地址,然后将参数进行压栈拷贝一份(仅限传值),然后通过在进入函数,在函数执行完毕后就会进行销毁出栈,接下来看我下面的图理解
2)拓展
1)函数指针为何物?
大家都知道有整形指针,浮点型指针,那么既然函数名是一个地址,那我们能不能用指针来接收它的地址呢,答案是YES。既然我们知道函数是能用指针来接收的,那我们应该如何来接收它呢?首先指针的类型是与函数返回值相同的,其次要有 * ,然后应该是指针的命名,为了保证 * 和指针名字结合,需要用括号合并二者,后面则是函数的参数类型,不一定要有参数的名称,但需要点明参数的类型。接下来我们展示一下如果写出函数相对应的指针
1) int Add(int a,int b); //一一对应 int (*ptr)(int ,int )=Add; 2) int *ButNode(struct Node* List, int n); //一一对应 int *(*ptr)(struct Node*,int)=BuyNode;
2)主函数的讨论
主函数虽然是多了一个主字,但是它本质也是函数,本质它是第一个执行的函数,主函数是通过编译系统已经存在的函数引用的,由于其中涉及到底层的实现原理,考虑难度较大,我这里推荐使用VS2019去观察主函数之前代码的运行,观察步骤较为复杂,这里不做过多描述,请查阅网上资料自行探索。接下来你可以去了解一下函数的有意思用法,如函数递归,有一种化繁为简的美学。
如果大家有收获的话不如三连(关注加点赞加收藏)see you