专升本C语言学习--第七章 函数

第七章 函数

函数的概念

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; }

函数的调用过程

  1. 在定义函数中的形参变量,在没有进行函数调用时,不会给形参开辟内存空间,只要在发生函数调用时,函数的形参才会在内存中开辟临时的空间。
  2. 当实参的值单向传递给形参。
  3. 在执行函数调用时,给形参开辟临时的内存空间,形参进行运算。
  4. 如果函数由return返回,函数执行完成后通过return语句将函数运算的值返回。
  5. 函数调用完成后,形参内存单元被释放。
函数的调用
// 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!

bear_sketch@2x 2

// 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的和
bear_sketch@2x 3

// 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);
}

例题:递归求 年龄

image

bear_sketch@2x 4

原理:
bear_sketch@2x 5

// 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;
}

例题:用递归求解

image 2
bear_sketch@2x 6

// 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;
}

例题:递归求斐波那契数列

bear_sketch@2x 7

// 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; }

bear_sketch@2x 8

// 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; }

bear_sketch@2x 9

// 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; }

image 3

数组元素作为实参

例题:

有一个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; }

image 4

全局变量

// 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;
}

image 5

变量的存储方式

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;
}

image 6

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;
}

image 7

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;
}

例题

image 8

// 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;
}

例题

image 9

例题

image 10

例题

编写函数,实现公式求π的近似值,直到发现某一项的绝对值小于指定周值为止(该项不累加),并返回近似值。
image 11

// 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;
}
  • 5
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liangpi_hero

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值