1.函数的概念
函数:founction
c语言的程序代码都是函数组成的
c语言中的函数就是一个完成某项特定的任务的一段代码,这段代码有特殊的写法和调用方法
c语言中我们一般见到两种函数:
.库函数
.自定义函数
2.库函数
有对应的头文件
#include <math.h> int main() { double r = sqrt(16); printf("%lf\n", r); return 0; } 用sqrt求平方根一定要添加头文件#include <math.h>
3.自定义函数
ret_type是用来表示函数计算结果的类型,
函数的参数可以是void,明确表示函数没有参数
//函数的定义 int Add(int x, int y) { int z = 0; z = x + y; return z;// return z把z的值返回到c里面 } int main() { int a = 0; int b = 0; //输入 scanf("%d %d", &a, &b); //计算 //int c = a + b; int c = Add(a, b);//使用函数,调用函数,调用函数就跑到1~7行调用函数了,把a传给x,b传给y //输出 printf("%d", c); return 0; } 还有种更加简介的写法: int Add(int x, int y) { return x + y;// return z把z的值返回到c里面 } 直接返回x+y void print(void) //无参数、无返回值 ,前面的是没有返回值,后面的是不需要参数 { printf("hello world"); } int main() { print();//直接调用 return 0; } 返回类型的地方的void表示函数没有返回值 参数部分的void表示函数不需要参数
4.形参和实参
在函数的使用过程中,把函数分为形参和实参
int Add(int x, int y) // 形参,形式上的存在 { return x+y; } int main() { int a = 0; int b = 0; //输入 scanf("%d %d", &a, &b); //计算 //int c = a + b; int c = Add(a, b);//使用函数,调用函数 //输出 printf("%d", c); return 0; } 在调用函数的时候,真实传递给函数额参数叫;实际参数,简称实参, 在这个代码里面,我们把第15行的a和b叫做实参 在函数定义部分,函数名后面的参数叫;形式参数,就是本代码里面的x和y 形参其实是实参的临时拷贝
5.return语句
return后面可以是一个数值,也可以是一个表达式,如果是表达式就先执行表达式,再返回表达式的结果
举个例子:return x + y;//令x=10,y=20,只有算完x+y才会返回值
int test() { int a = 0; scanf("%d", &a); if (a > 0) return 1; else return -1; } int main() { int ret = test(); printf("%d\n", ret); return 0; } return 语句执行后,函数彻底返回,后面的代码不再执行 void test() { printf("hehe\n"); if (1)//条件为真 return;//直接返回, printf("haha\n");//被跳过 } int main() { test(); return 0; } 返回值和返回类型不同会出现数据丢失 int test() { return 3.14;//返回的是浮点数,但被转换成整型了,如果返回值和返回类型不统一则会出现数据丢失 } int main() { int r = test(); printf("%d\n", r); return 0; } 如果不想出现数据丢失,可以想强制将3.14改变成整型 return (int)3.14; 如果函数中存在if等分支的语句,则要保证每种情况下都有return返回,否则会出现编译错误 函数不写返回类型,默认返回的是整型 int test() test() 函数的返回值没写的话,编译器会认为返回的是int类型的值 如果函数要求返回值,但是函数中没有使用return返回值吗,那具体返回什么就不确定了
6.数组做函数参数
void set_arr(int arr[10],int sz)//不需要返回值,所以加一个void,这里之所以用arr[10]是因为,下面把数组传过来了,我们要创建一个数组用来接受,sz也一样,同样需要一个形参去接受 { int i = 0; for (i = 0; i < sz; i++) { arr[i] = -1; } } int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; //写一个函数将一个整型数组的内容,全部置为-1, int sz = sizeof(arr) / sizeof(arr[0]); //算出数组元素的个数 set_arr(arr,sz);//传数组 //set_arr设置数组,把arr数组中的sz个数组设置一下,这里不能写arr[10],因为arr[10]是数组中下标为10的那个数,如果要传数组的话,传数组名就行了 return 0; } 改变:你想赋什么就赋什么,在46行括号内加上你想要赋的值,然后传到函数里面的set,然后通过34行就可以实现了 void set_arr(int arr[10],int sz,int set)//不需要返回值,所以加一个void,这里之所以用arr[10]是因为,下面把数组传过来了,我们要创建一个数组用来接受,sz也一样,同样需要一个形参去接受 { int i = 0; for (i = 0; i < sz; i++)//通过循环使每一个值都赋上值 { arr[i] = set; } } int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; //写一个函数将一个整型数组的内容,全部置为-1, int sz = sizeof(arr) / sizeof(arr[0]); //算出数组元素的个数 set_arr(arr,sz,-1);//传数组 //set_arr设置数组,把arr数组中的sz个数组设置一下,这里不能写arr[10],因为arr[10]是数组中下标为10的那个数,如果要传数组的话,传数组名就行了 return 0; } void set_arr(int arr[10],int sz,int set)//不需要返回值,所以加一个void,这里之所以用arr[10]是因为,下面把数组传过来了,我们要创建一个数组用来接受,sz也一样,同样需要一个形参去接受 { int i = 0; for (i = 0; i < sz; i++) { arr[i] = set; } } void print_arr(int arr[10],int sz) { int i = 0; for (i = 0; i < sz; i++)//sz=10,i<sz就是<=9,也就是标号为9的数字,也就是最后一位数字 { printf("%d", arr[i]); } printf("\n"); } int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; //写一个函数将一个整型数组的内容,全部置为-1, int sz = sizeof(arr) / sizeof(arr[0]); //算出数组元素的个数 print_arr(arr, sz);//设置之前数组内数字的大小没有变化 set_arr(arr,sz,-1);//传数组 //set_arr设置数组,把arr数组中的sz个数组设置一下,这里不能写arr[10],因为arr[10]是数组中下标为10的那个数,如果要传数组的话,传数组名就行了 //打印数组的函数 print_arr(arr, sz); return 0; } 输出结果为: 12345678910 //改变前 -1-1-1-1-1-1-1-1-1-1 //改变后
数组在传参的时候,实参就写数组名,形参也是数组的形式
实参和形参的名字是可以一样的
函数在设计的时候,一定要功能单一,不要要过于复杂
数组在传参的时候,形参的数组和是实参的数组是同一个数组
形参如果是一维数组,数组大小可以省略不写
形参如果是二维数组,行可以省略,但是列不能省略
//二维数组的案例 void print(int arr[3][5], int r, int c)//这里的3可以省略,但是5不能省略 //这里的r和c是元素个数 { int i = 0; for (i = 0; i < r; i++)//几行//这里的r和c是元素个数,这是个循环 { int j = 0; for (j = 0; j < c; j++)//一行有几列 { printf("%d ",arr[i][j]);//这里就要用下标访问了,这里的i和j 就是下标,下标的大小要比元素的数小1 } printf("\n"); } } int main() { int arr[3][5] = { 1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7 };//定义时是3行5列,这里是元素个数 //打印二维数组的内容 print(arr, 3, 5); return 0; }
C语言----函数(2)https://developer.aliyun.com/article/1544260