大学 C 练习

大一《程序设计基础(C 语言)》课后作业。


第 1 章:概述

Q1.

编写一个 C 程序并上机调试运行,其功能是输出以下信息:

********************************
      This is a C program!
********************************
1
2
3
4
5
6
7
8
9
#include <stdio.h>

int main()
{
printf("********************************\n");
printf(" This is a C program!\n");
printf("********************************\n");
return 0;
}

Q2.

编写一个 C 程序并上机调试运行,其功能是从随意输入的两个数中找出较大的数并输出。

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>

int main()
{
float x, y;
float max;
printf("请输入两个数:\n");
scanf("%f %f", &x, &y);
max = x > y ? x : y;
printf("较大数 %f\n", max);
return 0;
}

第 4 章:顺序结构程序设计

Q1.

求 $ a * x ^ {2} + b * x + c = 0 $ 方程的根。a、b、c 由键盘输入,$ a \neq 0 $。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <complex.h>
#include <stdio.h>

int main()
{
float a, b, c;
float complex root;
float complex x1, x2;
printf("请输入一元二次方程的三个系数:\n");
scanf("%f %f %f", &a, &b, &c);
if (a == 0)
{
printf("A 不能为 0!\n");
}
else
{
root = csqrt(b * b - 4 * a * c);
if (creal(root) > 0)
{
x1 = (-b + root) / (2 * a);
x2 = (-b - root) / (2 * a);
printf("x1 = %f, x2 = %f\n", creal(x1), creal(x2));
}
else
{
if (cimag(root) == 0)
{
x1 = -b / (2 * a);
printf("x1 = x2 = %f\n", creal(x1));
}
else
{
x1 = (-b + root) / (2 * a);
x2 = (-b - root) / (2 * a);
printf("x1 = %f%+fi, x2 = %f%+fi\n", creal(x1), cimag(x1),
creal(x2), cimag(x2));
}
}
}
return 0;
}

Q2.

加密数据,加密规则为:将单词中的每个字母变成其后的第四个。请把“class”加密输出。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <ctype.h>
#include <stdio.h>
#include <string.h>

int main()
{
char ch[6] = "class";
for (int i = 0; i < strlen(ch); i++)
{
if (isalpha(ch[i]))
{
ch[i] += 4;
}
}
printf("加密后 %s\n", ch);
return 0;
}

Q3.

任意从键盘输入一个三位整数,要求正确地分离出它的个位、十位和百位数,并分别在屏幕上输出。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>

int main()
{
int num, result;
printf("请输入一个三位正整数:\n");
scanf("%d", &num);
if (100 <= num && num <= 999)
{
printf("个位 十位 百位\n");
for (int i = 0; i < 3; i++)
{
result = num % 10;
num /= 10;
printf("%d ", result);
}
printf("\n");
}
else
{
printf("输入错误!\n");
}
return 0;
}

Q4.

输入任意三个整数,求它们的和及平均值。

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>

int main()
{
int x, y, z;
float sum, ave;
printf("请输入三个整数:\n");
scanf("%d %d %d", &x, &y, &z);
sum = x + y + z;
ave = sum / 3;
printf("和 %f,平均 %f\n", sum, ave);
return 0;
}

Q5.

输入存款金额 money、存期 year 和年利率 rate,采用定期 1 年,到期本息自动转存方式,根据公式计算存款到期时的本息合计 sum(税前),输出时保留 2 位小数。$ sum = money * (1 + rate) ^ {year} $。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <math.h>
#include <stdio.h>

int main()
{
float money;
int year;
float rate;
float sum;
printf("请输入存款金额、存期和年利率:\n");
scanf("%f %d %f", &money, &year, &rate);
sum = money * pow(1 + rate, year);
printf("本息合计 %.2f\n", sum);
return 0;
}

Q6.

输入上底边长、下底边长和高,求梯形的面积。

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>

int main()
{
float a, b, h;
float area;
printf("请输入梯形的上底、下底和高:\n");
scanf("%f %f %f", &a, &b, &h);
area = (a + b) * h / 2;
printf("面积 %f\n", area);
return 0;
}

Q7.

编写程序由一个人的出生时间计算此人某年的年龄。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <stdio.h>
#include <time.h>

int main()
{
time_t today_t = time(NULL);
struct tm today = *localtime(&today_t);
int year, month, day;
int age;
printf("请输入出生年月日:\n");
scanf("%d %d %d", &year, &month, &day);
age = today.tm_year + 1900 - year;
if (today.tm_mon + 1 - month < 0)
{
age--;
}
else if (today.tm_mon + 1 - month == 0)
{
if (today.tm_mday - day < 0)
{
age--;
}
}
printf("年龄 %d\n", age);
return 0;
}

Q8.

用编程的形式打印学生入学的姓名、性别、年龄、学号和入学成绩。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>

int main()
{
char name[10] = "张三";
char sex[5] = "男";
int age = 20;
int num = 151110001;
float score = 100;
printf("%s 的个人信息:\n", name);
printf("性别 %s\n", sex);
printf("年龄 %d\n", age);
printf("学号 %d\n", num);
printf("成绩 %f\n", score);
return 0;
}

Q9.

输入一个华氏温度,要求输出摄氏温度。

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>

int main()
{
float temp_f, temp_c;
printf("请输入华氏温度:\n");
scanf("%f", &temp_f);
temp_c = (temp_f - 32) * 5 / 9;
printf("摄氏温度 %f\n", temp_c);
return 0;
}

第 5 章:选择结构程序设计

Q1.

已知邮件的邮费计算标准如下:当邮件重量小于 200 克时,邮费为每克 0.05 元;当邮件重量超过 200 克时,超过部分每克 0.03 元;请编程实现邮件的计费程序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>

int main()
{
float weight, money;
printf("请输入邮件的重量:\n");
scanf("%f", &weight);
if (weight <= 200)
{
money = weight * 0.05;
}
else
{
money = 200 * 0.05 + (weight - 200) * 0.03;
}
printf("邮费 %f\n", money);
return 0;
}

Q2.

通过键盘输入一个字符,判断该字符是数字字符、大写字母、小写字母、空格还是其他字符。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <ctype.h>
#include <stdio.h>

int main()
{
char ch;
printf("请输入一个字符:\n");
scanf("%c", &ch);
if (ch == ' ')
{
printf("空格\n");
}
else if (isdigit(ch))
{
printf("数字\n");
}
else if (isupper(ch))
{
printf("大写字母\n");
}
else if (islower(ch))
{
printf("小写字母\n");
}
else
{
printf("其他字符\n");
}
return 0;
}

Q3.

编写程序实现输入三角形的三条边,判别它们是否能形成三角形,若能,则判断是等边、等腰还是一般三角形。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdio.h>

int main()
{
float a, b, c;
printf("请输入三角形的三条边:\n");
scanf("%f %f %f", &a, &b, &c);
if (a + b > c && b + c > a && c + a > b)
{
if (a == b && b == c)
{
printf("等边三角形\n");
}
else if (a == b || b == c || c == a)
{
printf("等腰三角形\n");
}
else
{
printf("一般三角形\n");
}
}
else
{
printf("不是三角形!\n");
}
return 0;
}

Q4.

编程计算分段函数

$ \begin{equation} y = \begin{cases} e ^ {-x} & x > 0 \\ 1 & x = 0 \\ -e ^ {x} & x < 0 \end{cases} \end{equation} $

输入 x,打印出 y 值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <math.h>
#include <stdio.h>

int main()
{
float x, y;
printf("请输入 x:\n");
scanf("%f", &x);
if (x > 0)
{
y = exp(-x);
}
else if (x == 0)
{
y = 1;
}
else
{
y = -exp(x);
}
printf("y = %f\n", y);
return 0;
}

Q5.

给一个不多于 5 位的正整数,要求:

  1. 求出它是几位数;
  2. 分别输出每一位数字;
  3. 按逆序输出各位数字,例如原数为 321,应输出 123。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <stdio.h>
#include <string.h>

int main()
{
int num;
char digit[5];
int len;
printf("请输入一个正整数(1 - 9999):\n");
scanf("%d", &num);
if (1 <= num && num <= 9999)
{
for (int i = 0; num != 0; i++)
{
sprintf(&digit[i], "%d", num % 10);
num /= 10;
}
len = strlen(digit);
printf("位数 %d\n", len);
printf("每位数字 ");
for (int i = 0; i < len; i++)
{
printf("%c ", digit[len - 1 - i]);
}
printf("\n");
printf("逆序数字 ");
for (int i = 0; i < len; i++)
{
printf("%c ", digit[i]);
}
printf("\n");
}
else
{
printf("输入错误!\n");
}
return 0;
}

第 6 章:循环结构程序设计

Q1.

我国古代《张丘建算经》中有这样一道著名的百鸡问题:“鸡翁一,值钱五;鸡母一,值钱三;鸡雏三,值钱一。百钱买百鸡,问鸡翁、母、雏各几何?”其意为:公鸡每只 5 元,母鸡每只 3 元,小鸡 3 只 1 元。用 100 元买 100 只鸡,问公鸡、母鸡和小鸡各能买多少只。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>

int main()
{
int rooster, hen, chick;
for (rooster = 0; rooster <= 14; rooster++)
{
if ((100 - 7 * rooster) % 4 == 0)
{
hen = (100 - 7 * rooster) / 4;
chick = 100 - rooster - hen;
printf("公鸡 %d,母鸡 %d,小鸡 %d\n", rooster, hen, chick);
}
}
return 0;
}

Q2.

编程计算 $ 1! + 2! + 3! + 4! + \cdots + 10! $ 的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>

int main()
{
int pro = 1, sum = 0;
for (int x = 1; x <= 10; x++)
{
for (int y = 1; y <= x; y++)
{
pro *= y;
}
sum += pro;
pro = 1;
}
printf("1! + 2! + ... + 10! = %d\n", sum);
return 0;
}

Q3.

输入一个整数 m,编写程序判断它是否是素数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <math.h>
#include <stdio.h>

int main()
{
int m, x;
printf("请输入一个正整数(> 1):\n");
scanf("%d", &m);
if (m >= 2)
{
if (m == 2)
{
printf("素数\n");
return 0;
}
for (x = 2; x * x < m; x++)
{
if (m % x == 0)
{
break;
}
}
if (m % x != 0)
{
printf("素数\n");
}
else
{
printf("非素数\n");
}
}
else
{
printf("输入错误!\n");
}
return 0;
}

Q4.

输入一行字符,分别统计出其中英文字母、空格、数字和其他字符的个数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <ctype.h>
#include <stdio.h>

int main()
{
char ch;
int space = 0, number = 0, letter = 0, other = 0;
printf("请输入一行字符:\n");
while ((ch = getchar()) != '\n')
{
if (ch == ' ')
{
space++;
}
else if (isdigit(ch))
{
number++;
}
else if (isalpha(ch))
{
letter++;
}
else
{
other++;
}
}
printf("字母 %d,数字 %d,空格 %d,其他 %d\n", letter, number, space,
other);
return 0;
}

Q5.

猴子吃桃问题。猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个。第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第 10 天早上想再吃时,就只剩下一个桃子了。求第一天共摘了多少个桃子。

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>

int main()
{
int total = 1;
for (int day = 9; day >= 1; day--)
{
total += 1;
total *= 2;
}
printf("桃子 %d\n", total);
return 0;
}

第 7 章:数组

Q1.

将一个数组中的值按逆序重新存放。例如,原来顺序 8、6、5、4、1,要求改为 1、4、5、6、8。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>

#define MAX 5

int main()
{
int num[MAX] = {8, 6, 5, 4, 1}, temp;
for (int i = 0; i < MAX / 2; i++)
{
temp = num[i];
num[i] = num[MAX - 1 - i];
num[MAX - 1 - i] = temp;
}
printf("逆序 ");
for (int i = 0; i < MAX; i++)
{
printf("%d ", num[i]);
}
printf("\n");
return 0;
}

Q2.

找出一个二维数组中的鞍点,即该位置上的元素在该行上最大,在该列上最小。也可能没有鞍点。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <stdio.h>

#define M 10
#define N 10

int main()
{
int x, y;
int num[M][N];
int max = 0, num_m = 0, flag = 0, flag_m = 0;
printf("请输入行数(<= 10):\n");
scanf("%d", &x);
printf("请输入列数(<= 10):\n");
scanf("%d", &y);
for (int i = 0; i < x; i++)
{
printf("第 %d 行:\n", i + 1);
for (int j = 0; j < y; j++)
{
scanf("%d", &num[i][j]);
}
}
for (int i = 0; i < x; i++)
{
max = num[i][0];
for (int j = 0; j < y; j++)
{
if (max < num[i][j])
{
max = num[i][j];
num_m = j;
}
}
for (int k = 0; k < x; k++)
{
if (max <= num[k][num_m])
{
flag = 1;
}
else
{
flag = 0;
break;
}
}
if (flag == 1)
{
flag_m = 1;
printf("鞍点 %d\n", max);
}
}
if (flag_m == 0)
{
printf("没有鞍点!\n");
}
return 0;
}

Q3.

有一行电文,已按照以下的规则译成密码:

A → Z    a → z
B → Y    b → y
C → X    c → x
……

即第一个字母变成第 26 个字母,第 i 个字母变成第 26 - i + 1 个字母,非字母字符不变,要求编程序将密码翻译回原文,并输出密码和原文。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <ctype.h>
#include <stdio.h>
#include <string.h>

#define MAX 100

int main()
{
char ch_e[MAX], ch_d[MAX];
printf("请输入一行密文:\n");
fgets(ch_e, sizeof(ch_e), stdin);
if (ch_e[strlen(ch_e) - 1] == '\n')
{
ch_e[strlen(ch_e) - 1] = '\0';
}
for (int i = 0; i < strlen(ch_e); i++)
{
if (isupper(ch_e[i]))
{
ch_d[i] = 'Z' - ch_e[i] + 'A';
}
else if (islower(ch_e[i]))
{
ch_d[i] = 'z' - ch_e[i] + 'a';
}
else
{
ch_d[i] = ch_e[i];
}
}
printf("密文 %s\n", ch_e);
printf("原文 %s\n", ch_d);
return 0;
}

Q4.

编写一个程序,将两个字符串 s1、s2 比较,若 s1 > s2,则输出一个正数,若 s1 = s2,则输出 0,若 s1 < s2,输出一个负数,不用 strcpy 函数,两个字符串用 gets 函数读入,输出的正数或负数的绝对值应是相比较的两个字符串相应字符的 ASCII 码的差值。

  1. “A”与“C”相比,由于“A”<“C”,应输出负数,同时由于“A”与“C”的 ASCII 码差值为 2,因此应输出“-2”
  2. “And”和“Aid”比较,根据第二个字符比较结果,“n”比“i”大 5,因此应该输出“5”。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>

#define MAX 100

int main()
{
char s1[MAX], s2[MAX];
int diff = 0;
printf("请输入第一行字符:\n");
gets(s1);
printf("请输入第二行字符:\n");
gets(s2);
for (int i = 0; s1[i] != '\0' || s2[i] != '\0'; i++)
{
diff = s1[i] - s2[i];
if (diff != 0)
{
break;
}
}
printf("差值 %d\n", diff);
return 0;
}

Q5.

有一篇文章,共有 3 行文字,每行有 80 个字符。要求分别统计出其中英文大写字母、小写字母、空格以及其他字符的个数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <ctype.h>
#include <stdio.h>
#include <string.h>

#define M 3
#define N 81

int main()
{
char ch[M][N];
int space = 0, upper = 0, lower = 0, other = 0;
printf("请输入三行字符(每行 <= 80):\n");
for (int i = 0; i < M; i++)
{
fgets(ch[i], sizeof(ch[i]), stdin);
if (ch[i][strlen(ch[i]) - 1] == '\n')
{
ch[i][strlen(ch[i]) - 1] = '\0';
}
for (int j = 0; j < strlen(ch[i]); j++)
{
if (ch[i][j] == ' ')
{
space++;
}
else if (isupper(ch[i][j]))
{
upper++;
}
else if (islower(ch[i][j]))
{
lower++;
}
else
{
other++;
}
}
}
printf("空格 %d,大写字母 %d,小写字母 %d,其他字符 %d\n", space, upper,
lower, other);
return 0;
}

Q6.

一个学习小组有 5 个人,每个人有三门课的考试成绩。求全组分科的平均成绩和各科总平均成绩,成绩用 int。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>

#define M 3
#define N 6

int main()
{
int score[M][N] = {0}, ave = 0;
for (int i = 0; i < M; i++)
{
printf("请输入第 %d 科的五人的成绩:\n", i + 1);
for (int j = 0; j < N - 1; j++)
{
scanf("%d", &score[i][j]);
score[i][N - 1] += score[i][j];
}
ave += score[i][N - 1];
score[i][N - 1] /= N - 1;
printf("第 %d 科的平均成绩 %d\n", i + 1, score[i][N - 1]);
}
ave /= M * (N - 1);
printf("总平均成绩 %d\n", ave);
return 0;
}

Q7.

用“*”输出一个菱形。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>

#define M 5

int main()
{
char diamond[M][M] = {{' ', ' ', '*'},
{' ', '*', ' ', '*'},
{'*', ' ', ' ', ' ', '*'},
{' ', '*', ' ', '*'},
{' ', ' ', '*'}};
for (int i = 0; i < M; i++)
{
for (int j = 0; j < M; j++)
{
printf("%c", diamond[i][j]);
}
printf("\n");
}
return 0;
}

Q8.

从键盘输入若干个整数,其值在 0 至 4 范围内,用 -1 作为输入结束的标志。统计输入各整数的个数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>

#define MAX 5

int main()
{
int num, count[MAX] = {0};
printf("请输入一行整数(0 - 4,-1 结束):\n");
do
{
scanf("%d", &num);
if (0 <= num && num <= 4)
{
count[num]++;
}
} while (num != -1);
for (int i = 0; i < MAX; i++)
{
printf("%d:%d\n", i, count[i]);
}
return 0;
}

第 8 章:函数

Q1.

编写一个函数,函数的功能是输出一个 200 以内能被 3 整除且个位数为 6 的所有整数,返回这些函数的个数。同时编写主函数调用该函数进行验证。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>

void fun()
{
int count;
for (int i = 6; i < 200; i += 10)
{
if (i % 3 == 0)
{
count++;
printf("%d ", i);
}
}
printf("\n");
printf("个数 %d\n", count);
}

int main()
{
fun();
return 0;
}

Q2.

编写程序,用选择法对数组中 10 个整数按由小到大排序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <stdio.h>

#define MAX 10

void sort(int num[], int len)
{
int min, temp;
for (int i = 0; i < len - 1; i++)
{
min = i;
for (int j = i + 1; j < len; j++)
{
if (num[min] > num[j])
{
min = j;
}
}
temp = num[min];
num[min] = num[i];
num[i] = temp;
}
}

int main()
{
int num[MAX];
printf("请输入十个整数:\n");
for (int i = 0; i < MAX; i++)
{
scanf("%d", &num[i]);
}
sort(num, MAX);
printf("排序后 ");
for (int i = 0; i < MAX; i++)
{
printf("%d ", num[i]);
}
printf("\n");
return 0;
}

Q3.

编写函数 double round(double h),函数的功能是对变量 h 中的值保留两位小数,并对第三位进行四舍五入(规定 h 中的值为正数)。

  1. h 值为 8.32433,则函数返回 8.32;
  2. h 值为 8.32533,则函数返回 8.33。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>

double round(double h)
{
int t;
h *= 1000;
t = (h + 5) / 10;
return (double)t / 100;
}

int main()
{
double h;
printf("请输入一个正数:\n");
scanf("%lf", &h);
printf("%f ≈ %.2lf\n", h, round(h));
return 0;
}

Q4.

编写一个函数,函数的功能是对长度为 7 个字符的字符串,除首、尾字符外,将其余 5 个字符按降序排列。例如,原来的字符串为 CEAedca,排序后输出为 CedcEAa。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <stdio.h>
#include <string.h>

#define MAX 10

void sort(char ch[], int num)
{
int t;
for (int i = 1; i < num - 1; i++)
{
for (int j = i + 1; j < num - 1; j++)
{
if (ch[j] > ch[i])
{
t = ch[j];
ch[j] = ch[i];
ch[i] = t;
}
}
}
}

int main()
{
char ch[MAX];
printf("请输入一行字符(个数 <= 7):\n");
scanf("%s", ch);
if (strlen(ch) <= 7)
{
sort(ch, strlen(ch));
printf("排序后 %s\n", ch);
}
else
{
printf("输入错误!\n");
}
return 0;
}

Q5.

编写一个函数,由实参传来一个字符串和一个字符,统计此字符串中该字符出现的次数,在主函数中输入字符串和字符以及输出字符在字符串中的个数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>

#define MAX 100

int count(char *str, char ch)
{
int num = 0;
while (*str != '\0')
{
if (*str++ == ch)
{
num++;
}
}
return num;
}

int main()
{
char str[MAX], ch;
printf("请输入一行字符和要统计的一个字符:\n");
scanf("%s %c", str, &ch);
printf("次数 %d\n", count(str, ch));
return 0;
}

Q6.

用递归算法编写函数 sum,求 1 到 n 的累加和,同时编写主函数调用 sum 进行验证。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>

int sum(int num)
{
int total = 0;
if (num == 1)
{
total = 1;
}
else
{
total = num + sum(num - 1);
}
return total;
}

int main()
{
int n;
printf("请输入 n:\n");
scanf("%d", &n);
printf("累加 %d\n", sum(n));
return 0;
}

Q7.

一个人赶着鸭子去每个村庄卖,每经过一个村子卖去所赶鸭子的一半又一只。这样他经过了七个村子后还剩两只鸭子,问他出发时共赶了多少只鸭子?请用递归法实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>

int duck(int num)
{
int total = 0;
if (num == 7)
{
total = 2;
}
else
{
total = (duck(num + 1) + 1) * 2;
}
return total;
}

int main()
{
printf("鸭子 %d\n", duck(0));
return 0;
}

Q8.

从键盘输入一个班(全班最多不超过 30 人)学生某门课的成绩,当输入成绩为负值时,输入结束,分别用几个函数实现下列功能:

  1. 统计不及格人数并打印不及格学生名单;
  2. 统计成绩在全班平均分以及平均分之上的学生人数,并打印这些学生的名单;
  3. 统计各分数段的学生人数及所占的百分比。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include <stdio.h>

#define MAX 30

int inputScore(int num[], float score[])
{
int i;
for (i = 0; i < MAX; i++)
{
scanf("%d %f", &num[i], &score[i]);
if (score[i] < 0 || 100 < score[i])
{
return i;
}
}
return i;
}

float getAve(float score[], int count)
{
float sum = 0;
for (int i = 0; i < count; i++)
{
sum += score[i];
}
return sum / count;
}

void getDetail(float score[], int count, float ave, int stu[])
{
for (int i = 0, j = 0; i < count; i++)
{
if (score[i] >= ave)
{
stu[6]++;
}
if (score[i] < 60)
{
j = 0;
}
else
{
j = ((int)score[i] - 50) / 10;
}
stu[j]++;
}
}

void getPer(int count, int stu[], float per[])
{
for (int i = 0; i < 6; i++)
{
per[i] = (float)stu[i] / (float)count * 100;
}
}

void printFail(int num[], float score[], int count)
{
for (int i = 0; i < count; i++)
{
if (score[i] < 60)
{
printf("%d %.2f\n", num[i], score[i]);
}
}
}

void printAve(int num[], float score[], int count, float ave)
{
for (int i = 0; i < count; i++)
{
if (score[i] >= ave)
{
printf("%d %.2f\n", num[i], score[i]);
}
}
}

int main()
{
int choice;
int num[MAX];
float score[MAX];
int count;
float ave;
int stu[7] = {0};
float per[6];
while (1)
{
printf("0 退出\t1 录入\n");
printf("2 不及格\t3 平均分\n");
printf("4 分数段\n");
scanf("%d", &choice);
switch (choice)
{
case 0:
return 0;
case 1:
printf("请输入三十个学号和成绩(成绩 < 0 或 > 100 结束):\n");
count = inputScore(num, score);
ave = getAve(score, count);
getDetail(score, count, ave, stu);
getPer(count, stu, per);
break;
case 2:
if (stu[0] != 0)
{
printf("不及格 %d:\n", stu[0]);
printf("学号 成绩\n");
printFail(num, score, count);
}
else
{
printf("全部及格!\n");
}
break;
case 3:
printf("平均分 %.2f,人数 %d:\n", ave, stu[6]);
printf("学号 成绩\n");
printAve(num, score, count, ave);
break;
case 4:
printf("总人数 %d:\n", count);
printf("分数段 人数 百分比\n");
printf("[0, 60) %d %.2f%%\n", stu[0], per[0]);
printf("[60, 70) %d %.2f%%\n", stu[1], per[1]);
printf("[70, 80) %d %.2f%%\n", stu[2], per[2]);
printf("[80, 90) %d %.2f%%\n", stu[3], per[3]);
printf("[90, 100) %d %.2f%%\n", stu[4], per[4]);
printf("[100] %d %.2f%%\n", stu[5], per[5]);
break;
default:
return 1;
}
}
return 0;
}

第 9 章:指针

Q1.

编写一个程序,在已知两个从小到大有序的数表中寻找都出现的第一个元素的指针。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <stdio.h>

int *search(int x[], int y[], int x_l, int y_l)
{
for (int *i = x; i < x + x_l; i++)
{
for (int *j = y; j < y + y_l; j++)
{
if (*i == *j)
{
return i;
}
}
}
return NULL;
}

int main()
{
int x[] = {1, 3, 5, 7, 9, 10}, y[] = {2, 4, 6, 8, 10};
int x_l = sizeof(x) / sizeof(x[0]), y_l = sizeof(y) / sizeof(y[0]);
int *sea = search(x, y, x_l, y_l);
if (sea)
{
printf("相同 %d\n", *sea);
}
else
{
printf("没有相同!\n");
}
return 0;
}

Q2.

输入一个 $ 2 * 3 $ 的整数矩阵和一个 $ 3 * 4 $ 的整数矩阵,用指针数组实现这两个矩阵的相乘。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <stdio.h>

int main()
{
int x[2][3], y[3][4], z[2][4] = {0};
printf("请输入整数矩阵 x[2][3] 的值:\n");
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
scanf("%d", &x[i][j]);
}
}
printf("请输入整数矩阵 y[3][4] 的值:\n");
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
scanf("%d", &y[i][j]);
}
}
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 4; j++)
{
for (int k = 0; k < 3; k++)
{
z[i][j] += x[i][k] * y[k][j];
}
}
}
printf("x[2][3] * y[3][4] =\n");
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 4; j++)
{
printf("%d ", z[i][j]);
}
printf("\n");
}
return 0;
}

Q3.

用一维数组和指针变量作函数参数,编程打印某班一门课成绩的最高分和学号。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <stdio.h>

#define MAX 100

int inputScore(int num[], float score[])
{
int i;
for (i = 0; i < MAX; i++)
{
scanf("%d %f", &num[i], &score[i]);
if (score[i] < 0 || 100 < score[i])
{
return i;
}
}
return i;
}

void findMax(int num[], float score[], int count, int *maxNum, float *maxScore)
{
*maxNum = num[0];
*maxScore = score[0];
for (int i = 0; i < count; i++)
{
if (score[i] > *maxScore)
{
*maxNum = num[i];
*maxScore = score[i];
}
}
}

int main()
{
int num[MAX], maxNum;
float score[MAX], maxScore;
int count;
printf("请输入不多于一百个学号和成绩(成绩 < 0 或 > 100 结束):\n");
count = inputScore(num, score);
findMax(num, score, count, &maxNum, &maxScore);
printf("最高分学号 %d,成绩 %.2f\n", maxNum, maxScore);
return 0;
}

Q4.

编写一个程序,输入 10 个字符串,对其进行排序(由小到大)后输出。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <stdio.h>
#include <string.h>

#define M 10
#define N 11

void sort(char ch[M][N])
{
char temp[N];
for (int i = 0; i < M; i++)
{
for (int j = 0; j < M - 1; j++)
{
if (strcmp(ch[j], ch[j + 1]) > 0)
{
strcpy(temp, ch[j]);
strcpy(ch[j], ch[j + 1]);
strcpy(ch[j + 1], temp);
}
}
}
}

int main()
{
char ch[M][N], (*temp)[N] = ch;
printf("请输入十行字符(每行 <= 10):\n");
for (int i = 0; i < M; i++)
{
scanf("%s", ch[i]);
}
sort(temp);
printf("排序后:\n");
for (int i = 0; i < M; i++)
{
printf("%s\n", ch[i]);
}
return 0;
}

Q5.

用指针实现模拟彩票的程序,在 1 ~ 45 的 45 个数中随机产生 6 个数字与用户输入的数字进行比较,输出它们相同的数字个数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define MAX 7

int main()
{
int num[MAX];
int count = 0;
int *temp = &num[0];
srand(time(NULL));
printf("请输入六个正整数(1 - 45):\n");
for (int i = 1; i < MAX; i++)
{
scanf("%d", &num[i]);
*temp = rand() % 45 + 1;
if (num[i] == *temp)
{
count++;
}
}
printf("猜中次数 %d\n", count);
return 0;
}

Q6.

输入一个字符串,内有数字和非数字字符。例如:a123x456 1860 212yz789。将其中连续的数字作为一个整数,依次存放到一维数组 a 中,例如 123 放在 a[0],456 放在 a[1]……依次类推,请统计共有多少个整数,并输出这些整数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX 100

int main()
{
char str[MAX];
int num[MAX / 2];
char *ch = str, *ch_t;
int count = 0;
printf("请输入一行字符(< 100):\n");
fgets(str, sizeof(str), stdin);
if (str[strlen(str) - 1] == '\n')
{
str[strlen(str) - 1] = '\0';
}
while (*ch != '\0')
{
if (isdigit(*ch))
{
ch_t = ch;
while (isdigit(*ch))
{
ch++;
}
*ch = '\0';
num[count++] = atoi(ch_t);
}
ch++;
}
printf("数字个数 %d:\n", count);
for (int i = 0; i < count; i++)
{
printf("%d ", num[i]);
}
printf("\n");
return 0;
}

Q7.

编写程序设计一个“万年历”,键盘输入任意年,输出该年的所有月份日期,对应的星期;第一行显示星期(从周日到周六),第二行开始显示日期从 1 号开始,并按照其是周几实际情况与上面的星期数垂直对齐(注意闰年情况)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <stdio.h>

int rule(int year, int month)
{
if (month == 2)
{
if (year % 4 != 0 || (year % 100 == 0 && year % 400 != 0))
{
return 28;
}
else
{
return 29;
}
}
else if (month == 4 || month == 6 || month == 9 || month == 11)
{
return 30;
}
else
{
return 31;
}
}

int main()
{
char *month[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
char *week[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
int year, days;
int w, c, y, d;
printf("请输入年份(1900 - 2100):\n");
scanf("%d", &year);
if (1900 <= year && year <= 2100)
{
c = (year - 1) / 100;
y = (year - 1) % 100;
w = (y + y / 4 + c / 4 - 2 * c + 36) % 7;
for (int i = 0; i < 12; i++)
{
days = rule(year, i + 1);
printf("%s\n", *(month + i));
for (int j = 0; j < 7; j++)
{
printf("%4s", *(week + j));
}
printf("\n");
for (int k = 0; k < w; k++)
{
printf(" ");
}
for (d = 1; d <= 31; d++)
{
printf("%4d", d);
if (days == d)
{
break;
}
if ((w + d) % 7 == 0)
{
printf("\n");
}
}
w = (w + d) % 7;
printf("\n\n");
}
}
else
{
printf("输入错误!\n");
}
return 0;
}

Q8.

编写替换字符的函数 replace(char *str, char *fstr, char *rstr),将 str 所指字符串中凡是与 fstr 字符串相同的字符替换成 rstr(rstr 与 fstr 字符长度不一定相同);从主函数中输入原始字符串、查找字符串和替换字符串,调用函数得到结果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <stdio.h>
#include <string.h>

#define MAX 100
#define MIN 20

void replace(char *str, char *fstr, char *rstr)
{
char temp[MAX] = "";
for (int i = 0, k = 0; i < strlen(str);)
{
if (*(str + i) == *fstr)
{
for (int j = 0; *(rstr + j) != '\0'; j++)
{
*(temp + k) = *(rstr + j);
k++;
}
i += strlen(fstr);
}
else
{
*(temp + k) = *(str + i);
k++;
i++;
}
}
strcpy(str, temp);
}

int main()
{
char str[MAX], fstr[MIN], rstr[MIN];
printf("请输入一行字符:\n");
fgets(str, sizeof(str), stdin);
if (str[strlen(str) - 1] == '\n')
{
str[strlen(str) - 1] = '\0';
}
printf("请输入要替换的字符:\n");
fgets(fstr, sizeof(fstr), stdin);
if (fstr[strlen(fstr) - 1] == '\n')
{
fstr[strlen(fstr) - 1] = '\0';
}
printf("请输入替换后的字符:\n");
fgets(rstr, sizeof(rstr), stdin);
if (rstr[strlen(rstr) - 1] == '\n')
{
rstr[strlen(rstr) - 1] = '\0';
}
replace(str, fstr, rstr);
printf("%s\n", str);
return 0;
}

第 10 章:结构体、共用体和枚举类型

Q1.

利用结构体类型编写一个程序,根据输入的日期(包括年、月、日),计算出该天在本年中是第几天。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <stdio.h>

typedef struct
{
int year;
int month;
int day;
} DATE;

int rule(int year, int month)
{
if (month == 2)
{
if (year % 4 != 0 || (year % 100 == 0 && year % 400 != 0))
{
return 28;
}
else
{
return 29;
}
}
else if (month == 4 || month == 6 || month == 9 || month == 11)
{
return 30;
}
else
{
return 31;
}
}

int main()
{
DATE date;
int days = 0;
printf("请输入年月日:\n");
scanf("%d %d %d", &date.year, &date.month, &date.day);
for (int i = 1; i < date.month; i++)
{
days += rule(date.year, i);
}
days += date.day;
printf("该年第 %d 天\n", days);
return 0;
}

Q2.

编写程序,在屏幕上模拟显示一个数字式电子时钟。

1
2
3
4
5
6
7
8
9
#include <stdio.h>
#include <time.h>

int main()
{
time_t Time = time(NULL);
printf("%s", ctime(&Time));
return 0;
}

Q3.

编写程序,用于计算某个不同尺寸不同材料的长方体箱子的造价,要求输入其尺寸及其材料单位面积价格(例如每平方米多少钱),计算该箱子造价并输出相关信息。要求用指针作为函数参数来完成。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <stdio.h>

typedef struct
{
float length;
float width;
float height;
float price;
} BOX;

float calculate(BOX rectangle)
{
float area, money;
area = (rectangle.length * rectangle.width +
rectangle.width * rectangle.height +
rectangle.height * rectangle.length) *
2;
money = area * rectangle.price;
return money;
}

int main()
{
BOX rectangle;
float money;
printf("请输入长方体盒子的长、宽、高和单位面积价格:\n");
scanf("%f %f %f %f", &rectangle.length, &rectangle.width, &rectangle.height,
&rectangle.price);
money = calculate(rectangle);
printf("总价 %f\n", money);
return 0;
}

Q4.

编写程序,计算某个班学生 C 语言课程的成绩并统计一些信息。为方便输出信息,假设有三个学生,小数位数字保留一位。具体实现功能如下:

  1. 学生数据包括学号(int),姓名(char),平时成绩(float),实验成绩(float),期末成绩(float)和总评成绩(float)共 6 项,现输入三个学生前 5 项数据;
  2. 根据公式“总评 = 平时成绩 * 10% + 实验成绩 * 30% + 期末成绩 * 60%”,计算学生的总评成绩;
  3. 输出学生成绩;
  4. 根据总评计算本课程的平均分(float),输出平均分及高于平均分的学生的信息;
  5. 按各分数段统计相应人数并输出,分数段为:0 ~ 59.9,60 ~ 69.9,70 ~ 79.9,80 ~ 89.9,90 分以上。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#include <stdio.h>

#define MAX 3

typedef struct
{
int num;
char name[20];
float peaScore;
float expScore;
float endScore;
float total;
} STU;

int inputScore(STU stu[])
{
int i;
for (i = 0; i < MAX; i++)
{
scanf("%d %s %f %f %f", &stu[i].num, stu[i].name, &stu[i].peaScore,
&stu[i].expScore, &stu[i].endScore);
stu[i].total = stu[i].peaScore * 0.1 + stu[i].expScore * 0.3 +
stu[i].endScore * 0.6;
if (stu[i].peaScore < 0 || 100 < stu[i].peaScore ||
stu[i].expScore < 0 || 100 < stu[i].expScore ||
stu[i].endScore < 0 || 100 < stu[i].endScore)
{
return i;
}
}
return i;
}

float getAve(STU stu[], int count)
{
float sum = 0;
for (int i = 0; i < count; i++)
{
sum += stu[i].total;
}
return sum / count;
}

void getDetail(STU stu[], int count, float ave, int people[])
{
for (int i = 0, j = 0; i < count; i++)
{
if (stu[i].total >= ave)
{
people[6]++;
}
if (stu[i].total < 60)
{
j = 0;
}
else
{
j = ((int)stu[i].total - 50) / 10;
}
people[j]++;
}
}

void getPer(int count, int people[], float per[])
{
for (int i = 0; i < 6; i++)
{
per[i] = (float)people[i] / (float)count * 100;
}
}

void printAll(STU stu[], int count)
{
for (int i = 0; i < count; i++)
{
printf("%d %s %.1f %.1f %.1f %.1f\n", stu[i].num, stu[i].name,
stu[i].peaScore, stu[i].expScore, stu[i].endScore, stu[i].total);
}
}

void printAve(STU stu[], int count, float ave)
{
for (int i = 0; i < count; i++)
{
if (stu[i].total >= ave)
{
printf("%d %s %.1f %.1f %.1f %.1f\n", stu[i].num, stu[i].name,
stu[i].peaScore, stu[i].expScore, stu[i].endScore,
stu[i].total);
}
}
}

int main()
{
STU stu[MAX];
int choice;
int count;
float ave;
int people[7] = {0};
float per[6];
while (1)
{
printf("1 录入\t2 输出\n");
printf("3 平均分\t4 分数段\n");
printf("0 退出\n");
scanf("%d", &choice);
switch (choice)
{
case 0:
return 0;
case 1:
printf("请输入三个学生的学号、姓名、平时、实验和期末成绩(成绩 < 0 "
"或 > 100 结束):\n");
count = inputScore(stu);
ave = getAve(stu, count);
getDetail(stu, count, ave, people);
getPer(count, people, per);
break;
case 2:
printf("学号 姓名 平时成绩 实验成绩 期末成绩 总评成绩\n");
printAll(stu, count);
break;
case 3:
printf("总评平均分 %.1f,人数 %d:\n", ave, people[6]);
printf("学号 姓名 平时成绩 实验成绩 期末成绩 总评成绩\n");
printAve(stu, count, ave);
break;
case 4:
printf("总人数 %d:\n", count);
printf("总评分数段 人数 百分比\n");
printf("[0, 60) %d %.1f%%\n", people[0], per[0]);
printf("[60, 70) %d %.1f%%\n", people[1], per[1]);
printf("[70, 80) %d %.1f%%\n", people[2], per[2]);
printf("[80, 90) %d %.1f%%\n", people[3], per[3]);
printf("[90, 100) %d %.1f%%\n", people[4], per[4]);
printf("[100] %d %.1f%%\n", people[5], per[5]);
break;
default:
return 1;
}
}
return 0;
}

Q5.

编写程序,用链表实现某个班学生成绩的管理,包括成绩表的建立、查找、插入、删除、输出五个基本操作。假设成绩表只含学号和成绩两项,当输入学号为 0 时,结束建立、查找、插入、删除各操作,各操作均用函数完成,内容要求如下:

  1. 建立单链表,完成成绩表的建立;
  2. 按学号查找该生信息;
  3. 插入一个结点;
  4. 删除一个结点;
  5. 输出链表内容;
  6. 在主函数中指定需要查找、插入和删除的学号。

其他扩展要求:

  1. 可在主函数中实现查找、插入、删除多个结点;
  2. 可在主函数中实现简易菜单操作。

Q6.

某服装厂的衣服清单如图所示。若衣服是本厂生产的,则“衣服来源”用本厂生产车间代码(int)表示,若衣服不是本厂生产的,则“衣服来源”用来源单位(char)填写,要求输入、输出衣服清单的数据(假设只有两类衣服)。

衣服编号 衣服名称 本厂生产 衣服来源
N001 CH-简竹 Y 5
N567 AU-flo N A-company
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <stdio.h>

#define MAX 2

typedef struct
{
char num[10];
char name[20];
char produce;
union
{
int no;
char unit[20];
} from;
} CLOTHES;

int main()
{
CLOTHES clo[MAX];
printf("请输入衣服清单:\n");
for (int i = 0; i < MAX; i++)
{
scanf("%s %s %c", clo[i].num, clo[i].name, &clo[i].produce);
if (clo[i].produce == 'Y' || clo[i].produce == 'y')
{
scanf("%d", &clo[i].from.no);
}
else if (clo[i].produce == 'N' || clo[i].produce == 'n')
{
scanf("%s", clo[i].from.unit);
}
}
printf("衣服编号 衣服名称 本厂生产 衣服来源\n");
for (int i = 0; i < MAX; i++)
{
printf("%s %s %c ", clo[i].num, clo[i].name, clo[i].produce);
if (clo[i].produce == 'Y' || clo[i].produce == 'y')
{
printf("%d\n", clo[i].from.no);
}
else if (clo[i].produce == 'N' || clo[i].produce == 'n')
{
printf("%s\n", clo[i].from.unit);
}
}
return 0;
}

Q7.

定义一个枚举类型 cattle(牛),其有三个枚举值:bull(公牛)、cow(奶牛)、calf(牛犊),定义一个枚举变量,通过循环分别输出枚举值对应的是什么牛。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <stdio.h>

#define MAX 100

enum cattle
{
bull,
cow,
calf,
};

int main()
{
for (int i = 0; i < MAX; i++)
{
switch (i % 3)
{
case bull:
printf("序号 %d 是 bull\n", i);
break;
case cow:
printf("序号 %d 是 cow\n", i);
break;
case calf:
printf("序号 %d 是 calf\n", i);
break;
}
}
return 0;
}

第 11 章:位运算

Q1.

编写程序,统计一个 32 位整数 n 的二进制形式中 1 的个数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>

int main()
{
int n;
int count = 0;
printf("请输入 n:\n");
scanf("%d", &n);
while (n != 0)
{
n &= n - 1;
count++;
}
printf("1:%d\n", count);
return 0;
}

Q2.

编写程序,检查所用的计算机系统的 C 编译系统在执行右移时是按照逻辑右移的原则还是算术右移的原则?如果是逻辑右移,请编一函数实现算术右移,如果是算术右移,请编一函数实现逻辑右移。

Q3.

编写函数 getbits,功能:从一个 16 位的单元中取出以 n1 开始至 n2 结束的某几位,起始位和结束位都从左向右计算。同时编写主函数调用 getbits 进行验证。


第 12 章:文件

Q1.

编程序,统计一个文本文件的行数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <stdio.h>
#include <string.h>

#define MAX 100

int main()
{
char fn[MAX];
FILE *fp;
int count = 0;
printf("请输入文件路径:\n");
fgets(fn, sizeof(fn), stdin);
if (fn[strlen(fn) - 1] == '\n')
{
fn[strlen(fn) - 1] = '\0';
}
fp = fopen(fn, "r+");
if (fp)
{
while (!feof(fp))
{
if (fgetc(fp) == '\n')
{
count++;
}
}
printf("行数 %d\n", count + 1);
}
else
{
printf("打开失败!\n");
}
fclose(fp);
return 0;
}

Q2.

在一个已建立的 string.txt 文件末尾追加一个字符串。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>

#define MAX 100

int main()
{
char ch[MAX];
FILE *fp = fopen("string.txt", "a+");
if (fp)
{
printf("请输入一行字符:\n");
fgets(ch, sizeof(ch), stdin);
fputs(ch, fp);
printf("输出成功!\n");
}
else
{
printf("打开失败!\n");
}
fclose(fp);
return 0;
}

Q3.

编程序,查找指定的文本文件中某个单词出现的行号及该行的内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <stdio.h>
#include <string.h>

#define MAX 100

int main()
{
char fn[MAX];
FILE *fp;
int line = 0;
char ch[MAX];
char sea[MAX];
printf("请输入文件路径:\n");
fgets(fn, sizeof(fn), stdin);
if (fn[strlen(fn) - 1] == '\n')
{
fn[strlen(fn) - 1] = '\0';
}
fp = fopen(fn, "r+");
if (fp)
{
printf("请输入要查找的字符串:\n");
fgets(sea, sizeof(sea), stdin);
if (sea[strlen(sea) - 1] == '\n')
{
sea[strlen(sea) - 1] = '\0';
}
while (!feof(fp))
{
fgets(ch, sizeof(ch), fp);
line++;
if (strstr(ch, sea))
{
printf("第 %d 行:%s", line, ch);
}
}
}
else
{
printf("打开失败!\n");
}
fclose(fp);
return 0;
}

Q4.

从键盘上输入一个字符串,把该字符串中的小写字母转换为大写字母,输出到文件 test.txt 中,然后从该文件读出字符串并显示出来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <ctype.h>
#include <stdio.h>
#include <string.h>

#define MAX 100

int main()
{
char ch[MAX];
FILE *fp = fopen("test.txt", "w+");
printf("请输入一行字符:\n");
fgets(ch, sizeof(ch), stdin);
if (ch[strlen(ch) - 1] == '\n')
{
ch[strlen(ch) - 1] = '\0';
}
if (fp)
{
for (int i = 0; i < strlen(ch); i++)
{
if (islower(ch[i]))
{
ch[i] = toupper(ch[i]);
}
}
fputs(ch, fp);
printf("输出 ");
while (!feof(fp))
{
fgets(ch, sizeof(ch), fp);
printf("%s\n", ch);
}
}
else
{
printf("打开失败!\n");
}
fclose(fp);
return 0;
}

Q5.

从键盘输入一个文件名,然后输入一串字符(用 # 结束输入)存放到此文件中形成文本文件,并将字符的个数写到文件尾部。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <stdio.h>
#include <string.h>

#define MAX 100

int main()
{
char fn[MAX];
FILE *fp;
char ch;
int count = 0;
printf("请输入文件路径:\n");
fgets(fn, sizeof(fn), stdin);
if (fn[strlen(fn) - 1] == '\n')
{
fn[strlen(fn) - 1] = '\0';
}
fp = fopen(fn, "w+");
if (fp)
{
printf("请输入一行字符:\n");
while ((ch = getchar()) != '#')
{
fputc(ch, fp);
count++;
}
fprintf(fp, "%d", count);
printf("输出成功!\n");
}
else
{
printf("打开失败!\n");
}
fclose(fp);
return 0;
}

Q6.

编程序,将两个文本文件 teste.txt 和 testx.txt 连接成一个文件 testcat.txt 文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <stdio.h>

#define MAX 100

int main()
{
FILE *fp1 = fopen("teste.txt", "r+");
FILE *fp2 = fopen("testx.txt", "r+");
FILE *fp3 = fopen("testcat.txt", "w+");
char ch[MAX];
if (fp1 && fp2 && fp3)
{
while (!feof(fp1))
{
fgets(ch, sizeof(ch), fp1);
fputs(ch, fp3);
}
while (!feof(fp2))
{
fgets(ch, sizeof(ch), fp2);
fputs(ch, fp3);
}
printf("输出成功!\n");
}
else
{
printf("打开失败!\n");
}
fclose(fp1);
fclose(fp2);
fclose(fp3);
return 0;
}

Q7.

从键盘输入一个班的学生数据(包括学号、姓名和总分)写到磁盘文件 student.dat,然后从该文件中读出所有的数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <stdio.h>

typedef struct
{
int num;
char name[20];
float score;
} STU;

int main()
{
FILE *fp = fopen("student.dat", "w+");
STU stu;
char ch;
if (fp)
{
do
{
printf("请输入学号、姓名和总分:\n");
scanf("%d %s %f", &stu.num, stu.name, &stu.score);
fprintf(fp, "%d %s %f\n", stu.num, stu.name, stu.score);
printf("是否继续(Y / N):");
ch = getchar();
ch = getchar();
} while (ch == 'Y' || ch == 'y');
printf("输出成功!\n");
}
else
{
printf("打开失败!\n");
}
fclose(fp);
return 0;
}

Q8.

假设磁盘文件 s1.dat 中有 10 个整型数(78、15、23、6、48、68、82、35、8、19),编写程序把它按升序排序,并将结果输出到屏幕和 s2.dat 文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <stdio.h>

#define MAX 10

int main()
{
FILE *fp1 = fopen("s1.dat", "r+");
FILE *fp2 = fopen("s2.dat", "w+");
int num[MAX], min, temp;
if (fp1 && fp2)
{
for (int i = 0; i < MAX; i++)
{
fscanf(fp1, "%d", &num[i]);
}
for (int i = 0; i < MAX - 1; i++)
{
min = i;
for (int j = i + 1; j < MAX; j++)
{
if (num[min] > num[j])
{
min = j;
}
}
temp = num[min];
num[min] = num[i];
num[i] = temp;
}
printf("排序后 ");
for (int i = 0; i < MAX; i++)
{
printf("%d ", num[i]);
fprintf(fp2, "%d ", num[i]);
}
printf("\n");
printf("输出成功!\n");
}
else
{
printf("s1.dat 打开失败!\n");
}
fclose(fp1);
fclose(fp2);
return 0;
}

Q9.

假设教师文件 teacher.txt 记录了教师的姓名和课程名称,课程文件 course.txt 记录了课程名称和学分。编程序对比两个文件,将同一个教师的姓名、课程名称和学分输出到第三个文件 tcourse.txt 中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <stdio.h>

#define MAX 20

int main()
{
FILE *fp1 = fopen("teacher.txt", "r+");
FILE *fp2 = fopen("course.txt", "r+");
FILE *fp3 = fopen("tcourse.txt", "w+");
char teacher[MAX], course1[MAX], course2[MAX], score[MAX];
if (fp1 && fp2 && fp3)
{
while (!feof(fp1))
{
fscanf(fp1, "%s %s\n", teacher, course1);
fprintf(fp3, "%s %s ", teacher, course1);
do
{
fscanf(fp2, "%s %s\n", course2, score);
} while (strcmp(course1, course2) != 0);
fprintf(fp3, "%s\n", score);
rewind(fp2);
}
printf("输出成功!\n");
}
else
{
printf("打开失败!\n");
}
fclose(fp1);
fclose(fp2);
fclose(fp3);
return 0;
}

Q10.

统计一篇文章中大写字母的个数和文章中的句子数(句子的结束标志是句号后跟一个或多个空格)。设该程序的文件名为 sum.c。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <ctype.h>
#include <stdio.h>
#include <string.h>

#define MAX 100

int main()
{
char fn[MAX], ch;
FILE *fp;
int word, sentence;
printf("请输入文件路径:\n");
fgets(fn, sizeof(fn), stdin);
if (fn[strlen(fn) - 1] == '\n')
{
fn[strlen(fn) - 1] = '\0';
}
fp = fopen(fn, "r+");
if (fp)
{
while ((ch = fgetc(fp)) != EOF)
{
if (isupper(ch))
{
word++;
}
if (ch == ".")
{
sentence++;
}
}
printf("大写字母 %d\n", word);
printf("句子 %d\n", sentence);
}
else
{
printf("打开失败!\n");
}
return 0;
}