赞
踩
目录
博主水平有限,文章中若有错误,望读者们斧正。
维基百科中,函数的定义是
函数在c语言中是可以自定义的,那如何定义一个函数呢?
- void fun_name(int x)
- {
- 函数语句;
- }
1)void是函数返回类型(如果函数在运行完成后需要给主程序返回一个值,我们就要用相应的类型去定义这个函数。要返回整形,就用 int去定义函数,不需要返回我们就用void类型)
2)fun_name是函数的名字,名字要起的与函数功能匹配
3)括号里的int是参数类型,x是函数参数(参数可以有一个或多个,但参数要尽量少),当然也可以没有参数,让程序直接运行函数的语句
- void test()
- {
- 函数语句;
- }
4)如果函数有返回值,调用函数时我们要创建一个变量接收返回值。没有变量时,我们直接调用就行
- //1有返回值时
-
- int fun(int x)
- {
- 语句;
- }
-
- int main()
- {
- int a = 0;
- int ret = fun(a);
- return 0;
- }
-
- //2没有返回值时
-
- void fun(int x)
- {
- 语句;
- }
-
- int main()
- {
- int a = 0;
- fun(a);
- return 0;
- }
我们举一个例子:自定义一个函数,找出两个数中的最大值。那我们接下来就要创建一个有两个参数的函数,并且函数将会返回两个数中的最大值,返回值是整形,所以我们用 int类型创建一个名为Max的函数。要怎么调用我们创建的函数呢?我们只要写上函数名,再将要求最大值的两个数以逗号间隔,放进括号中
Max(a, b)
- //找出两个数中的最大值
- int Max(int x, int y)//设定两个函数参数
- {
- return (x > y ? x : y);
- }
-
-
- int main()
- {
- int a = 10;
- int b = 20;
- //当程序运行到这时,函数会被程序调用
- //函数返回最大值,我们创建 max 变量接收最大值
- int max = Max(a, b);
- printf("%d", max);
- return 0;
- }
这样Max 函数就写好了。
cplusplus.com - The C++ Resources Network
(函数返回类型与应用举例)
函数在不同情况下会返回不同的值,在Return Vaule中都具体介绍了。如果看完后还是不懂要怎么使用这个库函数,我们还能通过Example,看看别人是怎么使用这个函数的。
最后我们在使用库函数时一定要引用头文件。可以看到,printf的头文件是熟悉的stdio.h,我们就要在程序开始处加上#include<stdio.h>(这里建议把头文件都写在开头处)
在函数中 x,y被称作形式参数(形参),a,b则是实际参数(实参)
结合刚刚的Max函数理解形参与实参
- //找出两个数中最大值
- int Max(int x, int y)
- {
- return x > y ? x : y;
- }
-
-
- int main()
- {
- int a = 10;
- int b = 20;
- int c = Max(a, b);
- printf("%d", c);
- return 0;
- }
它们有什么区别?形参其实是实参的一份临时拷贝。换言之,形参不等于实参,在函数运行时,程序为形参单独开辟内层空间,在程序结束时,程序销毁形参。两者的内存空间不同,所以改变形参的值不能改变实参。
我们再来一个例子
- void Swap(int x, int y)
- {
- int z = x;//两数交换时创建第三个变量,就像交换酱油与醋,我们要找第三个瓶子
- x = y;
- y = z;
- }
-
- int main()
- {
- int a = 10;
- int b = 20;
- printf("打印前:a = %d,b = %d\n", a, b);
- Swap(a, b);
- printf("打印后:a = %d,b = %d\n", a, b);
-
- }
这是一个交换函数,用它我们交换a与b的值,那结果是什么?
两个数没有发生交换,为什么?这是因为形参是实参的临时拷贝,改变形参的值不能改变实参的值。要实现两数交换,我们可以把地址传给形参,对地址解引用,找到实参,从而间接的改变实参。
把地址作为实参传给形参的调用函数方式称为传址调用,把实参的值作为实参传给形参的方式叫做传值调用。
来看看交换函数的正确写法
- void Swap(int* x, int* y)
- {
- int z = *x;
- *x = *y;
- *y = z;
- }
-
- int main()
- {
- int a = 10;
- int b = 20;
- printf("打印前:a = %d,b = %d\n", a, b);
- Swap(&a, &b);
- printf("打印后:a = %d,b = %d\n", a, b);
-
- }
运行结果
所以在写函数时要先考虑调用方式是传值调用还是传值调用。要想通过函数改变外部变量的值,我们通常传址调用,反之我们就使用传值调用。
如果我们在调用函数时,将函数写到了主函数的后面,程序会报一个警告,因为程序在运行时总是从上到下运行的,程序要调用一个函数,但是它却不认识这个函数,更不要说去调用它了。所以我们在调用函数时要满足先声明后使用,声明就是告诉程序这个函数叫什么,返回类型是什么,参数有什么...而声明一般会放到头文件中。(这里先简单介绍下,之后我会接着补充怎么具体声明)
- #include<stdio.h>
-
- //这就是声明Swap函数的格式
- void Swap(int* x, int* y);
-
- int main()
- {
- int a = 10;
- int b = 20;
- printf("打印前:a = %d,b = %d\n", a, b);
- Swap(&a, &b);
- printf("打印后:a = %d,b = %d\n", a, b);
-
- }
-
- //把Swap函数放在主函数的后面
- void Swap(int* x, int* y)
- {
- int z = *x;
- *x = *y;
- *y = z;
- }
什么是嵌套调用?在函数中调用其他函数的方式被称为嵌套调用。
- void hehe()
- {
- printf("hehe");
- }
-
- void three_hehe()
- {
- hehe();
- hehe();
- hehe();
- }
这里举一个简单的例子。hehe函数的作用是打印 “hehe”,three_hehe函数的作用是打印三个 “hehe” ,函数中一共调用了三次hehe函数。three_hehe中调用了 hehe函数。这样就是嵌套调用了。
那什么又是链式访问呢?
将一个函数的返回值作为另一个函数的参数。我们再举一个例子
- //strlen:求字符串长度,返回值为字符串中字符个数
- //方式1
- int main()
- {
- char a[] = "abcde";
- printf("%d", strlen(a));
- return 0;
- }
-
-
- //方式2
- int main()
- {
- char a[] = "abcde";
- int ret = 0;
- ret = strlen(a);
- printf("%d", ret);
- return 0;
- }
两种方式哪种是链式访问呢?答案是方式1。方式1将 strlen函数的运算结果直接作为printf函数的参数。方式2中,我们通过创建中间变量 ret存储strlen函数的返回值,最后打印 ret的值,是一种间接使用 strlen函数返回值的方式。两种方式各有优缺点,方式 1简洁,代码量少,方式 2虽然代码多,但是对于新手来说可读性高。
前面我们介绍了函数的嵌套调用(在函数中调用其他函数),递归呢,就是函数自己对自己的嵌套调用,自己调用自己。运用递归我们能将大事化小,用少量代码解决复杂问题。但是函数如果不停地调用自己,我们的程序是会崩溃的,所以我们要有一个终止条件,当函数满足该条件时,停止调用自己,并且我们在每一次调用函数后,更接近这个条件。
先来看一个简单的递归:如何递归来求 n 的阶乘?
分析:(假设函数名为fac)当 n为1时,函数直接返回1。n大于1时,函数返回 n * fac(n - 1),直到fac(n - 1)中的(n - 1)为1,函数停止递归。
- int fac(int n)
- {
- if (n == 1)
- {
- return 1;
- }
- else
- {
- return (n * fac(n - 1));
- }
- }
-
- int main()
- {
- int n = 0;
- scanf("%d", &n);
- printf("%d", fac(n));
- return 0;
- }
假设我们要求5 的阶乘,画图理解。
红色代表的是函数”递“的部分,程序不断的调用fac函数,一层层往下接近终止条件,绿色代表的是函数”归“的部分,当程序遇到终止条件,会 返回函数值,一层层向上地返回函数值,直到递归的起点。
我们还能用递归求第 n个斐波那契数。(斐波那契数列:1,1,2,3,5,8,13,21,34,55...从第 3项开始每一项都是前两项的和)
可以这样分析,当 n 小于等于 2时,斐波那契数为1,当 n大于 2时,f(n) = f(n - 1)+ f(n - 2)。当 n大于 2我们就进行递归,每次递归调用函数时 n都减一,直到(n - 2) 与 (n -1)这两个表达式满足终止条件,程序结束'递',开始往上'归'。
- int Fib(int x)
- {
- if (x <= 2)
- {
- return 1;
- }
- else
- {
- return Fib(x - 1) + Fib(x - 2);
- }
- }
-
-
- int main()
- {
- int n = 0;
- scanf("%d", &n);
- printf("%d", Fib(n));
- return 0;
- }
最后,由于前几天状态不佳,总结这篇博客时相当敷衍,在进行了删改之后重新发布这篇博客。希望以后能及时调整自己,保持一个学习的状态。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。