认识c语言中的函数
目录
一.函数
1.库函数
2.自定义函数
1.为什么这个int compare(int a,int b){}这一堆代码要放在int main(){}上面啊?
A.函数的声明
2.这个int max=compare(a, b);里面的compare(a,b)的a和b是什么呀,int compare(int a,int b)里面吗的int a和int b又是什么,为什么这么放?
A.实参
B.形参
C.至于为什么这么做?
3.这个自定义函数起名字有什么用或者有什么影响吗?
4.如果我在自定义函数里面再定义一个自定义函数可不可以?
5.如果在int max=compare(a, b);里面的compare(a,b)可以写成compare(a,compare(a,b))这样吗?
A.函数的链式结构
6.为什么用这个函数可以得到一个值啊,这个函数里面的return有什么用,还有这个函数为什么要用int啊?
二.函数的调用
1.传值调用
2.传址调用
一.函数
1.库函数
定义:
库函数是编译器或语言标准提供的一组预定义函数,这些函数被封装在库中,供用户直接在程序中使用。
这个定义听起来很高大上,但是其实我们新手也常常用到它们。比如说打印函数printf(),输入函数scanf(),还有求绝对值abs(),求字符串长度strlen(),这些都是库函数。
我们在使用库函数的时候要记得加上其对应的头文件#include,每个库函数都有其对应的头文件#include
比如说printf()和scanf()函数是属于#include头文件的,
abs()属于#include,
strlen()属于#include。
库函数有很多很多,但是我们并不是全都要学习,我们只需要学习我们经常需要用到的,或者是比较常见的就可以了,亦或者你想要学习一些少见且好用的功能可以去有关库函数的网站去查阅资料,这里推荐一个安全好用的网站:https://cplusplus.com/
2.自定义函数
什么是自定义函数?
其实也就是字面意思,相较于库函数,自定义函数能够让我们自由发挥,而且和库函数一样,都有参数和函数名
这里我们看一个例子,求两个数的最大值:
#include int compare(int a,int b) { if (a > b) { return a; } else { return b; } } int main() { int a = 0; int b = 0; scanf("%d %d", &a, &b); int max=compare(a, b); printf("%d", max); return 0; }
可以看到代码还是很成功的,我们自定义了一个compare()函数,但是疑问就来了:
1.为什么这个int compare(int a,int b){}这一堆代码要放在int main(){}上面啊?
2.这个int max=compare(a, b);里面的compare(a,b)的a和b是什么呀,int compare(int a,int b)里面吗的int a和int b又是什么,为什么这么做?
3.这个自定义函数起名字有什么用或者有什么影响吗?
4.如果我在自定义函数里面再定义一个自定义函数可不可以?
5.如果在int max=compare(a, b);里面的compare(a,b)可以写成这样吗?比如:compare(a,compare(a,b))。
6.为什么用这个函数可以得到一个值啊,这个函数里面的return有什么用,还有这个函数为什么要用int啊?
1.为什么这个int compare(int a,int b){}这一堆代码要放在int main(){}上面啊?
这个问题涉及到函数的声明
A.函数的声明
函数声明的作用是把函数名、函数类型及形参的类型、个数和顺序通知编译系统,以便在调用该函数时编译系统能正确识别函数并检查调用是否合法。
由于编译器他是默认从代码的上往下遍历的,所以我们需要把自定义函数的代码写在你使用这个函数的地方的上面,也就是我们这里的主函数main()的上面,否则,你需要声明这个函数
我们来看反过来的代码:
#include int main() { int a = 0; int b = 0; scanf("%d %d", &a, &b); int max=compare(a, b); printf("%d", max); return 0; } int compare(int a,int b) { if (a > b) { return a; } else { return b; } }
那我们来修改一下:
#include int compare(int a,int b); int main() { int a = 0; int b = 0; scanf("%d %d", &a, &b); int max=compare(a, b); printf("%d", max); return 0; } int compare(int a,int b) { if (a > b) { return a; } else { return b; } }
可以看到我们在main()上面加上了函数的声明,这时就不会发生报错了.
2.这个int max=compare(a, b);里面的compare(a,b)的a和b是什么呀,int compare(int a,int b)里面吗的int a和int b又是什么,为什么这么放?
这里则涉及到函数的参数。
函数的参数又分为实参和形参。
A.实参
实参是在调用函数时传递给函数的参数。它们可以是常量、变量、表达式、函数等。无论实参是何种类型的量,在进行函数调用时,它们都必须具有确定的值,以便把这些值传送给形参。
所以int max=compare(a, b);里面的compare(a,b)的a和b就是实参。
B.形参
形式参数是指函数名后括号中的变量,因为形式参数只有在函数被调用的过程中才实例化(分配内存单元),所以叫形式参数。形式参数当函数调用完成之后就自动销毁了。因此形式参数只在函数中有效。
int compare(int a,int b)里面吗的int a和int b就是形参
C.至于为什么这么做?
因为我们需要把实参传给形参,函数把实参传给形参是为了在函数内部使用这些参数进行计算,并且确保实参的值在函数调用结束后保持不变。
3.这个自定义函数起名字有什么用或者有什么影响吗?
不会有什么影响,不过我们在给函数起名字的时候一般都是取一些比较有意义的名字,比如说我们要建立一个交换函数,我们可以起swap(意思是交换),还有如果要建立一个比较函数,我们可以compare(意思是比较),如果我们起的名字是由两个或两个单词以上组成的,我们通常是以驼峰式来起,比如说init board(初始面板),我们起为:InitBoard,(每个单词的首字母都要大写)
4.如果我在自定义函数里面再定义一个自定义函数可不可以?
可以,比如说:
#include int compare2(int a, int b) { if (a > b) { return a; } else { return b; } } int compare(int a,int b) { return compare2(a, b); } int main() { int a = 0; int b = 0; scanf("%d %d", &a, &b); int max=compare(a, b); printf("%d",max); return 0; }
可以看到我们在compare函数里面又建立了一个自定义函数compare2,最终结果还是一样。
不过要注意的是:我们通常不会在自定义函数里面建立另外一个自定义函数,因为这样容易混乱,当我们这样嵌套了多个函数,在我们过一段时间再回头看的时候可能都不知道这些函数有什么用了,所以只能说可以这么用,但是不推荐.
5.如果在int max=compare(a, b);里面的compare(a,b)可以写成compare(a,compare(a,b))这样吗?
可以,这是
A.函数的链式结构
就是把一个函数的返回值作为另外一个函数的参数(实参)。
6.为什么用这个函数可以得到一个值啊,这个函数里面的return有什么用,还有这个函数为什么要用int啊?
因为函数中的return语句主要用于结束函数的执行并返回一个值给调用者,而我们主函数main()中的return 0;就是结束该主函数。
int 说明我们返回的值是整型,如果我们要返回字符型,就用char,等等。或者我们可能只希望交换一下几个数的位置啊,就不需要返回值的时候我们可以用void。
二.函数的调用
1.传值调用
顾名思义,传值调用就是直接将实参的值传递给形参。
方法在调用参数时,不是对原参数进行操作,而是创建参数的拷贝并对其进行操作
2.传址调用
函数传址调用,也称为传地址调用或传引用调用,是一种函数参数的传递方式,其中函数的参数是通过传递变量的内存地址(即指针,指针我后面发的文章会讲)来实现的。
这种方式允许函数直接操作函数外部的变量,因为函数内部可以通过指针直接访问和修改原始变量的值。
这是我不用传址调用的代码(交换输入的两个数):
void swap(int a, int b) { int temp = a; a = b; b = temp; } int main() { int a = 0; int b = 0; scanf("%d %d", &a, &b); printf("现在a=%d b=%d\n", a, b); swap(a, b); printf("交换后a=%d b=%d", a, b); return 0; }
使用传址调用后:
#include void swap(int *a, int *b) { int temp = *a; *a = *b; *b = temp; } int main() { int a = 0; int b = 0; scanf("%d %d", &a, &b); printf("现在a=%d b=%d\n", a, b); swap(&a, &b); printf("交换后a=%d b=%d", a, b); return 0; }
可以看到明显的区别,在c语言中我们不能够直接从函数内部访问函数外部的变量,但是我们可以通过传址调用来实现。因为传址调用直接将变量的内存地址传递给函数参数,使得函数内部可以直接操作函数外部的变量。
点个赞吧~~~