第五章:循环结构程序设计,重点介绍如何通过循环结构实现代码的重复执行,简化编程任务,提高代码可读性和可维护性。
友情提示:有的题目可能没写,因为我感觉没必要,还有就是下面的所有回答专业性的名词解释使用人工智能或Baidu的,程序是完全自己写的,主要是用来记笔记方便以后复习用的,希望对大家有帮助,共勉!
题目1:输入两个正整数m和n,求其最大公约数和最小公倍数。
基础知识:什么是最大公约数和最小公倍数
最大公约数: 是两个或多个整数共有的最大的能整除它们的正整数。
例如,对于整数12和18,它们的公约数有1, 2, 3, 6,其中最大的公约数是6,所以GCD(12, 18) = 6。
最小公倍数:是两个或多个整数的公共倍数中最小的一个。
例如,对于整数12和18,它们的倍数有24, 36, 72, ...等,其中最小的公倍数是36,所以LCM(12, 18) = 36。
#include <stdio.h>
int main(){
int m,n,min,i;
printf("请输入两个正整数:\n");
scanf("%d %d",&m,&n);
//1.求最大公约数
//找到两个数中最小的那个值,因为最大公约数一定比最小值还小
if(m > n)
min = n;
else
min = m;
int gcd = 1;//记录最大公约数,初始化为1
for(i = 1;i <= min;i++){
if(m % i == 0 && n % i == 0){
gcd = i;//更新公约数的值,以能得到最大公约数
}
}
printf("最大公约数为:%d\n",gcd);
//2.求最小公倍数(法一)
//最大公倍数要比比较的最大值还要大
int max = m > n ? m : n;
for(i = max; ;i++){//不要参数2的条件表达式,满足下面的条件直接退出即可
if(i % m == 0 && i % n == 0)
break;
}
printf("最小公倍数是:%d\n",i);
//2.求最小公倍数(法二)
//已知最大公约数求最小公倍数的公式:LCM=(m*n)/GCD
int lcm = m * n / gcd;
printf("最小公倍数为:%d\n",lcm);
return 0;
}
题目2:统计相应字符数
分析:
需要使用C语言中的<ctype.h>头文件,里面有isalpha()函数判断是否为英文字母,isdigit()函数判断是否为数字,isspace()函数判断是否是一个空白字符(如空格、制表符和换行符等)
#include <stdio.h>
#include <ctype.h>
int main() {
char c; // 用于存储读取的每个字符
int letters = 0, spaces = 0, digits = 0, others = 0; // 分别用于存储字母、空格、数字和其他字符的数量
printf("请输入一行字符:\n"); // 提示用户输入
// 循环读取每一个字符,直到读取到换行符或文件结束符
while ((c = getchar()) != '\n' && c != EOF) {
// 判断字符的类型
if (isalpha(c)) { // 如果字符是字母
letters++; // 字母的数量加1
} else if (isspace(c)) { // 如果字符是空格
spaces++; // 空格的数量加1
} else if (isdigit(c)) { // 如果字符是数字
digits++; // 数字的数量加1
} else { // 如果字符既不是字母,也不是空格,也不是数字,那么它就是其他字符
others++; // 其他字符的数量加1
}
}
// 输出结果
printf("英文字母的个数: %d\n", letters);
printf("空格的个数: %d\n", spaces);
printf("数字的个数: %d\n", digits);
printf("其他字符的个数: %d\n", others);
return 0;
}
扩展:
源文件中的EOF是什么
EOF是End Of File的缩写,表示文件结束。在C语言中,当读取文件或标准输入(如键盘)的数据时,如果已经读到了数据的末尾,那么再次尝试读取数据就会得到EOF。在C标准库中,EOF被定义为一个负的整数,通常是-1。这是因为所有的字符都可以表示为非负的整数,所以可以使用一个负的整数来表示读取数据已经到达末尾。
可以不写EOF判断吗?
可以不写,但是最好写,因为在一些情况下,输入可能会在没有换行符的情况下结束,此时getchar()
会返回EOF。例如,如果程序是从一个文件或者其他程序读取输入,或者在命令行中重定向了输入。在这些情况下,如果你不检查EOF,你的程序可能会陷入无限循环。
题目3:求2+22+222+2222+2222
分析:
观察规律,首先是2,然后加上2*10+2得到22,然后加上22*10+2,以此类推,通过这个规律计算每一次的结果,然后将结果加一起即可实现
#include <stdio.h>
int main(){
int number, n, sum = 0, res = 0, temp; // 引入temp变量来保存res的当前值
printf("请输入要计算的值和需要计算多少次:");
scanf("%d", &number);
scanf("%d", &n);
res = number; // 初始化res为输入的值
for(int i = 1; i <= n; i++){
temp = res; // 保存res的当前值
res = res * 10 + number; // 更新res为下一个递增的数
sum += temp; // 累加temp(即res的当前值)到sum中
}
printf("sum = %d\n", sum);
return 0;
}
题目4:求1! + 2! + 3! + 4! + 5!+......+ 20!
使用递归进行实现的
要注意,这个计算的值特别的大,要使用long long int或者更大的unsigned long long int 类型来存储,其中long long int
可以表示的范围是从-9223372036854775808到9223372036854775807,unsigned long long int
可以表示的范围是从0到18446744073709551615。
#include <stdio.h>
//定义一个递归函数
unsigned long long int recursion(int n){
if(n <= 1)
return 1;//0! == 1 1! == 1
else
return n * recursion(n - 1);//递归调用计算(n-1)!然后乘以n
}
int main(){
unsigned long long int sum = 0;//因为计算的值太大了,使用
//循环计算1!到20!的和
for(int i = 1;i <= 20;i++){
sum += recursion(i);
}
printf("sum = %llu\n",sum);
return 0;
}
题目5:水仙花数
水仙花数的概念:
水仙花数是指一个3位数,它的每一位上的数字的3次幂之和等于它本身。例如,153是一个3位数的水仙花数,因为1^3 + 5^3 + 3^3 = 153。
思路:
通过一个循环遍历100到999之间的所有数,然后通过一些简单的数学操作,如除法和取余获取每个数的百位、十位和个位数字。如果这个数等于它的每个位上的数字的立方之和,那么这个数就是水仙花数,程序会将其打印出来。
#include <stdio.h>
int main(){
int i, a, b, c;
for(i=100; i<1000; i++){
a = i / 100; //百位数
b = i / 10 % 10; //十位数
c = i % 10; //个位数
if(i == a*a*a + b*b*b + c*c*c){
printf("%d\n", i);
}
}
return 0;
}
题目6:完数
思路:
使用外层for循环来控制遍历1到1000中的每一个数,然后使用内层for循环对每一个数找出所有的因子,然后将所有因子的和与这个数进行比较。如果两者相等,那么这个数就是完数。
#include <stdio.h>
int main() {
int i, j, sum;
//外层循环找到1-1000以内的数
for(i=1; i<=1000; i++){
sum = 0;//保证每次检查新的数时,都是从0开始叠加的
//内层循环找到数的因子
for(j=1; j<i; j++){
if(i % j == 0){
sum += j;
}
}
//如果因子的和与原始值相等的话,就是完数
if(sum == i){
printf("%d its factors are ", i); //如果i是一个完数,先打印出i及其开头的提示信息
//循环打印完数的因子
for(j=1; j<i; j++){
if(i % j == 0){
printf("%d, ", j); //打印出i的所有因子
}
}
//\b 是一个转义字符,代表退格
//在 printf 函数中使用 \b 时,它会使光标向后移动一个位置
//相当于删除了最后打印出的一个字符。
printf("\b\b \n"); //删除最后打印的", ",然后换行
}
}
return 0;
}
题目7:输出以下图案
思路:通过观察空格数和星星数进行编写,找出规律如下。
-
空格数:从第一行开始,空格数逐渐减少,直到中间行时空格数才为0。可以推出空格数的计算是
size - i - 1
,其中i
是当前行数(从0开始)。 -
星星数:从第一行开始,星星数逐渐增加,直到中间行才达到最大值,然后星星数开始减少。星星数的计算是
2 * i + 1
(对于上半部分)或2 * (size - i - 2) + 1
(对于下半部分,不包括中间行,因为中间行在上半部分已经打印了)。
值得注意的是,对于size
为偶数的情况,中间两行星星数相同,且为最大值(不是本题考虑的范围)。
#include <stdio.h>
int main() {
int i, j;
int size = 4; // 定义图形的大小,这里是4层
// 打印上半部分包括中间的星号行
for(i = 0;i < size;i++) {
//打印每一行之前的空格
for(j = 0;j < size - i - 1;j++) {
printf(" ");
}
//打印每一行的星星*
for(j = 0;j < 2 * i + 1;j++) {
printf("*");
}
printf("\n");
}
//打印下半部分的星号行
//这里的循环将从下到上打印出等腰三角形的下半部分(除了中间的那一行,因为它已经在上面打印过了)
for(i = size - 2;i >= 0;i--) {
//打印空格
for(j = 0;j < size - i - 1;j++) {
printf(" ");
}
//打印星星*
for(j = 0;j < 2 * i + 1;j++) {
printf("*");
}
printf("\n");
}
return 0;
}