admin管理员组

文章数量:1794759

C语言大作业

C语言大作业

目录
  • 前言
  • 题目要求
  • 整体思路
  • “明7暗7数”
  • 求阶乘
  • 最大公约数及最小公倍数
  • 回文数
  • 素数
  • 完数
  • 运行截图
  • 结束语

前言

大家好哇,本人是大一的一名学生。刚学了一学期的C语言,发现挺有兴趣的hhhhhh.就在假期买了一本基础入门的书《C Primer Plus》来学习了一番。买的时候也没管太多,不管书的评价好坏与否(个人觉得还是很不错滴),反正也快看完了。又恰逢老师留了几个新手拿来练手的大作业,就想检验一下自己学的成果,也想通过写文章来获取大家的建议。有点啰嗦了…开始吧!

题目要求

第一题是要求我们写出一个整数处理程序。 输入两个正整数 m 和 n, 要求完成以下任务:

  • 求出 m 和 n 两数之间所有明7暗7数。
  • 分别求出 m! 和 n!。
  • 求 m 和 n 的最大公约数和最小公倍数。
  • 求出 m 和 n 之间的所有回文数。
  • 求出 m 和 n 之间的所有素数。
  • 求出 m 和 n 之间的所有完数。
  • 老师还说每个任务至少编写一个函数来完成,而且函数越多越好。 (文章最后附完整源代码)

    整体思路

    这道题目涉及的内容都是些较基础的,所以开干就完了,要啥功能写啥函数。(我也并没有设置输入判断,假设用户输入的都是正整数) 首先, 既然要处理两个整数,那之后调用的函数都要用到 m 和 n。我们假设函数要处理的对象都是后者>=前者,那么如果用户输入的 m < n, 就调换 m 和 n 的值。我们来编写一个交换两数数值的函数。

    • 传指针
    void swap(int * pa, int *pb) { /* ** 函数功能:交换两个数 ** 参 数:*pa, *pb 要交换两数的地址 ** 返 回 值:无 */ int temp; // 中间值 temp = *pa; *pa = *pb; *pb = temp; }

    再用#define预处理指令设置一行要打印的数字数量

    #define K 8 // 一行内打印数字的次数 “明7暗7数”
    • 明7:就是数字里包含‘7’这个数的,如37,173等等。
    • 暗7:就是能被7整除的数,如49,63等对7求模得0的数(0除外)。
    • 代码如下
    void seven(int m, int n) { /* ** 函数功能:输出两数之间所有"明7暗7"数 ** 参 数:m, n 待处理对象 ** 返 回 值:无 */ int i, count = 0; // count 已打印数量 printf("\\n%d与%d之间的\\"明7暗7\\"数有:\\n", m, n); printf("包含7的数有:\\n"); for (i = m; i <= n; i++) { if (within_seven(i)) // 判断是否包含"7" { printf("%5d", i); count++; if (count % K == 0) // 每打印K个数字换行 printf("\\n"); } } count = 0; printf("\\n能被7整除的数有:\\n"); for (i = m; i <= n; i++) { if (i % 7 == 0) // 判断是否被7整除 { printf("%5d", i); count++; if (count % K == 0) // 每打印K个数字换行 printf("\\n"); } } printf("\\n"); }
    • 上面的代码块中有一个within_seven()函数,是用来判断“明7数”的。
    int within_seven(int n) { /* ** 函数功能:判断是否包含"7" ** 参 数:n 待处理对象 ** 返 回 值:[1为包含,0为不包含] */ char number[10]; sprintf(number, "%d", n); // 把整数参数存为字符串处理 if (strchr(number, '7')) return 1; return 0; }
    • 用到了字符串函数strchr()所以程序要包含<string.h>头文件。
    • 还有利用输入流sprintf()函数把数字转换为字符串以便处理。
    求阶乘
    • 这个函数直接返回参数的阶乘好了。 代码如下
    double factorial(int n) { /* ** 函数功能:计算阶乘 ** 参 数:n 待处理对象 ** 返 回 值:n 的阶乘 */ double fac = 1; for (int i = 1; i <= n; i++) { fac *= i; } return fac; }
    • 我这里用了循环,还可以用递归。
    double factorial(int n) { if (n == 0) return 1; else return n * factorial(n - 1); }
    • 主函数内调用情况
    printf("\\n输入两数的阶乘:"); printf("\\n%3d! = ", m); // 阶乘小用%lf打印,太大用%e打印 printf((m > 15)? "%.13e\\n" : "%.0lf\\n", factorial(m)); printf("%3d! = ", n); printf((n > 15)? "%.13e\\n" : "%.0lf\\n", factorial(n));
    • 可能注意到了我这里很麻烦,浮点数可以直接用%g打印
    最大公约数及最小公倍数
    • 结果也直接返回到主程序。
    • 这里用了枚举法(别的方法我竟然还没有尝试过)。代码如下
    int gys(int m, int n) { /* ** 函数功能:计算两数最大公约数 ** 参 数:m, n 待处理对象 ** 返 回 值:最大公约数 */ int i, max; for (i = 1; i <= m; i++) { if (m % i == 0 && n % i == 0) max = i; // 循环赋给max最大公约数 } return max; } int gbs(int m, int n) { /* ** 函数功能:计算两数最小公倍数 ** 参 数:m, n 待处理对象 ** 返 回 值:最小公倍数 */ return (m * n / gys(m, n)); // 两个数的积 = 最小公倍数 * 最大公约数 } 回文数
    • 接下来就是求回文数(正着读反着读都一样的数)。也转换成字符串处理。
    • 代码如下
    void palindrome(int m, int n) { /* ** 函数功能:输出两数之间所有回文数 ** 参 数:m, n 待处理对象 ** 返 回 值:无 */ int i, count = 0; // count 已打印数量 printf("\\n%d与%d之间的回文数有:\\n", m, n); for (i = m; i <= n; i++) { if (is_palin(i)) // 判断是否为回文数 { printf("%5d", i); count++; if (count % K == 0) // 每打印K个数字换行 printf("\\n"); } } printf("\\n"); } int is_palin(int n) { /* ** 函数功能:判断是否为回文数 ** 参 数:n 待处理对象 ** 返 回 值:[1为回文,0不是] */ int i, len, count = 0; // len 参数长度 char number[10], rever[10]; sprintf(number, "%d", n); // 把参数存为字符串 len = strlen(number); reverse(number, rever); // 倒序存在另一字符串 for (i = 0; i < len; i++) { if (number[i] == rever[i]) // 如对应字符相同,count+1 count++; } if (count == len) // 相同字符数等同原字符串长度,返回1 return 1; return 0; }
    • 上面也包含着一个判断是否为回文数的函数。
    • 下面给出倒置字符串函数(可能因为我处理得不够好,这部分代码感觉很繁琐)
    void reverse(char * source, char * target) { /* ** 函数功能:倒置另存字符串 ** 参 数:原字符数组,目标字符数组 ** 返 回 值:无 */ int i, j, srclen = strlen(source); for (i = srclen - 1, j = 0; i >= 0; i--, j++) { *(target + j) = *(source + i); } }
    • 处理回文数函数和剩下的两个函数都很相似,都包含着一个判断的函数作为 if 的判断条件。
    素数
    • 直接上代码
    void prime(int m, int n) { /* ** 函数功能:输出两数之间所有素数 ** 参 数:m, n 待处理对象 ** 返 回 值:无 */ int i, count = 0; // count 已打印数量 printf("\\n%d与%d之间的素数有:\\n", m, n); for (i = m; i <= n; i++) { if (is_prime(i)) // 判断是否为素数 { printf("%5d", i); count++; if (count % K == 0) // 每打印K个数字换行 printf("\\n"); } } printf("\\n"); } int is_prime(int n) { /* ** 函数功能:判断是否为素数 ** 参 数:n 待处理对象 ** 返 回 值:[1为素数,0不是] */ int i = 2; if (n == 1) return 0; // 1不是素数 if (n == 2) return 1; // 2是素数 for (i = 2; i < n ; i++) { if (n % i == 0) return 0; } return 1; } 完数
    • 废话少说
    • (还是说一下,完数:一个数的所有因子(包括1)之和等于它自身。)
    void perfect(int m, int n) { /* ** 函数功能:输出两数之间所有完数 ** 参 数:m, n 待处理对象 ** 返 回 值:无 */ int i, j; printf("\\n%d与%d之间的所有完数及其因子:\\n", m, n); for (i = m; i <= n; i++) { if (is_perfect(i)) // 判断是否为完数 { printf("%5d 的因子有 ", i); for (j = 1; j < i; j++) { if (i % j == 0) printf("%d,", j); } printf("\\b \\n"); } } printf("\\n"); } int is_perfect(int n) { /* ** 函数功能:判断是否为完数 ** 参 数:n 待处理对象 ** 返 回 值:[1是完数,0不是] */ int i, sum = 0; for (i = 1; i < n; i++) { if (n % i == 0) sum += i; } if (sum == n) return 1; return 0; }
    • 品吧。
    运行截图

    结束语

    函数的数量老师应该会满意吧~ 我发布的第一篇文章就到这里啦。程序有很多的不足,日后也会改进,也希望各位可以给出宝贵的意见!后续还有5个题吧我记着…做完也会慢慢发布的。敬请期待。。。 差点忘了完整源码

    #include <stdio.h> #include <string.h> #define K 8 // 一行内打印数字的次数 #define _ 0 // 函数原型 void swap (int *, int *); // 交换两数 void seven (int, int); // 输出"明7暗7"数 int within_seven (int); // 判断是否包含"7" double factorial (int); // 阶乘 int gys (int, int); // 最大公约数 int gbs (int, int); // 最小公倍数 void palindrome (int, int); // 输出回文数 int is_palin (int); // 判断回文数 void prime (int, int); // 输出素数 int is_prime (int); // 判断素数 void perfect (int, int); // 输出完数 int is_perfect (int); // 判断完数 void reverse (char *, char *); // 倒置字符串 int main() { int m, n; printf("请输入两个正整数。(回车键退出)\\n"); printf("请输入第一个数字:"); scanf("%d", &m); printf("请输入第二个数字:"); scanf("%d", &n); if (m > n) // 如果m > n, 交换 swap(&m, &n); seven(m, n); // 输出"明7暗7"数 printf("\\n输入两数的阶乘:"); printf("\\n%3d! = ", m); // 阶乘小用%lf打印,太大用%e打印 printf((m > 15)? "%.13e\\n" : "%.0lf\\n", factorial(m)); printf("%3d! = ", n); printf((n > 15)? "%.13e\\n" : "%.0lf\\n", factorial(n)); printf("\\n输入两数的最大公约数,最小公倍数:\\n"); printf("%d与%d的最大公约数为%d\\n", m, n, gys(m, n)); printf("%d与%d的最小公倍数为%d\\n", m, n, gbs(m, n)); palindrome(m, n); // 输出回文数 prime(m, n); // 输出素数 perfect(m, n); // 输出完数 return (0^_^0); } void swap(int * pa, int *pb) { /* ** 函数功能:交换两个数 ** 参 数:*pa, *pb 要交换两数的地址 ** 返 回 值:无 */ int temp; // 中间值 temp = *pa; *pa = *pb; *pb = temp; } void seven(int m, int n) { /* ** 函数功能:输出两数之间所有"明7暗7"数 ** 参 数:m, n 待处理对象 ** 返 回 值:无 */ int i, count = 0; // count 已打印数量 printf("\\n%d与%d之间的\\"明7暗7\\"数有:\\n", m, n); printf("包含7的数有:\\n"); for (i = m; i <= n; i++) { if (within_seven(i)) // 判断是否包含"7" { printf("%5d", i); count++; if (count % K == 0) // 每打印K个数字换行 printf("\\n"); } } count = 0; printf("\\n能被7整除的数有:\\n"); for (i = m; i <= n; i++) { if (i % 7 == 0) // 判断是否被7整除 { printf("%5d", i); count++; if (count % K == 0) // 每打印K个数字换行 printf("\\n"); } } printf("\\n"); } int within_seven(int n) { /* ** 函数功能:判断是否包含"7" ** 参 数:n 待处理对象 ** 返 回 值:[1为包含,0为不包含] */ char number[10]; sprintf(number, "%d", n); // 把整数参数存为字符串处理 if (strchr(number, '7')) return 1; return 0; } double factorial(int n) { /* ** 函数功能:计算阶乘 ** 参 数:n 待处理对象 ** 返 回 值:n 的阶乘 */ double fac = 1; for (int i = 1; i <= n; i++) { fac *= i; } return fac; } int gys(int m, int n) { /* ** 函数功能:计算两数最大公约数 ** 参 数:m, n 待处理对象 ** 返 回 值:最大公约数 */ int i, max; for (i = 1; i <= m; i++) { if (m % i == 0 && n % i == 0) max = i; // 循环赋给max最大公约数 } return max; } int gbs(int m, int n) { /* ** 函数功能:计算两数最小公倍数 ** 参 数:m, n 待处理对象 ** 返 回 值:最小公倍数 */ return (m * n / gys(m, n)); // 两个数的积 = 最小公倍数 * 最大公约数 } void palindrome(int m, int n) { /* ** 函数功能:输出两数之间所有回文数 ** 参 数:m, n 待处理对象 ** 返 回 值:无 */ int i, count = 0; // count 已打印数量 printf("\\n%d与%d之间的回文数有:\\n", m, n); for (i = m; i <= n; i++) { if (is_palin(i)) // 判断是否为回文数 { printf("%5d", i); count++; if (count % K == 0) // 每打印K个数字换行 printf("\\n"); } } printf("\\n"); } int is_palin(int n) { /* ** 函数功能:判断是否为回文数 ** 参 数:n 待处理对象 ** 返 回 值:[1为回文,0不是] */ int i, len, count = 0; // len 参数长度 char number[10], rever[10]; sprintf(number, "%d", n); // 把参数存为字符串 len = strlen(number); reverse(number, rever); // 倒序存在另一字符串 for (i = 0; i < len; i++) { if (number[i] == rever[i]) // 如对应字符相同,count+1 count++; } if (count == len) // 相同字符数等同原字符串长度,返回1 return 1; return 0; } void reverse(char * source, char * target) { /* ** 函数功能:倒置另存字符串 ** 参 数:原字符数组,目标字符数组 ** 返 回 值:无 */ int i, j, srclen = strlen(source); for (i = srclen - 1, j = 0; i >= 0; i--, j++) { *(target + j) = *(source + i); } } void prime(int m, int n) { /* ** 函数功能:输出两数之间所有素数 ** 参 数:m, n 待处理对象 ** 返 回 值:无 */ int i, count = 0; // count 已打印数量 printf("\\n%d与%d之间的素数有:\\n", m, n); for (i = m; i <= n; i++) { if (is_prime(i)) // 判断是否为素数 { printf("%5d", i); count++; if (count % K == 0) // 每打印K个数字换行 printf("\\n"); } } printf("\\n"); } int is_prime(int n) { /* ** 函数功能:判断是否为素数 ** 参 数:n 待处理对象 ** 返 回 值:[1为素数,0不是] */ int i = 2; if (n == 1) return 0; // 1不是素数 if (n == 2) return 1; // 2是素数 for (i = 2; i < n ; i++) { if (n % i == 0) return 0; } return 1; } void perfect(int m, int n) { /* ** 函数功能:输出两数之间所有完数 ** 参 数:m, n 待处理对象 ** 返 回 值:无 */ int i, j; printf("\\n%d与%d之间的所有完数及其因子:\\n", m, n); for (i = m; i <= n; i++) { if (is_perfect(i)) // 判断是否为完数 { printf("%5d 的因子有 ", i); for (j = 1; j < i; j++) { if (i % j == 0) printf("%d,", j); } printf("\\b \\n"); } } printf("\\n"); } int is_perfect(int n) { /* ** 函数功能:判断是否为完数 ** 参 数:n 待处理对象 ** 返 回 值:[1是完数,0不是] */ int i, sum = 0; for (i = 1; i < n; i++) { if (n % i == 0) sum += i; } if (sum == n) return 1; return 0; }

    再见!

    本文标签: 作业语言