C第七天

本文介绍了函数的基本概念,包括定义、声明、调用等,并详细解释了递归与递推的区别及应用场景。此外还提供了多个函数编程实例,如求立方根、费氏数列等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第七课    函数
一、函数的概念
int max = 0, i;
for (i = 0; i < 10; i++)
    if (i != max && scores[i] > scores[max])
        max = i;
scores[max]就是最高分
函数就是一系列语句的组合,用以实现一些相对独立且具有一定通用性的功能。
y = f(x)
y = kx+b
二、函数的定义
1.语法
返回类型 函数名 (形参表) {
    函数体语句;
}
int main (void) {
    // ...
    return 0;
}
三、函数的声明
声明语法:
返回类型 函数名 (形参表);
1.函数在使用前最好进行声明,如果没有给出函数的显示声明,则编译器会采用如下隐式声明:
int func ();
返回int,且参数表任意。
2.如果函数返回类型不是int,或者希望编译器对函数调用的参数匹配性做检查,那么就要显示地对函数进行声明。
3.函数声明中的参数表,空括号“()”表示可以接受任意参数,而void,表示不接受任何参数。
4.如果函数的定义在函数调用之前,定义本身即是声明。
四、函数的调用
调用语法:
函数名(实参表);
1.有参数的函数在定义时使用的参数叫形参,当调用该函数时需要传入的参数叫实参。将实参传递给形参的过程,相当于将实参的值赋值给形参变量。从内存的角度看,实参属于调用者的栈区,形参属于被调用者的栈区。
2.当以数组名作为实参调用函数时,实际传给形参的是该实参数组的首地址(而非实参数组的副本),因此在函数中对形参数组的修改也就是对实参数组的修改。
在函数中对形参数组不用通过sizeof(arr)/sizeof(arr[0])获得该数组的长度。如果函数有必要了解数组中有效数据的个数,应该通过另一个附加参数传入该函数。
3.return可以用于退出函数,exit()用于退出整个程序,只有在main函数中,二者才相当。
五、递归与递推
1.递归就是函数自己调用自己。
n! = n*(n-1)(n-2)...1
n!=n*(n-1)!
使用递归的时机:需要进行的操作就是正在进行的操作。
注意:递归一定要有终止条件,否则就会形成无限递归。
2.递推就是一种迭代算法。
a(n+1) = a(n) + d;
费氏数列:f(n) = f(n-2) + f(n-1), f(1)=f(2) = 1
1 1 2 3 5 8 13 ...
第12项的值?
递归函数可以简化算法,但是效率不高。如果不是十分必要的话,尽可能避免使用递归。
汉诺塔问题:递归。
A     B     C
N
第一步:通过某种操作将N-1个盘子借助C移到B上。
第二步:将A上第N个盘子移到C。
第三步:通过某种操作将B上的N-1个盘子借助于A移到C上。
循环递归:func_a -> func_b _> func_c -> func_a
交叉递归:func_a -> func_b _> func_a
自递归:func_a -> func_a
练习:实现求立方根函数
double cbrt (double x);
立方根迭代公式:
Rn+1=(2*Rn+X/Rn^2)/3, R1=X, |Rn+1-Rn|<EPS
double fabs (double x);

10*10

int add (int a, int b) {
  return a + b;
}
int sub (int a, int b) {
  return a - b;
}
int mul (int a, int b) {
  return a * b;
}
int div (int a, int b) {
  return a / b;
}
int mod (int a, int b) {
  return a % b;
}

#include <stdio.h>
#include <math.h>
double cbrt (double x) {
  double r1, r2 = x;
  do {
    r1 = r2;
    r2 = (2*r1+x/(r1*r1))/3;
  } while (fabs (r2 - r1) > 1E-6);
  return r2;
}
int main (void) {
  printf ("输入一个数:");
  double x;
  scanf ("%lf", &x);
  printf ("%lf的立方根:%lf\n", x, cbrt (x));
  return 0;
}

#include <stdio.h>
int gui (int n) {
  if (n < 3)
    return 1;
  return gui (n-1) + gui (n-2);
}
int tui (int n) {
  int x = 1, y = 1, i;
  for (i = 3; i <= n; i++) {
    y = x + y;
    x = y - x;
  }
  return y;
}
int main (void) {
  //printf ("%d\n", gui (45));
  printf ("%d\n", tui (45));
  return 0;
}

#include <stdio.h>
// 函数声明
int add (int a, int b);
int sub (int, int);
void print (int);
/* 定义同时声明 */
int mul (int a, int b) {
  return a * b;
}
int main (void) {
  int x = 100, y = 200;
  int z = add (x, y); // 函数调用
  printf ("%d\n", z);
  z = sub (x, y);
  print (z);
  print (sub (y, x));
  z = mul (x, y);
  return 0;
}
// 函数定义
int add (int a, int b) {
  int c = a + b;
  return c;
}
int sub (int a, int b) {
  return a - b;
}
void print (int a) {
  if (a < 0)
    return;
  printf ("%d\n", a);
}

#include <stdio.h>
int jiecheng (int n) {
  printf ("n=%d\n", n);
  if (n == 1)
    return n;
  return n * jiecheng (n - 1);
}
int main (void) {
  int res = jiecheng (5);
  printf ("%d\n", res);
  return 0;
}

#include <stdio.h>
void han (int n, char f, char b, char t) {
  if (n) {
    han (n-1, f, t, b);
    printf ("%d: %c -> %c\n", n, f, t);
    han (n-1, b, f, t);
  }
}
int main (void) {
  han (3, 'A', 'B', 'C');
  return 0;
}

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>
#include <sys/ioctl.h>
#define H 10
#define W 10
void init (char c[][W]) {
  srand (time (NULL));
  int i, j;
  for (i = 0; i < H; i++)
    for (j = 0; j < W; j++)
      c[i][j] = rand () % 2 ? '*' : ' ';
}
void show (char c[][W], int g) {
  int i, j, k = 0;
  for (i = 0; i < H; i++) {
    for (j = 0; j < W; j++) {
      printf ("%c ", c[i][j]);
      if (c[i][j] == '*')
        k++;
    }
    printf ("\n");
  }
  printf ("第%d代,有%d个活细胞。\n", g, k);
}
int getch (void) {
  struct termios old;
  ioctl (STDIN_FILENO, TCGETS, &old);
  struct termios new = old;
  new.c_lflag &= ~(ECHO | ICANON);
  ioctl (STDIN_FILENO, TCSETS, &new);
  int ch = getchar ();
  ioctl (STDIN_FILENO, TCSETS, &old);
  return ch;
}
void quit (void) {
  printf ("按<Q>键退出,其它键继续...");
  int ch = getch ();
  printf ("\n");
  if (ch == 'q' || ch == 'Q')
    exit (0);
}
void breed (char c[][W]) {
  int i, j;
  for (i = 0; i < H; i++)
    for (j = 0; j < W; j++) {
      int u = i - 1, d = i + 1, l = j - 1, r = j + 1, k = 0;
      if (u >= 0 && c[u][j] == '*')
        k++;
      if (d < H && c[d][j] == '*')
        k++;
      if (l >= 0 && c[i][l] == '*')
        k++;
      if (r < W && c[i][r] == '*')
        k++;
      if (u >= 0 && l >= 0 && c[u][l] == '*')
        k++;
      if (u >= 0 && r < W && c[u][r] == '*')
        k++;
      if (d < H && l >= 0 && c[d][l] == '*')
        k++;
      if (d < H && r < W && c[d][r] == '*')
        k++;
      if (k == 3)
        c[i][j] = '*';
      else if (k != 2)
        c[i][j] = ' ';
    }
}
int main (void) {
  char c[H][W];
  init (c);
  int g;
  for (g = 1; ; g++) {
    show (c, g);
    quit ();
    breed (c);
  }
  return 0;
}

#include <stdio.h>
// 输入数据
void input (float scores[], int sts) {
  int i;
  for (i = 0; i < sts; i++) {
    printf ("第%d个学生:", i+1);
    scanf ("%f", &scores[i]);
  }
}
// 计算总分
float total (float scores[], int sts) {
  float total = 0;
  int i;
  for (i = 0; i < sts; i++)
    total += scores[i];
  return total;
}
// 计算最高分
float max (float scores[], int sts) {
  int max = 0, i;
  for (i = 0; i < sts; i++)
    if (i != max && scores[i] > scores[max])
      max = i;
  return scores[max];
}
int main (void) {
  printf ("学生人数:");
  int sts;
  scanf ("%d", &sts);
  float scores[sts];
  input (scores, sts);
  float t = total (scores, sts);
  float m = max (scores, sts);
  printf ("总分:%g,平均分:%g,最高分:%g\n", t, t / sts, m);
  return 0;
}

#include <stdio.h>


void swap (int a, int b) 
{
  int c = a;
  
a = b;
 
 b = c;
  
printf ("swap: %d,%d\n", a, b);
  // 200,100


}
void swap2 (int arr[]) 
{
  printf ("%d\n", sizeof (arr) / sizeof (arr[0]));
 
 int c = arr[0];
  arr[0] = arr[1];
  
arr[1] = c;
  
printf ("swap2: %d,%d\n", 
arr[0], arr[1]); // 200,100


}


void print (int arr[], int len) {
  
int i;
  for (i = 0; i < len; i++)
    
printf ("%d ", arr[i]);
  
printf ("\n"); 
}
void printm (int mtx[][4], int row) {
  
int i, j;
  
for (i = 0; i < row; i++) {
    for (j = 0; j < sizeof (mtx[0]) / sizeof (mtx[0][0]); j++)
      printf ("%4d", mtx[i][j]);
    
printf ("\n");
  }


}


int main (void) {
  int a = 100, b = 200;
  
swap (a, b);
  
printf ("main: %d,%d\n", a, b);
  // 100,200
  int arr[2] = {100, 200};
  
swap2 (arr);
  printf ("main: %d,%d\n", arr[0], arr[1]); // 200,100
  
int array[] = {10,20,30,40,50};
  print (array, sizeof (array) / sizeof (array[0]));
 
 int mtx[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
 
 printm (mtx, sizeof (mtx) / sizeof (mtx[0]));
 
 return 0;


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值