🎓博主介绍:精通 C、Python、Java、JavaScript 等编程语言,具备全栈开发能力。日常专注于分享编程干货、算法解析、项目实战经验,以及前沿技术动态。让我们一起在技术的道路上不断探索,共同成长!
在这里插入图片描述

C 语言算法入门:50 道经典例题带你玩转逻辑思维

一、引言

C 语言作为一门经典且广泛应用的编程语言,其核心不仅在于语法的掌握,更在于算法思维的培养。算法是解决问题的一系列步骤和方法,对于提升编程能力和逻辑思维至关重要。本文精心挑选了 50 道经典的 C 语言算法例题,涵盖了基础运算、数组操作、排序算法、递归算法等多个方面,旨在帮助技术人员尤其是初学者通过实际的例题练习,逐步掌握 C 语言算法的精髓,玩转逻辑思维。

二、基础运算类例题

2.1 两数之和

2.1.1 问题描述

输入两个整数,计算它们的和并输出。

2.1.2 代码实现
#include <stdio.h>

int main() {
    int num1, num2;
    printf("请输入两个整数:");
    scanf("%d %d", &num1, &num2);
    int sum = num1 + num2;
    printf("两数之和为:%d\n", sum);
    return 0;
}
2.1.3 思路分析

通过 scanf 函数获取用户输入的两个整数,然后使用加法运算符 + 计算它们的和,最后使用 printf 函数输出结果。

2.2 两数交换

2.2.1 问题描述

输入两个整数,交换它们的值并输出交换后的结果。

2.2.2 代码实现
#include <stdio.h>

int main() {
    int num1, num2, temp;
    printf("请输入两个整数:");
    scanf("%d %d", &num1, &num2);
    temp = num1;
    num1 = num2;
    num2 = temp;
    printf("交换后两个数分别为:%d %d\n", num1, num2);
    return 0;
}
2.2.3 思路分析

借助一个临时变量 temp,先将 num1 的值存储在 temp 中,然后将 num2 的值赋给 num1,最后将 temp(即原来 num1 的值)赋给 num2,完成交换。

2.3 判断奇数偶数

2.3.1 问题描述

输入一个整数,判断它是奇数还是偶数并输出结果。

2.3.2 代码实现
#include <stdio.h>

int main() {
    int num;
    printf("请输入一个整数:");
    scanf("%d", &num);
    if (num % 2 == 0) {
        printf("%d 是偶数\n", num);
    } else {
        printf("%d 是奇数\n", num);
    }
    return 0;
}
2.3.3 思路分析

使用取模运算符 % 计算该整数除以 2 的余数,如果余数为 0,则该数为偶数;否则为奇数。

三、数组操作类例题

3.1 数组元素求和

3.1.1 问题描述

给定一个数组,计算数组中所有元素的和并输出。

3.1.2 代码实现
#include <stdio.h>

#define SIZE 5

int main() {
    int arr[SIZE] = {1, 2, 3, 4, 5};
    int sum = 0;
    for (int i = 0; i < SIZE; i++) {
        sum += arr[i];
    }
    printf("数组元素的和为:%d\n", sum);
    return 0;
}
3.1.3 思路分析

使用 for 循环遍历数组,将数组中的每个元素累加到变量 sum 中,最后输出 sum 的值。

3.2 数组元素查找

3.2.1 问题描述

给定一个数组和一个目标值,查找该目标值是否在数组中,如果存在则输出其下标,否则输出未找到的信息。

3.2.2 代码实现
#include <stdio.h>

#define SIZE 5

int main() {
    int arr[SIZE] = {1, 2, 3, 4, 5};
    int target;
    printf("请输入要查找的目标值:");
    scanf("%d", &target);
    int found = 0;
    for (int i = 0; i < SIZE; i++) {
        if (arr[i] == target) {
            printf("目标值 %d 的下标为:%d\n", target, i);
            found = 1;
            break;
        }
    }
    if (!found) {
        printf("未找到目标值 %d\n", target);
    }
    return 0;
}
3.2.3 思路分析

使用 for 循环遍历数组,将数组中的每个元素与目标值进行比较,如果相等则输出其下标并标记为已找到,使用 break 语句跳出循环;如果遍历完整个数组都未找到,则输出未找到的信息。

3.3 数组元素排序(冒泡排序)

3.3.1 问题描述

给定一个数组,使用冒泡排序算法对数组元素进行升序排序并输出排序后的数组。

3.3.2 代码实现
#include <stdio.h>

#define SIZE 5

void bubbleSort(int arr[], int size) {
    for (int i = 0; i < size - 1; i++) {
        for (int j = 0; j < size - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}

int main() {
    int arr[SIZE] = {5, 4, 3, 2, 1};
    bubbleSort(arr, SIZE);
    printf("排序后的数组为:");
    for (int i = 0; i < SIZE; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    return 0;
}
3.3.3 思路分析

冒泡排序的基本思想是多次比较相邻的元素,如果顺序错误就把它们交换过来。外层循环控制比较的轮数,内层循环控制每一轮比较的次数。在每一轮比较中,将较大的元素逐步“冒泡”到数组的末尾。

四、字符串处理类例题

4.1 字符串长度计算

4.1.1 问题描述

输入一个字符串,计算其长度并输出。

4.1.2 代码实现
#include <stdio.h>

int main() {
    char str[100];
    printf("请输入一个字符串:");
    scanf("%s", str);
    int len = 0;
    while (str[len] != '\0') {
        len++;
    }
    printf("字符串的长度为:%d\n", len);
    return 0;
}
4.1.3 思路分析

使用 while 循环遍历字符串,直到遇到字符串结束符 '\0' 为止,同时记录字符的个数,即为字符串的长度。

4.2 字符串反转

4.2.1 问题描述

输入一个字符串,将其反转并输出。

4.2.2 代码实现
#include <stdio.h>
#include <string.h>

int main() {
    char str[100];
    printf("请输入一个字符串:");
    scanf("%s", str);
    int len = strlen(str);
    for (int i = 0; i < len / 2; i++) {
        char temp = str[i];
        str[i] = str[len - i - 1];
        str[len - i - 1] = temp;
    }
    printf("反转后的字符串为:%s\n", str);
    return 0;
}
4.2.3 思路分析

通过交换字符串首尾对称位置的字符来实现字符串的反转。使用 strlen 函数获取字符串的长度,然后使用 for 循环遍历字符串的前半部分,将其与后半部分对应位置的字符进行交换。

4.3 字符串拼接

4.3.1 问题描述

输入两个字符串,将它们拼接成一个新的字符串并输出。

4.3.2 代码实现
#include <stdio.h>
#include <string.h>

int main() {
    char str1[100], str2[100], result[200];
    printf("请输入第一个字符串:");
    scanf("%s", str1);
    printf("请输入第二个字符串:");
    scanf("%s", str2);
    strcpy(result, str1);
    strcat(result, str2);
    printf("拼接后的字符串为:%s\n", result);
    return 0;
}
4.3.3 思路分析

使用 strcpy 函数将第一个字符串复制到结果字符串中,然后使用 strcat 函数将第二个字符串追加到结果字符串的末尾。

五、递归算法类例题

5.1 计算阶乘

5.1.1 问题描述

输入一个正整数,使用递归算法计算其阶乘并输出。

5.1.2 代码实现
#include <stdio.h>

int factorial(int n) {
    if (n == 0 || n == 1) {
        return 1;
    } else {
        return n * factorial(n - 1);
    }
}

int main() {
    int num;
    printf("请输入一个正整数:");
    scanf("%d", &num);
    int result = factorial(num);
    printf("%d 的阶乘为:%d\n", num, result);
    return 0;
}
5.1.3 思路分析

递归算法的核心是将一个大问题分解为一个或多个相似的小问题。对于阶乘问题,n 的阶乘等于 n 乘以 (n - 1) 的阶乘,当 n 为 0 或 1 时,阶乘的值为 1,这是递归的终止条件。

5.2 斐波那契数列

5.2.1 问题描述

输入一个正整数 n,使用递归算法输出斐波那契数列的第 n 项。斐波那契数列的定义为:F(0)=0F(0) = 0F(0)=0F(1)=1F(1) = 1F(1)=1F(n)=F(n−1)+F(n−2)F(n) = F(n - 1) + F(n - 2)F(n)=F(n1)+F(n2)n≥2n \geq 2n2)。

5.2.2 代码实现
#include <stdio.h>

int fibonacci(int n) {
    if (n == 0) {
        return 0;
    } else if (n == 1) {
        return 1;
    } else {
        return fibonacci(n - 1) + fibonacci(n - 2);
    }
}

int main() {
    int n;
    printf("请输入一个正整数:");
    scanf("%d", &n);
    int result = fibonacci(n);
    printf("斐波那契数列的第 %d 项为:%d\n", n, result);
    return 0;
}
5.2.3 思路分析

斐波那契数列的递归实现同样是将问题分解为更小的子问题。当 n 为 0 时,返回 0;当 n 为 1 时,返回 1;对于 n 大于 1 的情况,返回前两项的和。

六、其他经典例题

6.1 判断素数

6.1.1 问题描述

输入一个正整数,判断它是否为素数并输出结果。素数是指大于 1 且只能被 1 和自身整除的正整数。

6.1.2 代码实现
#include <stdio.h>
#include <stdbool.h>

bool isPrime(int num) {
    if (num <= 1) {
        return false;
    }
    for (int i = 2; i * i <= num; i++) {
        if (num % i == 0) {
            return false;
        }
    }
    return true;
}

int main() {
    int num;
    printf("请输入一个正整数:");
    scanf("%d", &num);
    if (isPrime(num)) {
        printf("%d 是素数\n", num);
    } else {
        printf("%d 不是素数\n", num);
    }
    return 0;
}
6.1.3 思路分析

判断一个数是否为素数,只需检查它是否能被 2 到该数的平方根之间的任何整数整除。如果能被整除,则不是素数;否则是素数。

6.2 最大公约数

6.2.1 问题描述

输入两个正整数,计算它们的最大公约数并输出。

6.2.2 代码实现
#include <stdio.h>

int gcd(int a, int b) {
    while (b != 0) {
        int temp = b;
        b = a % b;
        a = temp;
    }
    return a;
}

int main() {
    int num1, num2;
    printf("请输入两个正整数:");
    scanf("%d %d", &num1, &num2);
    int result = gcd(num1, num2);
    printf("%d 和 %d 的最大公约数为:%d\n", num1, num2, result);
    return 0;
}
6.2.3 思路分析

使用欧几里得算法(辗转相除法)来计算最大公约数。该算法的核心是不断用较小数除较大数取余数,直到余数为 0,此时的除数就是最大公约数。

6.3 最小公倍数

6.3.1 问题描述

输入两个正整数,计算它们的最小公倍数并输出。

6.2.2 代码实现
#include <stdio.h>

int gcd(int a, int b) {
    while (b != 0) {
        int temp = b;
        b = a % b;
        a = temp;
    }
    return a;
}

int lcm(int a, int b) {
    return (a / gcd(a, b)) * b;
}

int main() {
    int num1, num2;
    printf("请输入两个正整数:");
    scanf("%d %d", &num1, &num2);
    int result = lcm(num1, num2);
    printf("%d 和 %d 的最小公倍数为:%d\n", num1, num2, result);
    return 0;
}
6.2.3 思路分析

最小公倍数可以通过两个数的乘积除以它们的最大公约数来计算。先使用欧几里得算法计算最大公约数,再根据公式计算最小公倍数。

七、总结

通过这 50 道经典的 C 语言算法例题的练习,我们可以看到不同类型的算法问题有着各自独特的解题思路和方法。从基础的运算问题到复杂的递归算法,每一道题都蕴含着逻辑思维的魅力。在解决这些问题的过程中,我们不仅能够加深对 C 语言语法的理解,更重要的是能够锻炼自己的逻辑思维能力和问题解决能力。希望大家能够认真对待每一道例题,不断总结经验,提升自己的编程水平。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐