青衣 发表于 2021-7-9 09:39:14

大学生必学练习题 - C 语言经典50例

  
  文章目录

[*]

[*]引言
[*]回文数
[*]汉诺塔
[*]无重复数字
[*]判断星期几
[*]字符串反转
[*]数字排序
[*]九九乘法表
[*]兔子生崽
[*]素数
[*]水仙花数
[*]小球自由下落
[*]求自然底数e
[*]杨辉三角
[*]最小公倍数
[*]亲密数


  
引言
  在大学期间,C语言几乎是每个计算机专业必学的课程,在学习掌握基础知识之后,通过大量的C语言练习题,手写代码,是巩固基础知识,锻炼编程思维的重要手段之一。下面介绍C语言练习实例50例,题目+解决方法。

回文数
  题目:输入一个数,判断它是不是回文数。一个数从左边读和从右边读的结果是一模一样的话就是回文数,例如12321是回文数,12531不是回文数。
  分析:判断从左边读和右边读,结果是不是一样。
#include <stdio.h>

int main( ) {
    int num, x, y = 0;
    printf("请输入一位数:");
    scanf("%d", &num);
    x = num;
    while (x > 0) {
      y = y * 10 + x % 10;
      x = x / 10;
    }
    if (num == y) {
      printf("%d是一个回文数", num);
    } else {
      printf("%d不是一个回文数", num);
    }
}
请输入一位数:12321
12321是一个回文数

汉诺塔
  题目:假设一块板上有三根针 A、B、C。A 针上套有 64 个大小不等的圆盘,按照大的在下、小的在上的顺序排列,要把这 64 个圆盘从 A 针移动到 C 针上,每次只能移动一个圆盘,移动过程可以借助 B 针。但在任何时候,任何针上的圆盘都必须保持大盘在下,小盘在上。从键盘输入需移动的圆盘个数,给出移动的过程。
  分析:利用递归实现圆盘的整个移动过程;当只移动一个圆盘时,直接将圆盘从 A 针移动到 C 针。若移动的圆盘为 n(n>1),则分成几步走:把 (n-1) 个圆盘从 A 针移动到 B 针(借助 C 针);A 针上的最后一个圆盘移动到 C 针;B 针上的 (n-1) 个圆盘移动到 C 针(借助 A 针)。每做一遍,移动的圆盘少一个,逐次递减,最后当 n 为 1 时,完成整个移动过程。
#include <stdio.h>

int move(char from, int n, char to) {
    static int k = 1;
    printf("%2d:%3d # %c---%c\n", k, n, from, to);
    if (k++ % 3 == 0)
      printf("\n");
    return 0;
}

int hanoi(int n, char x, char y, char z) {
    if (n == 1)
      move(x, 1, z);
    else {
      hanoi(n - 1, x, z, y);
      move(x, n, z);
      hanoi(n - 1, y, x, z);
    }
    return 0;
}

int main() {
    int n;
    printf("请输入盘子的数量:");
    scanf("%d", &n);
    printf("\n");
    hanoi(n, 'A', 'B', 'C');
    return 0;
}
  演示输出结果如下:
请输入盘子的数量:3

1:1 # A---C
2:2 # A---B
3:1 # C---B

4:3 # A---C
5:1 # B---A
6:2 # B---C

7:1 # A---C

无重复数字
  题目:给你1、2、3、4、5总共五个数字,能组成多少个互不相同且无重复数字的三位数?并且输出。
  分析:通过三层循环遍历,遍历所有情况,并排除重复的数字即可。
#include <stdio.h>

int main() {
    int i, j, k; // i,j,k分别代表百位,十位,个位
    int count = 0; // 记录总共不重复的数字的个数
    for (i = 1; i <= 5; i++) {
      for (j = 1; j <= 5; j++) {
            for (k = 1; k <= 5; k++) {
                if (i != k && i != j && j != k) {
                  count++;
                  printf("%d%d%d ", i, j, k);
                  if (0 == count % 10) {
                        printf("\n");
                  }
                }
            }
      }
    }
    printf("不重复的数字的个数为:%d", count);
}
  演示输出结果如下:
123 124 125 132 134 135 142 143 145 152
153 154 213 214 215 231 234 235 241 243
245 251 253 254 312 314 315 321 324 325
341 342 345 351 352 354 412 413 415 421
423 425 431 432 435 451 452 453 512 513
514 521 523 524 531 532 534 541 542 543
不重复的数字的个数为:60

判断星期几
  题目:输入星期几的第一个字母,判断是星期几,如果第一个字母一样,则继续输入第二个字母进行判断。
  分析:首先可以通过 switch 语句进行大方向判断,首字母一样再通过 if 语句判断。
#include <stdio.h>

int main() {
    char i, j;
    printf("请输入星期几第一个字母:");
    scanf("%c", &i);
    // scanf("%c",&j) 最后会输入一个换行符,需要使用调这个换行符,避免下一次读取字符时读取到上一次的换行符
    getchar();
    switch (i) {
      case 'm':
            printf("monday\n");
            break;
      case 'w':
            printf("wednesday\n");
            break;
      case 'f':
            printf("friday\n");
            break;
      case 't':
            printf("请输入星期几第二个字母:");
            scanf("%c", &j);
            if (j == 'u') {
                printf("tuesday\n");
                break;
            }
            if (j == 'h') {
                printf("thursday\n");
                break;
            }
      case 's':
            printf("请输入星期几第二个字母:");
            scanf("%c", &j);
            if (j == 'a') {
                printf("saturday\n");
                break;
            }
            if (j == 'u') {
                printf("sunday\n");
                break;
            }
      default :
            printf("error\n");
            break;
    }
    return 0;
}
  演示输出结果如下:
请输入星期几第一个字母:t
请输入星期几第二个字母:u
tuesday

字符串反转
  题目:字符串反转,例如 chenPiJavaLib 翻转为 biLavaJiPnehc。
#include <stdio.h>

void reverse(char* s)
{
    // 获取字符串长度
    int len = 0;
    char* p = s;
    while (*p != 0)
    {
      len++;
      p++;
    }

    // 首尾交换字符
    int i = 0;
    char c;
    while (i <= len / 2 - 1)
    {
      c = *(s + i);
      *(s + i) = *(s + len - 1 - i);
      *(s + len - 1 - i) = c;
      i++;
    }
}

int main()
{
    char s[] = "chenPiJavaLib";
    printf("翻转前:%s\n", s);
    reverse(s);
    printf("翻转后:%s", s);
    return 0;
}
  演示输出结果如下:
翻转前:chenPiJavaLib
翻转后:biLavaJiPnehc

数字排序
  题目:输入三个整数 x,y,z,请把这三个数由小到大输出。
  分析:先将 x 分别与 y,z 比较,将最小的值赋值到 x。然后 y 和 z 再进行比较,找出第二小的值赋值到 y。最后 x,y,z 就是从小到大的数。
#include <stdio.h>

int main() {
    int x, y, z, t;
    printf("请输入三个数字(逗号隔开):");
    scanf("%d,%d,%d", &x, &y, &z);
    if (x > y) {
      t = x;
      x = y;
      y = t;
    }
    if (x > z) {
      t = z;
      z = x;
      x = t;
    }
    if (y > z) {
      t = y;
      y = z;
      z = t;
    }
    printf("从小到大排序: %d %d %d", x, y, z);
}
  演示输出结果如下:
请输入三个数字(逗号隔开):10,2,6
从小到大排序: 2 6 10

九九乘法表
  题目:输出九九乘法表。
#include <stdio.h>

int main() {
    int i, j, result;
    for (i = 1; i < 10; i++) {
      for (j = 1; j <= i; j++) {
            result = i * j;
            printf("%d*%d=%-3d", i, j, result);
      }
      printf("\n");
    }
}
  演示输出结果如下:
1*1=1
2*1=22*2=4
3*1=33*2=63*3=9
4*1=44*2=84*3=12 4*4=16
5*1=55*2=10 5*3=15 5*4=20 5*5=25
6*1=66*2=12 6*3=18 6*4=24 6*5=30 6*6=36
7*1=77*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49
8*1=88*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64
9*1=99*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81

兔子生崽
  题目:一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子对数总数为多少?假设输出前30个月。
  分析:兔子的个数规律为:1,1,2,3,5,8,13,21…,即下个月是上两个月之和(从第三个月开始)。
#include <stdio.h>

int main() {
    int f1 = 1, f2 = 1, i;
    for (i = 1; i <= 15; i++) {
      printf("%12d%12d", f1, f2);
      if (i % 2 == 0) printf("\n");
      f1 = f1 + f2;
      f2 = f1 + f2;
    }

    return 0;
}
  演示输出结果如下:
         1         1         2         3
         5         8          13          21
          34          55          89         144
         233         377         610         987
      1597      2584      4181      6765
       10946       17711       28657       46368
       75025      121393      196418      317811
      514229      832040

素数
  题目:判断3到200之间的素数。
  分析:对于一个数 n,如果 2 到 n - 1 之间存在一个数能被 n 整除,则这个数 n 不是素数,反之则是素数。
#include <stdio.h>

int main() {
    int i, j;
    int count = 0;
    char isPrime;
    for (i = 3; i <= 200; i++) {
      isPrime = 'Y';
      for (j = 2; j < i; j++) {
            // 如果存在一个能整除的,则不是素数
            if (i % j == 0) {
                isPrime = 'N';
                break;
            }
      }
      if ('Y' == isPrime) {
            count++;
            printf("%3d ", i);
            // 每10个数换行
            if (count % 10 == 0)
                printf("\n");
      }
    }
    return 0;
}
  演示输出结果如下:
3   5   711131719232931
37414347535961677173
79838997 101 103 107 109 113 127
131 137 139 149 151 157 163 167 173 179
181 191 193 197 199

水仙花数
  题目:水仙花数 是指一个三位数,其各位数字立方和等于该数本身。例如:153是一个水仙花数,153 = 1^3 + 5^3 + 3^3.
  分析:遍历100-999 之间的数,计算每位数字的立方是否等于其本身.
#include <stdio.h>

int main() {
    int i, x, y, z;
    for (i = 100; i <= 999; i++) {
      x = i % 10;
      y = i / 10 % 10;
      z = i / 100 % 10;

      if (i == (x * x * x + y * y * y + z * z * z))
            printf("%d\n", i);
    }
    return 0;
}
  演示输出结果如下:
153
370
371
407

小球自由下落
  题目:一球从100米高度自由落下,每次落地后反跳回原高度的一半,再落下,求它在第10次落地时,共经过多少米?第10次反弹多高?
#include <stdio.h>

int main() {
    float h = 100, s = 100;
    //第一次反弹高度
    h = h / 2;
    for (int i = 2; i <= 10; i++) {
      s = s + 2 * h;
      h = h / 2;
    }
    printf("第10次落地时,共经过%f米,第10次反弹高%f米", s, h);
    return 0;
}
  演示输出结果如下:
第10次落地时,共经过299.609375米,第10次反弹高0.097656米

求自然底数e
  题目:自然底数 e=2.718281828…,e 的计算公式:e=1+1/1!+1/2!+1/3!+…。当最后一项的值小于 10^-10 时结束。
  分析:循环遍历累加求和,并在求和后计算下一项所对应的阶乘。
#include <stdio.h>

int main() {
    double e = 1.0, n = 1.0;
    int i = 1;
    while (1 / n > 1e-10) {
      e += 1 / n;
      i++;
      n = i * n;
    }
    printf("e=%f", e);
    return 0;
}
  演示输出结果如下:
e=2.718282

杨辉三角
  题目:杨辉三角的两个腰边的数都是 1,其它位置的数都是上顶上两个数之和。
#include <stdio.h>

int main() {
    int i, j, k, n = 0;
    printf("输入要打印的行数:");
    scanf("%d", &n);

    int a;

    printf("%d行杨辉三角如下:\n", n);

    for (i = 1; i <= n; i++)
      a = a = 1;// 两边的数令它为1
    for (i = 3; i <= n; i++)
      for (j = 2; j <= i - 1; j++)
            a = a + a;// 除两边的数外都等于上两顶数之和
    for (i = 1; i <= n; i++) {
      for (k = 1; k <= n - i; k++)
            printf("   ");// 让显示美观,在输出数之前打上合适的空格
      for (j = 1; j <= i; j++)
            printf("%6d", a);

      printf("\n");// 当一行数字输出后换行
    }
    printf("\n");
}
  演示输出结果如下:
输入要打印的行数:10
10行杨辉三角如下:
                              1
                           1   1
                        1   2   1
                     1   3   3   1
                  1   4   6   4   1
               1   5    10    10   5   1
            1   6    15    20    15   6   1
         1   7    21    35    35    21   7   1
      1   8    28    56    70    56    28   8   1
   1   9    36    84   126   126    84    36   9   1

最小公倍数
  题目:求任意两个正整数的最小公倍数.
#include <stdio.h>

int main() {
    int a, b, temp, i;
    printf("请输入两个数字,同空格隔开:");
    scanf("%d %d", &a, &b);
    // 保证 a >= b
    if (a < b) {
      temp = a;
      a = b;
      b = temp;
    }
    for (i = a; i > 0; i++)// 从大数开始查找满足条件的数
      if (i % a == 0 && i % b == 0) {
            printf("%d 和 %d 的最小公倍数是%d", a, b, i);
            break;
      }

    return 0;
}
  演示输出结果如下:
请输入两个数字,同空格隔开:12 8
12 和 8 的最小公倍数是24

亲密数
  题目:一个整数 X 的全部因子(包括1,不包括 X 本身)之和等于 Y;并且整数 Y 的全部因子(包括1,不包括 Y 本身)之和等于 X ,则将整数 X 和 Y 称为亲密数。求3000以内的全部亲密数。
#include <stdio.h>

int main() {
    int i, x, y, z;

    for (i = 1; i < 3000; i++) {
      for (y = 0, x = 1; x <= i / 2; x++)
            // 计算x的所有因子之后,保存再y中
            if (0 == (i % x))
                y += x;
      for (z = 0, x = 1; x <= y / 2; x++)
            // 计算y的所有因子之后,保存再z中
            if (0 == (y% x))
                z+= x;
      if (z== i && i < y)
            printf("%4d 的亲密数是 %4d\n", i, y);
    }

    return 0;
}
  演示输出结果如下:
220 的亲密数是284
1184 的亲密数是 1210
2620 的亲密数是 2924

  

  
文档来源:51CTO技术博客https://blog.51cto.com/u_11812862/3017448
页: [1]
查看完整版本: 大学生必学练习题 - C 语言经典50例