头歌C语言程序设计——递归函数,函数,指针基础,指针进阶,指针及其应用,常见字符串处理函数


递归函数

第1关:计算学生年龄

#include <stdio.h>

// 用递归的方式计算第 n 个学生的年龄
int calcAge(int n) {
    if (n == 1) {
        return 10; // 基准情况:第一个学生的年龄是10岁
    } else {
        return calcAge(n - 1) + 2; // 递归调用,每个学生比前一个学生大2岁
    }
}

int main() {
    int n;
    scanf("%d", &n); // 从标准输入读取学生的序号
    printf("%d\n", calcAge(n)); // 打印第 n 个学生的年龄
    return 0;
}

第2关:用递归的思想计算阶乘

#include<stdio.h>

int fac(int n) {
  /*******begin********/
  if (n <= 1) // 当n为1或者更小时,返回1,因为1的阶乘是1
    return 1;
  else
    return n * fac(n - 1); // 否则返回n乘以n-1的阶乘,这是递归调用
  /*******end**********/
}

int main() {
  int n;
  int ret;
  scanf("%d", &n); // 读取用户输入的整数n
  ret = fac(n); // 调用阶乘函数
  printf("%d", ret); // 输出阶乘结果
  return 0;
}

第3关:猴子吃桃

#include <stdio.h>

// 递归函数计算第n天的桃子数
int taoshu(int n) {
    if (n == 10) {
        return 1;
    } else {
        return (taoshu(n + 1) + 1) * 2;
    }
}

int main() {
    int result = taoshu(1);
    printf("%d\n", result);  // 输出第一天的桃子数
    return 0;
}

函数

第1关:求和

#include <stdio.h>

// 函数声明
int sum_of_series(int n);

int main() {
    int n;
    scanf("%d", &n);
    printf("%d\n", sum_of_series(n));
    return 0;
}

// 函数定义
int sum_of_series(int n) {
    return n * (n + 1) / 2;
}

第2关:回文数计算

#include <stdio.h>

// 函数声明
int is_palindrome(int num);

int main() {
    // 遍历区间[200, 3000]
    for (int i = 200; i <= 3000; i++) {
        // 检查当前数字是否是回文数
        if (is_palindrome(i)) {
            // 如果是回文数,则输出
            printf("%d\n", i);
        }
    }
    return 0;
}

// 函数定义:检查一个数是否是回文数
int is_palindrome(int num) {
    int original_num = num;
    int reversed_num = 0;

    // 反转数字
    while (num > 0) {
        reversed_num = reversed_num * 10 + num % 10;
        num /= 10;
    }

    // 如果反转后的数字与原数字相同,则是回文数
    return original_num == reversed_num;
}

第3关: 编写函数求表达式的值

#include <stdio.h>

double calculate_s(int n) {
    double s = 1.0;
    for (int i = 1; i <= n; i++) {
        double numerator = 1.0;
        double denominator = 1.0;
        for (int j = 1; j <= i; j++) {
            numerator *= j;
            denominator *= (2 * j + 1);
        }
        s += numerator / denominator;
    }
    return s;
}

int main() {
    int n;
    scanf("%d", &n);
    printf("%.10f\n", calculate_s(n));
    return 0;
}

第4关:阶乘数列

#include <stdio.h>

// 函数声明
long long factorial(int n);

int main() {
    int n;
    scanf("%d", &n);
    
    long long sum = 0;
    for (int i = 1; i <= n; i++) {
        sum += factorial(i);
    }
    
    printf("%lld\n", sum);
    return 0;
}

// 函数定义:计算阶乘
long long factorial(int n) {
    long long result = 1;
    for (int i = 2; i <= n; i++) {
        result *= i;
    }
    return result;
}

第5关:亲密数

#include <stdio.h>

// 函数声明
int sum_of_factors(int num);

int main() {
    // 用于存储已经找到的亲密数对
    int found[3001] = {0};

    // 遍历所有可能的数对
    for (int a = 1; a <= 3000; a++) {
        int b = sum_of_factors(a);
        if (b > a && b <= 3000 && sum_of_factors(b) == a) {
            // 检查是否已经找到过这对亲密数
            if (!found[a]) {
                printf("(%d,%d)", a, b);
                found[a] = 1;
            }
        }
    }

    return 0;
}

// 函数定义:计算一个数的所有因子之和
int sum_of_factors(int num) {
    int sum = 0;
    for (int i = 1; i <= num / 2; i++) {
        if (num % i == 0) {
            sum += i;
        }
    }
    return sum;
}

第6关:公约公倍数

#include <stdio.h>

// 函数声明
long long int gcd(long long int a, long long int b);
long long int lcm(long long int a, long long int b);

int main() {
    long long int a, b;

    // 读取输入
    scanf("%lld %lld", &a, &b);

    // 检查输入是否包含负数
    if (a < 0 || b < 0) {
        printf("Input Error\n");
    } else {
        // 计算并输出最大公约数和最小公倍数
        printf("%lld %lld\n", gcd(a, b), lcm(a, b));
    }

    return 0;
}

// 函数定义:计算两个整数的最大公约数
long long int gcd(long long int a, long long int b) {
    while (b != 0) {
        long long int temp = b;
        b = a % b;
        a = temp;
    }
    return a;
}

// 函数定义:计算两个整数的最小公倍数
long long int lcm(long long int a, long long int b) {
    return (a * b) / gcd(a, b);
}

第7关:素数判断

#include <stdio.h>

// 函数声明
int isPrime(int num);

int main() {
    int num;
    scanf("%d", &num);
    
    if (isPrime(num)) {
        printf("%d是一个素数\n", num);
    } else {
        printf("%d不是一个素数\n", num);
    }
    
    return 0;
}

// 函数定义
int isPrime(int num) {
    if (num <= 1) {
        return 0; // 小于等于1的数不是素数
    }
    for (int i = 2; i * i <= num; i++) {
        if (num % i == 0) {
            return 0; // 如果num能被i整除,则num不是素数
        }
    }
    return 1; // 如果num不能被任何小于等于其平方根的数整除,则num是素数
}
#include <stdio.h>

// 函数声明
int isPrime(int num);

int main() {
    int num;
    scanf("%d", &num);
    
    if (isPrime(num)) {
        printf("%d是一个素数\n", num);
    } else {
        printf("%d不是一个素数\n", num);
    }
    
    return 0;
}

// 函数定义
int isPrime(int num) {
    if (num <= 1) {
        return 0; // 小于等于1的数不是素数
    }
    for (int i = 2; i * i <= num; i++) {
        if (num % i == 0) {
            return 0; // 如果num能被i整除,则num不是素数
        }
    }
    return 1; // 如果num不能被任何小于等于其平方根的数整除,则num是素数
}

第8关:最大公约数

#include<stdio.h>

// 函数原型声明
int MaxCommonFactor(int a, int b);

int main() {
    int a, b;
    // 输入两个整数
    scanf("%d,%d", &a, &b);
    // 调用函数并输出最大公约数
    printf("%d\n", MaxCommonFactor(a, b));
    return 0;
}

// 求最大公约数的函数实现
int MaxCommonFactor(int a, int b) {
    if(a <= 0 || b <= 0) { // 如果输入不正确,返回-1
        return -1;
    }
    int temp;
    // 辗转相除法
    while(b) {
        temp = a % b;
        a = b;
        b = temp;
    }
    return a;
}

指针基础

第1关:利用指针找最大值

#include <stdio.h>

int main() {
    int a, b;
    int *p1, *p2, *pmax;


    scanf("%d %d", &a, &b);

    // 指针变量指向相应的变量
    p1 = &a;
    p2 = &b;

    // 比较并找出最大值
    if (*p1 > *p2) {
        pmax = p1;
    } else {
        pmax = p2;
    }

    // 输出最大值
    printf("max=%d\n", *pmax);

    return 0;
}

第2关:调用函数求两个数的和与差

#include <stdio.h>

// 自定义函数 sum_diff,用于计算和与差
void sum_diff(float op1, float op2, float *psum, float *pdiff) {
    *psum = op1 + op2;    // 计算和
    *pdiff = op1 - op2;   // 计算差
}

int main() {
    float op1, op2;
    float sum, diff;

    // 输入两个实数
    scanf("%f %f", &op1, &op2);

    // 调用 sum_diff 函数计算和与差
    sum_diff(op1, op2, &sum, &diff);

    // 输出和与差
    printf("The sum is %g\n", sum);
    printf("The diff is %g\n", diff);

    return 0;
}

第3关:循环后移

#include <stdio.h>

// 函数声明,循环后移数组元素
void move(int *x, int n, int m);

int main() {
    int n, m;
    
    // 输入数组的大小和移动的位置数
    scanf("%d %d", &n, &m);

    int arr[1000]; // 假设数组最多包含1000个元素

    // 输入数组的元素
    for (int i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
    }

    // 调用函数进行循环后移
    move(arr, n, m);

    // 输出调整后的数组
    printf("After moved:");
    for (int i = 0; i < n; i++) {
        if (i == 0) {
            printf("%d", arr[i]); // 第一个数字前没有空格
        } else {
            printf(" %d", arr[i]); // 其他数字前有空格
        }
    }
    printf("\n");

    return 0;
}

// 函数定义,循环后移数组元素
void move(int *x, int n, int m) {
    int temp[1000]; // 临时数组用于存储移动后的结果

    // 计算新位置
    for (int i = 0; i < n; i++) {
        temp[(i + m) % n] = x[i];
    }

    // 将临时数组的内容复制回原数组
    for (int i = 0; i < n; i++) {
        x[i] = temp[i];
    }
}

指针进阶

第1关:输出若干个学生成绩中的最高分.要求用指针函数实现

#include <stdio.h>

// 函数声明,返回指向最高分的指针
int* max_score(int scores[], int n);

int main() {
    int n;
    int scores[1000];

    // 输入学生数量
    scanf("%d", &n);

    // 输入学生成绩
    for (int i = 0; i < n; i++) {
        scanf("%d", &scores[i]);
    }

    // 调用函数求最高分
    int *max = max_score(scores, n);

    // 输出最高分
    printf("%d\n", *max);

    return 0;
}

// 函数定义,返回指向最高分的指针
int* max_score(int scores[], int n) {
    int *max = &scores[0];
    for (int i = 1; i < n; i++) {
        if (scores[i] > *max) {
            max = &scores[i];
        }
    }
    return max;
}

第2关:采用指针变量表示地址的方法输入输出数组中的个元素

#include <stdio.h>

int main() {
    int n;
    int arr[1000]; // 假设数组最多包含1000个元素

    // 输入数组的大小
    scanf("%d", &n);

    // 输入数组的元素
    for (int i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
    }

    // 用指针变量输出数组的元素
    for (int i = 0; i < n; i++) {
        printf("%d", *(arr + i)); // 用指针表示数组元素的地址
        if (i < n - 1) {
            printf(" "); // 在元素之间添加空格
        }
    }

    printf("\n"); // 输出换行符

    return 0;
}

第3关:用指针实现数组循环移动

#include <stdio.h>

// 函数声明,循环右移数组元素
void move(int *x, int n, int m);

int main() {
    int n, m;
    
    // 输入数组的大小和移动的位置数
    scanf("%d %d", &n, &m);

    int arr[1000]; // 假设数组最多包含1000个元素

    // 输入数组的元素
    for (int i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
    }

    // 调用函数进行循环右移
    move(arr, n, m);

    // 输出调整后的数组
    for (int i = 0; i < n; i++) {
        printf("%d", arr[i]);
        if (i < n - 1) {
            printf(" ");
        }
    }
    printf("\n");

    return 0;
}

// 函数定义,循环右移数组元素
void move(int *x, int n, int m) {
    int temp[1000]; // 临时数组用于存储移动后的结果

    // 计算新位置
    for (int i = 0; i < n; i++) {
        temp[(i + m) % n] = x[i];
    }

    // 将临时数组的内容复制回原数组
    for (int i = 0; i < n; i++) {
        x[i] = temp[i];
    }
}

指针及其应用

第1关:数组倒置

#include "stdio.h"
#define N 10

void reverse(int *p, int a, int b) {
    int c;
    
    /***** 请在以下一行填写代码 *****/
    // 当 a 小于 b 时,继续循环
    while (a < b) {
        c = *(p + a); // 将 p[a] 的值存储在 c 中
        
        /***** 请在以下一行填写代码 *****/
        // 将 p[b] 的值赋给 p[a]
        *(p + a) = *(p + b);
        
        *(p + b) = c; // 将 c 的值赋给 p[b]
        
        a++; // 增加 a 的值
        /***** 请在以下一行填写代码 *****/
        b--; // 减少 b 的值
    }
}

int main() {
    int a[N], i;
    for (i = 0; i < N; i++)
        /***** 请在以下一行填写代码 *****/
        // 读取输入的整数并存储在数组 a 中
        scanf("%d", &a[i]);
    
    reverse(a, 0, N - 1); // 调用 reverse 函数,倒置数组 a 的元素
    
    for (i = 0; i < N; i++) {
        /***** 请在以下一行填写代码 *****/
        // 输出数组 a 的元素
        if (i == N - 1) {
            printf("%d", a[i]);
        } else {
            printf("%d ", a[i]);
        }
    }
    
    printf("\n"); // 输出换行符
    
    return 0; // 程序结束
}

第2关:字符排序

#include <stdio.h>
#include <ctype.h>
#include <string.h>

int fun(char *s, int num) {
    char ch;
    int i, j;
    // 对中间的5个字符进行排序
    for (i = 1; i < 6; i++) {
        for (j = i + 1; j < 6; j++) {
            /***** 请在以下一行填写代码 *****/
            // 如果 s[i] 的 ASCII 码小于 s[j] 的 ASCII 码,则交换它们的位置
            if (*(s + i) < *(s + j)) {
                ch = *(s + j);
                *(s + j) = *(s + i);
                *(s + i) = ch;
            }
        }
    }
    return 0; // 函数结束
}

int main() {
    char s[10]; // 定义字符数组 s,用于存储输入的字符串

    // 读取输入的字符串
    scanf("%s", s);
    
    /***** 请在以下一行填写代码 *****/
    // 调用 fun 函数,对字符串进行排序
    fun(s, strlen(s));
    
    // 输出排序后的字符串
    printf("%s", s);
    
    return 0; // 程序结束
}

第3关:找最长串

#include <stdio.h>
#include <string.h>
#define N 5
#define M 81

char* fun(char (*sq)[M]) {
    int i;
    char *sp;
    sp = sq[0]; // 初始化 sp 为第一个字符串的地址
    for (i = 1; i < N; i++) { // 从第二个字符串开始比较
        if (strlen(sp) < strlen(sq[i])) {
            sp = sq[i]; // 如果当前字符串长度大于 sp 指向的字符串长度,则更新 sp
        }
    }
    return sp; // 返回最长字符串的地址
}

int main() {
    char str[N][M], *longest; 
    int i;
    
    for (i = 0; i < N; i++) {
        scanf("%s", str[i]); // 读取 N 个字符串
    }
    
    printf("The %d string :\n", N);
    
    for (i = 0; i < N; i++) {
        puts(str[i]); // 输出 N 个字符串
    }
    
    longest = fun(str); // 调用 fun 函数,获取最长字符串的地址
    
    printf("The longest string :\n");
    puts(longest); // 输出最长的字符串
    
    return 0; // 程序结束
}

第4关:星号转移

#include <stdio.h>

void fun(char *a) {
    int i = 0, n = 0; // 定义变量 i 和 n,分别用于遍历字符串和统计前导 * 号的个数
    char *p;
    p = a;
    
    // 统计前导 * 号的个数
    while (*p == '*') {
        n++;
        /***** 请在以下一行填写代码 *****/
        p++;
    }
    
    // 将非 * 号的字符移到字符串的前面
    while (*p) {
        /***** 请在以下一行填写代码 *****/
        a[i] = *p;
        i++;
        p++;
    }
    
    // 将统计的 * 号移到字符串的尾部
    while (n != 0) {
        a[i] = '*';
        i++;
        /***** 请在以下一行填写代码 *****/
        n--;
    }
    
    a[i] = '\0'; // 添加字符串结束符
}

int main() {
    char s[81]; // 定义字符数组 s,用于存储输入的字符串
    int n = 0;
    
    // 读取输入的字符串
    scanf("%s", s);
    
    // 调用 fun 函数,处理字符串
    fun(s);
    
    // 输出处理后的字符串
    printf("The string  after oveing: \n");
    puts(s);
    
    return 0; // 程序结束
}

常见字符串处理函数

第1关:比较两个字符串的大小

#include <stdio.h>
#include <string.h>

int main() {
    char a[] = "computer";
    char b[20];

    // 输入字符串"compare"
    printf("");
    scanf("%s", b);

    // 比较字符串a和b
    if (strcmp(a, b) > 0) {
        printf("%s\n", a);
    } else {
        printf("%s\n", b);
    }

    return 0;
}

第2关:合并两个字符串

#include <stdio.h>

void strc(char s[], char t[]) {
    int i = 0, j = 0;
    while (*s != '\0')
    /*******begin********/
    {
        s++;
    }
    /*******end**********/
    while (*t != '\0')
    {
    /*******begin*******/
        *s = *t;
        s++;
        t++;
    /*******end*********/
    }
    *s = '\0';
}

int main() {
    char s[80] = {"hello "}, t[80];
  
    gets(t);
    strc(s, t);
    puts(s);

    return 0;
}

第3关:在字符数组中找出最小的字符串

#include <stdio.h>
#include <string.h>

int main() {
    int i; // 定义循环变量 i
    char min[80], str[80]; // 定义两个字符数组 min 和 str,用于存储字符串
  
    // 读取第一个字符串,并将其存储到 str 中
    scanf("%s", str);
    // 将第一个字符串复制到 min 中,作为初始的最小字符串
    strcpy(min, str);
  
    /***********begin***********/
    // 循环读取剩余的 4 个字符串
    for (i = 1; i < 5; i++) {
        // 读取下一个字符串,并将其存储到 str 中
        scanf("%s", str);
        // 使用 strcmp 函数比较当前字符串和 min 字符串
        // 如果当前字符串比 min 小,则更新 min
        if (strcmp(str, min) < 0) {
            strcpy(min, str); // 将当前字符串复制到 min 中
        }
    }
    /**********end***********/
  
    // 输出最小的字符串
    printf("Min is:%s", min);
  
    return 0; // 程序结束
}

第4关:找最长字符串

#include <stdio.h>
#include <string.h>

int main() {
    int i; // 定义循环变量 i
    char str[80], max[80]; // 定义两个字符数组 str 和 max,用于存储字符串
  
    // 读取第一个字符串,并将其存储到 str 中
    scanf("%s", str);
    // 将第一个字符串复制到 max 中,作为初始的最长字符串
    strcpy(max, str);
  
    /***********begin**************/
    // 循环读取剩余的 4 个字符串
    for (i = 1; i < 5; i++) {
        // 读取下一个字符串,并将其存储到 str 中
        scanf("%s", str);
        // 使用 strlen 函数比较当前字符串和 max 字符串的长度
        // 如果当前字符串比 max 长,则更新 max
        if (strlen(str) > strlen(max)) {
            strcpy(max, str); // 将当前字符串复制到 max 中
        }
    }
    /***********end*************/
  
    // 输出最长的字符串
    printf("%s", max);
  
    return 0; // 程序结束
}

第5关:字符串排序

#include <stdio.h>
#include <string.h>

int main() {
    char *name[] = {"blue", "yellow", "red", "black", "green"}; // 定义字符串数组
    char *temp; // 定义临时指针变量,用于交换字符串
    int i, j; // 定义循环变量 i 和 j

    /*************begin*************/
    // 使用冒泡排序法对字符串数组进行排序
    for (i = 0; i < 5 - 1; i++) {
        for (j = 0; j < 5 - 1 - i; j++) {
            // 使用 strcmp 函数比较相邻的两个字符串
            if (strcmp(name[j], name[j + 1]) > 0) {
                // 如果前一个字符串大于后一个字符串,则交换它们的位置
                temp = name[j];
                name[j] = name[j + 1];
                name[j + 1] = temp;
            }
        }
    }
    /**************end*************/

    // 输出排序后的字符串数组
    for (i = 0; i < 5; i++) {
        printf("%s ", name[i]);
    }

    return 0; // 程序结束
}

第6关:判断字符串是否是“回文”

#include <stdio.h>
#include <string.h>

int main() {
    int i, k;
    char line[80];
    
    // 读取输入的字符串
    gets(line);
    
    // 获取字符串的长度
    k = strlen(line);
    
    // 初始化变量 i 和 k
    i = 0;
    k = k - 1;
    
    /*************begin**********/
    // 循环比较字符串的开始和结束位置的字符
    while (i < k) {
        // 如果字符不一致,则跳出循环
        if (line[i] != line[k]) {
            break;
        }
        // 移动开始位置向后
        i++;
        // 移动结束位置向前
        k--;
    }
    /***************end***********/
    
    // 判断是否为回文
    if (i >= k)
        printf("yes");
    else
        printf("no");
    
    return 0; // 程序结束
}

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值