函数(上)
一. 函数的概念
数学中我们其实就见过函数的概念,比如:一次函数y=kx+b,k和b都是常数,给⼀个任意的x,得到⼀个y值。
其实在C语言也引入函数(function)的概念,有些翻译为:子程序,子程序这种翻译更加准确⼀些。C语言中的函数就是⼀个完成某项特定的任务的⼀小段代码。这段代码是有特殊的写法和调用方法的。也就是说C语言的程序其实是由无数个小的函数组合而成的,也可以说:⼀个大的计算任务可以分解成若干个较小的函数(对应较小的任务)完成。
二. 函数的使用
1. 库函数和自定义函数
C语言中的函数也分为两种,一种是库函数,我们称它为C语言中已经实现的函数,比如像printf、scanf等函数,已经不需要程序员自己编写而是直接使用的函数。另一种是自定义函数,也就是需要程序员自己创造,自定义函数其实更加重要,也能给程序员写代码更多的创造性。
(1) 库函数
在这里要说明一下,我们使用库函数并不是简单的直接使用,每一个库函数都有它自己相应的头文件,我们只有调用出了这个头文件才能使用对应的库函数,比如我们使用printf函数,我们要在开头加上#include <stdio.h>;再者我们如果使用strlen函数,我们也要加上#include <string.h>,所以后面我们也要了解函数所对应的头文件。
(2) 自定义函数的形式
首先来讲函数的语法形式,下面给大家一张图了解清楚:
也就说自定义函数也是有一个规范使用的格式,我们是照着这样的格式一步步去写属于我们自己的代码,比如说现在我要实现一个加法的代码,我应该怎么去写这个函数,下面给大家举一个简单的例子说明:下面展示一些 内联代码片
。
int Add(int x,int y) { int z=0; z=x+y; return z; }
上面的代码就是一个很简单的加法运算,int就代表我们的函数返回的类型是整形,而Add就是我们的函数名,如果后期要使用,我们就直接可以调用这个函数的名字进行使用,(int x,int y)就代表了我们要传入的形式参数,后面也会再详细教大家如何使用。
2. 形参和实参
在函数使用的过程中,把函数的参数分为,实参和形参。也就是我们在使用函数的时候,函数体本身和需要调用函数的那部分是分开的,我们也可以通过一个简单的例子向大家说明,我们还使用一个简单的加法的运算:下面展示一些 内联代码片
。
1 int Add(int x, int y) 2 { 3 int z = 0; 4 z = x + y; 5 return z; 6 } 7 int main() 8 { 9 int a = 0; 10 int b = 0; 11 scanf("%d %d", &a, &b); 12 int r = Add(a, b); 13 printf("%d\n", r); 14 return 0; 15 }
上面就是一个简单的使用自定义函数的代码展示我们可以看到1~6行是我们Add函数的代码,而我们在第12行真正调用了这个函数,我们把函数的返回值赋给r,而也就是在这个里面我们向Add函数里面传入的a和b叫做实参,实际参数就是真实传递给函数的参数。在上面代码中,第1行定义函数的时候,在函数名Add后面的x和y叫做形式参数,也叫做形参。为什么叫形式参数呢?实际上,如果只是定义了Add 后的括号中写的x和y,而不去调用这个函数的话,那么x和y就只是形式上的存在,不会向内存申请空间,不会真实存在,形式参数只有在函数被调用的过程中为了存放实参传递过来的值,才向内存申请空间,这个过程就是形参的实例化。
3. return语句
其实在前面的例子中大家也可以看到在函数的设计中,函数中经常会出现return语句,这⾥讲⼀下return语句使用的注意事项。
• return后边可以是⼀个数值,也可以是⼀个表达式,如果是表达式则先执行表达式,再返回表达式的结果。
• return后边也可以什么都没有,直接写return,这种写法适合函数返回类型是void的情况。
• return返回的值和函数返回类型不一致,系统会自动将返回的值隐式转换为函数的返回类型。
• return语句执行后,函数就彻底返回,后边的代码不再执行。
• 如果函数中存在if等分支的语句,则要保证每种情况下都有return返回,否则会出现编译错误。
4. 数组做函数参数
在使用函数解决问题的时候,难免会将数组作为参数传递给函数,在函数内部对数组进行操作。比如:写⼀个函数将⼀个整型数组的内容,全部置为-1,再写⼀个函数打印数组的内容。简单思考⼀下,基本的形式应该是这样的:下面展示一些 内联代码片
。
void set_arr(int arr[], int sz) { int i = 0; for (i = 0;i < sz; i++) { arr[i] = -1; } } void printf_arr(int arr[], int sz) { int i = 0; for (i = 0; i < sz; i++) { printf("%d ", arr[i]); } printf("\n"); } int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int sz = sizeof(arr) / sizeof(arr[0]); set_arr(arr, sz); //将数组全部置换为-1 printf_arr(arr, sz); //打印数组内容 return 0; }
从代码我们可以看出来,上面的set_arr函数要能够对数组内容进行设置,就得把数组作为参数传递给函数,同时函数内部在设置数组每个元素的时候,也得遍历数组,需要知道数组的元素个数。所以我们需要给set_arr传递2个参数,⼀个是数组,另外⼀个是数组的元素个数。仔细分析print_arr也是⼀样的,只有拿到了数组和元素个数,才能遍历打印数组的每个元素。
另外我们要注意的是在调用函数的时候,我们可以只传入数组名和元素个数,但是在写函数的时候我们在前面仍然要加上类型,这里我们需要知道数组传参的几个重点知识:
• 函数的形式参数要和函数的实参个数匹配
• 函数的实参是数组,形参也是可以写成数组形式的
• 形参如果是⼀维数组,数组大小可以省略不写
• 形参如果是⼆维数组,行可以省略,但是列不能省略
• 数组传参,形参是不会创建新的数组的
• 形参操作的数组和实参的数组是同⼀个数组
以上就是关于函数的部分知识,希望可以帮到大家,我也会及时更新关于函数的另一部分内容。