笔记目录
第七章 函数
函数的概念
function函数:为了完成一定功能的一个模块。一个源程序是由一个或多个函数组成的。
main()函数是程序的入口,所有的函数都是平行的,相互独立的。
函数可以分为:库函数(stdio.h、string.h、math.h)和用户自定义函数。
函数的形式:无参函数和有参函数
定义一个函数
函数包括:函数名称,函数类型,函数参数,函数的具体操作。
无参函数的一般形式
返回值 函数名称(){
函数的具体操作
}
```c
// 2020/11/09
// C
#include <stdio.h>
int main() {
// 2.声明无参函数hello()
void hello();
void star();
// 3.函数的调用
star();
hello();
star();
return 0;
}
// 1.定义一个无参函数hello()
void hello() { printf("Hello World!\n"); }
void star() { printf("*******\n"); }
```
有参函数的一般形式
返回值 函数名称(参数列表){
函数的具体操作
}
函数的调用
C语言中,实参和形参的传递形式为:由实参向形参进行单向传递(值,地址)。不能由形参向实参传递。
// 2020/11/09
// C
#include <stdio.h>
int main() {
int a = 1, b = 2;
int sum(int, int);
//返回值通常需要一个相同类型的变量接收
printf("sum=%d\n", sum(a, b));//实际参数(实参)
return 0;
}
//函数功能:计算两个整数的和
int sum(int a, int b) {//形式参数(形参)
return a + b; }
函数的调用过程
- 在定义函数中的形参变量,在没有进行函数调用时,不会给形参开辟内存空间,只要在发生函数调用时,函数的形参才会在内存中开辟临时的空间。
- 当实参的值单向传递给形参。
- 在执行函数调用时,给形参开辟临时的内存空间,形参进行运算。
- 如果函数由return返回,函数执行完成后通过return语句将函数运算的值返回。
- 函数调用完成后,形参内存单元被释放。
函数的调用
// 2020/11/09
// C
#include <stdio.h>
int main() {
int max(int, int);
int a = 10, b = 30;
printf("max=%d\n", max(a, b));
return 0;
}
//函数功能:比较两个整数的大小,得到最大值。
int max(int a, int b) { //形式参数(形参)
int m;
if (a > b) {
m = a;
} else {
m = b;
}
return m;
}
函数的嵌套(函数不能嵌套定义,但可以嵌套调用)
例如:有4个整数,通过函数,求最大值。
// 2020/11/09
// C
#include <stdio.h>
int main() {
int max(int, int);//1.
int max2(int, int, int, int);//2.
int a = 1, b = 2, c = 3, d = 4;//3.
printf("max=%d\n", max2(a, b, c, d));//4.12.
return 0;//13.
}
int max(int a, int b) {//8.
int m = a > b ? a : b;//9.
return m;//10.
}
int max2(int a, int b, int c, int d) {//5.
int m;//6.
m = max(max(a, b), max(c, d));//7.
return m;//11.
}
函数的递归
函数的递归就是函数直接或间接的调用本身。
int fun(int a){
……
fun(5);
……
}
循环和函数的递归是等价的。
函数递归:
通向公式(递推公式);函数的出口。
例如:求5!
// 2020/11/09
// C
#include <stdio.h>
int main() {
//int n = 1;
int fun(int);
//for (int i = 1; i <= 5; i++) {
//n *= i;
//}
printf("%d\n", fun(5));
return 0; // 13.
}
// 5!
int fun(int x) {
if (x == 0 || x == 1) {
return 1;
} else if (x >= 2) {
return x * fun(x - 1);
}
}
例如:求100的和
// 2020/11/09
// C
#include <stdio.h>
int main() {
int fun(int);
printf("%d\n", fun(100));
return 0;
}
int fun(int n) {
if (n == 1)
return 1;
else if (n >= 2)
return n + fun(n - 1);
}
例题:递归求 年龄
原理:
// 2020/11/09
// C
#include <stdio.h>
int main() {
int fun(int);
printf("age=%d\n", fun(5));
return 0;
}
int fun(x) {
if (x == 1)
return 10;
else if (x >= 2)
return fun(x - 1) + 2;
}
例题:用递归求解
// 2020/11/09
// C
// n^{k}
#include <stdio.h>
int main() {
double fun2(double,double);
printf("%f\n", fun2(5, -2));
return 0;
}
double fun2(double n, double k) {
if (k == 0)
return 1;
else if (k < 0)
return fun2(n,k+1)*(1/n);
else if (k >= 1)
return fun2(n, k - 1) * n;
}
例题:递归求斐波那契数列
// 2020/11/09
// C
#include <stdio.h>
int main() {
int fun(int);
for (int i = 1; i <= 15; i++) {
printf("%5d", fun(i));
}
// printf("%d\n", fun(15));
}
int fun(int n) {
if (n == 1 || n == 2)
return 1;
else if (n > 2)
return fun(n - 1) + fun(n - 2);
}
函数的引用传递
// 2020/11/13
// C
#include <stdio.h>
int main() {
//函数的传递
void fun(int);
int a = 10;
fun(a);
printf("%d", a);
return 0;
}
void fun(int a) { a = 100; }
// 2020/11/13
// C
#include <stdio.h>
int main() {
void fun(int a[]);
int a[5] = {1,2,3,4,5};
fun(a);
printf("%d", a[2]);
return 0;
}
void fun(int a[]) { a[2] = 100; }
// 2020/11/13
// C
#include <stdio.h>
int main() {
void fun(int a[]);
int a = 10;
fun(&a);// 通过fun()函数找到了a的地址,函数的作用:更改了地址为a的内存中存放的值,修改后,函数更改所需产生的内存空间自动释放
printf("%d", a);
return 0;
}
void fun(int a[]) { a[0] = 100; }
数组元素作为实参
例题:
有一个10个元素的一维数组,找到数组中最大值和对应的下标。
// 2020/11/13
// C
#include <stdio.h>
int main() {
int fun(int, int);
int a[10];
for (int i = 0; i <= 9; i++) {
scanf("%d", &a[i]);
}
int x = a[0];
int y = 0;
for (int i = 0; i <= 9; i++) {
if (fun(x, a[i]) > x) {
x = a[i];
y = i;
}
}
printf("max=%d\nindex=%d", x, y);
return 0;
}
int fun(int a, int b) {
if (a > b) {
return a;
} else {
return b;
}
}
当函数名称作为形参时,在函数调用的时候,是将地址传递给形式参数。
当普通变量作为形参时,在函数调用的时候,是将值传递给形式参数。
局部变量和全局变量
局部变量
// 2020/11/13
// C
#include <stdio.h>
int main() {
int i = 10;
for (int i = 0; i <= 9; i++) {
printf("%5d", i);
}
printf("\ni=%d", i);
return 0;
}
int fun(int a) { int b, c; }
全局变量
// 2020/11/13
// C
#include <stdio.h>
int p = 10, q = 20;
void fun() { printf("%d|%d\n", p, q); }
int A = 2, B = 30;
void fun2() { printf("%d|%d\n", A, B); }
int main() {
printf("%d|%d\n", p, q);
fun();
fun2();
return 0;
}
变量的存储方式
auto{自动变量}
auto:在定义函数的内部定义的变量,默认情况下为自动变量。当函数发生调用时,内存会给自动变量分配临时的空间,当函数调用完成后,内存空间自动释放。
// 2020/11/13
// C
#include <stdio.h>
int main() {
int fun(int);
int a = 1;
printf("%d\n", fun(a));
printf("%d\n", fun(a));
printf("%d\n", fun(a));
return 0;
}
int fun(int x) {
int a = 0; // auto int a=0;
return x + a;
}
static{静态变量}
static:在定义函数时内部定义的变量,如果为静态变量时,当函数发生调用时,内存会给变量分配空间,当函数调用完成后,内存空间不会释放。
// 2020/11/13
// C
#include <stdio.h>
int main() {
int fun(int);
int a = 1;
printf("%d\n", fun(a));
printf("%d\n", fun(a));
printf("%d\n", fun(a));
return 0;
}
int fun(int x) {
static int a = 0;
a++;
return x + a;
}
register{寄存变量}
extern{外部变量}
例题:分段函数
// 2020/11/13
// C
#include <stdio.h>
int main() {
double fun(double);
double x;
scanf("%lf", &x);
double y = fun(x);
printf("%f\n", y);
return 0;
}
double fun(double x) {
if (x < 1)
return x;
else if (x >= 1 && x < 10)
return 2 * x - 1;
else if (x >= 10)
return 3 * x - 11;
}
例题:输入一个数,判断该数是否为素数。
素数:一个整数如果只能被1或其本身整除,为素数
方法1:i是否为素数 2----(i-1)
方法2:i是否为素数 2---- sqrt(i)
// 2020/11/13
// C
//方法1
#include <stdio.h>
int main() {
int fun(int);
int x;
scanf("%d", &x);
int bol = fun(x);
if (bol == 1)
printf("是素数");
else
printf("不是素数");
return 0;
}
// 1是,0否
int fun(int x) {
for (int i = 2; i <= x - 1; i++) {
if (x % i == 0) {
return 0;
break;
}
}
return 1;
}
// 2020/11/13
// C
//方法2
#include <stdio.h>
#include <math.h>
int main() {
int fun(int);
int x;
scanf("%d", &x);
int bol = fun(x);
if (bol == 1)
printf("是素数");
else
printf("不是素数");
return 0;
}
// 1是,0否
int fun(int x) {
for (int i = 2; i <= sqrt(x); i++) {
if (x % i == 0) {
return 0;
break;
}
}
return 1;
}
例题
// 2020/11/13
// C
#include <stdio.h>
int main() {
long fun(int);
int n = 20;
printf("%d\n", fun(n));
return 0;
}
long fun(int n) {
int i, j;
long temp = 1, result = 0;
if (n == 0)
return 1;
if (n > 20)
return 0;
for (int i = 1; i <= n; i++) {
temp = temp * i;
result += temp;
}
return result;
}
例题
例题
例题
编写函数,实现公式求π的近似值,直到发现某一项的绝对值小于指定周值为止(该项不累加),并返回近似值。
// 2020/11/le
// C
#include <math.h>
#include <stdio.h>
int main() {
double ava(double);
double av;
scanf("%lf", &av);
av = ava(av);
printf("%.20f\n", av);
return 0;
}
double ava(double av) {
double pi = 0;
int m = 1; //分子
double n = 1.0; //分母
double term = 1.0; //项
while (fabs(term) >= av) {
pi = pi + term;
m = -m;
n += 2;
term = m / n;
}
pi *= 4;
return pi;
}
例题
编写函数,判断某一年是否为闰年。(闰年的条件:能被4整除,但不能被100整除的年份是闰年;能被400整除的年份是闰年。)
// 2020/11/13
// C
//函数判断闰年
#include <stdio.h>
int main() {
int year(int);
int y;
scanf("%d", &y);
printf("%d\n", year(y));
return 0;
}
int year(int y) {
if (y % 4 == 0 && y % 100 != 0 || y % 400 == 0)
return 1;
return 0;
}