七天入门C语言之第三天:题目训练
经过前两天的学习,我们已经基本掌握了一部分C语言的语法规则,今天,我们将以写题运用的视角来带领大家学会如何运用。
建议大家看完题目之后自己手敲出来再看解析,要学会独立思考。(为了便于大家理解,我在写本次的题目时尽量使用英文单词作为变量名称)
1.海伦公式计算三角形面积:请设计一个C语言程序,通过输入三角形的三条边,输出这个三角形对应的面积(如果三条边无法构成三角形,要输出“输入的三边长不能构成三角形”)
本题主要考察了较为简单的if结构和基础的浮点数运算。写这道题的时候,可以先思考一下,什么是海伦公式,如何判断三条边能否组成三角形
海伦公式:https://baike.baidu.com/item/%E6%B5%B7%E4%BC%A6%E5%85%AC%E5%BC%8F/106956
判断三角形:都为整数且两边之和大于第三边(两边之差小于第三边)
#include <stdio.h>
#include <math.h>
int main() {
double a, b, c;
printf("请输入三角形的三边长:\n");
printf("边a: ");
scanf("%lf", &a);
printf("边b: ");
scanf("%lf", &b);
printf("边c: ");
scanf("%lf", &c);
// 检查是否构成三角形
if (a + b > c && a + c > b && b + c > a) {
// 计算半周长
double s = (a + b + c) / 2;
// 使用海伦公式计算面积
double area = sqrt(s * (s - a) * (s - b) * (s - c));
printf("三角形的面积为: %lf\n", area);
}
else {
printf("输入的三边长不能构成三角形。\n");
}
return 0;
}
2.假设您是一家购物商城的程序员,您需要编写一个程序来计算客户的折扣和总费用。折扣规则如下:
- 如果客户购买的商品总额大于等于100美元,他们将获得10%的折扣。
- 如果客户购买的商品总额大于等于200美元,他们将获得20%的折扣。
- 如果客户购买的商品总额大于等于300美元,他们将获得30%的折扣。
请编写一个C程序,要求用户输入购买的商品总额,并根据上述规则计算折扣和最终费用,并输出结果。
分析这道题目,发现在不同的条件下获得的折扣(也就是计算方法不一样),这个时候我们就要用到多重的if结构,也可以称为if-else if-else结构
大体的逻辑实现并不困难,可以参考以下代码。
#include <stdio.h>
int main() {
double totalAmount;
double discount = 0.0;
printf("请输入购物总额(美元):");
scanf("%lf", &totalAmount);
if (totalAmount >= 100) {
discount = 0.10; // 10% 折扣
}
if (totalAmount >= 200) {
discount = 0.20; // 20% 折扣
}
if (totalAmount >= 300) {
discount = 0.30; // 30% 折扣
}
double discountedAmount = totalAmount - (totalAmount * discount);
printf("您的折扣为 %.0lf%%\n", discount * 100);
printf("您的最终费用为 $%.2lf\n", discountedAmount);
return 0;
}
3.字母转换:输入一个字符,如果它是大写字母,输出相应的小写字母;如果它是小写字母,输出相应的大写字母;否则,原样输出。不要改变与输入输出有关的语句。
对于这道题,我们要引入一个新的知识点,叫做字符对应的ASCII码
ASCII(American Standard Code for Information Interchange)码是一种将字符编码为整数的字符编码标准。ASCII 码使用7位二进制数(0或1)来表示128个不同的字符,包括控制字符(如换行符和制表符)以及可打印字符(如字母、数字和标点符号)。每个字符都分配了一个唯一的整数值。
以下是一些常见的ASCII字符及其对应的整数值:
- 数字0到9的ASCII码:48到57
- 大写字母A到Z的ASCII码:65到90
- 小写字母a到z的ASCII码:97到122 (小写字母的ASCII码更大)
- 空格的ASCII码:32
- 换行符的ASCII码:10
- 制表符的ASCII码:9
对于ASCII码的用处,在C语言之中,主要有以下几种:
1.用于大小写字母的转化:我们可以通过对一个已知的字母+或-32来得出对应的字母,例如:
char ch = 'A' + 32; //此时 ch 代表的字母就是A对应的小写字母 a,32就是对应大小写字母的差
2.存储数字:
首先,我们需要知道,char类型转化成int类型时,会默认按照char类型的ASCII码进行转化或者计算,因此,我们可以利用数字0到9的 ASCII码,来进行存储int类型的数字。
#include <stdio.h>
int main() {
char digitChar = '5'; // 存储数字字符'5'
// 将数字字符转换为整数
int digitInt = digitChar - '0';
printf("字符表示的数字:%c\n", digitChar);
printf("整数表示的数字:%d\n", digitInt);
return 0;
}
有了以上知识点的补充,这道题就会变的很简单
我们可以先利用ch存储输入的字符,接着+或-32进行转换(需要用到if结构判断大小写)
#include <stdio.h>
int main() {
char inputChar;
// 提示用户输入一个字符
printf("请输入一个字符:");
scanf(" %c", &inputChar); // 注意空格,以忽略前面的空白字符
// 检查字符的大小写并进行转换
if (inputChar >= 'A' && inputChar <= 'Z') {
// 输入是大写字母,转换为小写字母
char lowercaseChar = inputChar + ('a' - 'A');
printf("转换后的字符:%c\n", lowercaseChar);
} else if (inputChar >= 'a' && inputChar <= 'z') {
// 输入是小写字母,转换为大写字母
char uppercaseChar = inputChar - ('a' - 'A');
printf("转换后的字符:%c\n", uppercaseChar);
} else {
// 输入不是字母,原样输出
printf("输入的字符是:%c\n", inputChar);
}
return 0;
}
4.对输入的三个数排序:设计一个c语言程序,由键盘输入三个数字,将他们从大到小排序并输出。
这道题主要考察的有多个if结构的使用,以及交换操作的实现。
在编程语言之中,要想实现两个变量对应的值的交换,需要开辟一个临时变量来进行对一个数字暂存
int a = 5;
int b = 10;
int temp; //开辟临时变量 temp
temp = a; //将a的值存放在临时变量之中
a = b; //将b的值赋给a
b = temp;//将暂存的a的值赋给b
由此,我们可以实现:
#include <stdio.h>
int main() {
double num1, num2, num3;
// 提示用户输入三个数
printf("请输入三个数,以空格或换行符分隔:");
scanf("%lf %lf %lf", &num1, &num2, &num3);
// 排序三个数,从大到小
if (num1 < num2) {
double temp = num1;
num1 = num2;
num2 = temp;
}
if (num1 < num3) {
double temp = num1;
num1 = num3;
num3 = temp;
}
if (num2 < num3) {
double temp = num2;
num2 = num3;
num3 = temp;
}
// 输出排序后的结果
printf("从大到小排序的结果:%lf, %lf, %lf\n", num1, num2, num3);
return 0;
}
当然,如果使用逻辑运算符先找出最大值,再找出第二大的值,并在找到之后直接输出也可以实现,可以自己编程尝试。
5.用辗转相除法(即欧几里得算法)求两个正整数的最大公约数和最小公倍数。
求最大公约数和最小公倍数是学习所有编程语言前期都会经常见到的一个题目,这道题和我们的第一题比较相似,需要有一定的数学知识。
辗转相除法:辗转相除法的代数描述是这样的,假设我们有两个数字[12921,4234]。我们将两数中较大的那一个看作是被除数A,将较小的那一个看作是除数B,二者相除的商记作C,余数记作D。这样我们就可以得到一个等式:A = B×C + D。而辗转相除法的所要用到的原理则是:(A , B) = (B , D)。有了这个公式我们就可以进行计算了,最后算出答案是73。
详细的计算过程是这样的:
(12921,4234)=(4234,219)
(4234,219)=(219,73)
(73,0)
最后就可以得到73是最终的结果,也就是二者的最大公约数。
如果用程序语句来表达的话就是:循环执行rem=a%b; a=b;b=rem;若rem=0,a是最大公约数,程序结束;否则重新执行以上语句。
最小公倍数的求法:设b和b的最大公约数为Div,最小公倍数为Multi=a*b/Div
#include <stdio.h>
int main() {
int num1, num2;
int originalNum1, originalNum2;
printf("请输入两个正整数:");
scanf("%d %d", &num1, &num2);
// 保存原始输入值
originalNum1 = num1;
originalNum2 = num2;
if (num1 <= 0 || num2 <= 0) {
printf("请输入正整数。\n");
} else {
// 计算最大公约数
while (num2 != 0) {
int temp = num2;
num2 = num1 % num2;
num1 = temp;
}
int greatestCommonDivisor = num1;
// 计算最小公倍数
int leastCommonMultiple = (originalNum1 * originalNum2) / greatestCommonDivisor;
printf("最大公约数:%d\n", greatestCommonDivisor);
printf("最小公倍数:%d\n", leastCommonMultiple);
}
return 0;
}
以上的五道题,是对咱们第一天的学习内容做一个大概的实践练习,建议大家同时写咱们201的OJ题目进行循序渐进的提升。
6.设计一个程序,实现输入m确定数组numbers的长度,接下来由键盘输入m个数字作为数组numbers的元素,分别输出numbers之中奇数和偶数的个数。
实现这道题需要我们运用到第二天学习到的数组分配和遍历数组的操作,此外,我们还需要学到一个计数的方法,就是定义一个初始值为0的变量,每次遍历查询到相关的目标之后就可以进行自增的操作。而奇数偶数就非常简单了,可以通过mod2运算来判断。
#include <stdio.h>
int main() {
int m;
printf("请输入数组长度 m:");
scanf("%d", &m);
if (m <= 0) {
printf("数组长度必须为正整数。\n");
return 1; // 程序退出,返回错误代码
}
int numbers[m]; // 声明一个长度为m的数组
int oddCount = 0; // 奇数计数器
int evenCount = 0; // 偶数计数器
printf("请输入 %d 个数字作为数组元素:\n", m);
for (int i = 0; i < m; i++) {
scanf("%d", &numbers[i]);
if (numbers[i] % 2 == 0) {
evenCount++;
} else {
oddCount++;
}
}
printf("数组中奇数的个数:%d\n", oddCount);
printf("数组中偶数的个数:%d\n", evenCount);
return 0;
}
7.字符串的连接
对于这道题而言,最简单的办法就是使用昨天学习的strcat()函数
#include <stdio.h>
#include <string.h>
int main() {
char str1[100]; // 声明一个字符数组用于存储第一个字符串
char str2[100]; // 声明一个字符数组用于存储第二个字符串
printf("请输入第一个字符串:");
scanf("%s", str1);
printf("请输入第二个字符串:");
scanf("%s", str2);
// 使用 strcat 连接两个字符串
strcat(str1, str2);
printf("连接后的字符串:%s\n", str1);
return 0;
}
那,如果说,出题者不希望我们直接使用strcat()函数的话该怎么办?
因为,我们在昨天的学习之中得知,字符串的结尾是转义字符\0,所以,我们只需要在第一个字符串之中找到\0,然后将接下来的每一项都对应赋给字符串2的值
#include <stdio.h>
int main() {
char str1[100]; // 声明一个字符数组用于存储第一个字符串
char str2[100]; // 声明一个字符数组用于存储第二个字符串
printf("请输入第一个字符串:");
scanf("%s", str1);
printf("请输入第二个字符串:");
scanf("%s", str2);
// 寻找第一个字符串的末尾
int len1 = 0;
while (str1[len1] != '\0') {
len1++;
}
// 连接第二个字符串到第一个字符串的末尾
int i = 0;
while (str2[i] != '\0') {
str1[len1 + i] = str2[i];
i++;
}
// 确保连接后的字符串以 null 结尾
str1[len1 + i] = '\0';
printf("连接后的字符串:%s\n", str1);
return 0;
}
8.字符串元素的统计
由键盘输入任意一串字符串,将其存入一个字符数组,统计其中的大写字母、小写字母、数字以及其他字符的个数。
和第六题类似,是一个遍历+计数器的操作就可以实现
#include <stdio.h>
int main() {
char str[100]; // 声明一个字符数组用于存储输入的字符串
printf("请输入一个字符串:");
gets(str); //使用gets()函数读取字符串
int uppercaseCount = 0, lowercaseCount = 0, digitCount = 0, otherCount = 0;
for (int i = 0; str[i] != '\0'; i++) {
char ch = str[i];
if (ch >= 'A' && ch <= 'Z') {
uppercaseCount++;
} else if (ch >= 'a' && ch <= 'z') {
lowercaseCount++;
} else if (ch >= '0' && ch <= '9') {
digitCount++;
} else {
otherCount++;
}
}//遍历+计数器的操作
printf("大写字母的个数:%d\n", uppercaseCount);
printf("小写字母的个数:%d\n", lowercaseCount);
printf("数字的个数:%d\n", digitCount);
printf("其他字符的个数:%d\n", otherCount);
return 0;
}
9.数组的倒置
将具有10个元素的一维数组中的数据倒置输出。
这道题使用遍历+交换操作就可以实现,但是需要注意,只需要遍历到一半就可以了,否则会把刚交换成功的数字再换回去。
#include <stdio.h>
int main() {
int arr[10]; // 声明一个包含10个元素的整数数组
printf("请输入10个整数:\n");
// 从键盘输入10个整数并存储到数组中
for (int i = 0; i < 10; i++) {
scanf("%d", &arr[i]);
}
printf("倒置前的数组:");
for (int i = 0; i < 10; i++) {
printf("%d ", arr[i]);
}
// 倒置数组元素
for (int i = 0; i < 5; i++) {
int temp = arr[i];
arr[i] = arr[9 - i];
arr[9 - i] = temp;
}
printf("\n倒置后的数组:");
for (int i = 0; i < 10; i++) {
printf("%d ", arr[i]);
}
return 0;
}
10.二维数组(矩阵)的输入输出操作,其实和一维数组是一样的,利用循环,不过是使用循环套循环的方式,具体实现如下:
#include <stdio.h>
int main() {
int rows, cols;
printf("请输入矩阵的行数和列数:");
scanf("%d %d", &rows, &cols);
int matrix[rows][cols]; // 声明一个二维整数数组
// 输入矩阵元素
printf("请输入矩阵的元素:\n");
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
scanf("%d", &matrix[i][j]);
}
}
// 输出矩阵元素
printf("矩阵的内容:\n");
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
printf("%d\t", matrix[i][j]);
}
printf("\n"); // 换行来分隔每一行
}
return 0;
}
在这个示例中,程序首先要求用户输入矩阵的行数和列数,然后根据用户提供的行数和列数声明一个二维整数数组 matrix
。接下来,程序使用嵌套循环来遍历数组的每个元素,并使用scanf
来输入矩阵的元素。
然后,程序再次使用嵌套循环来遍历数组,并使用printf
来输出矩阵的内容。每一行的元素用制表符分隔,每行之间使用换行符分隔,以形成矩阵的视觉效果。
运行这个程序后,您可以输入矩阵的行数、列数和元素,然后它会将矩阵的内容输出到屏幕上。
这就是今天的学习内容,其实主要分为以下几个部分:
1.数学公式的程序实现
2.遍历思想
3.char与int的转换
4.计数器方法
5.循环的嵌套
6.多个if结构
一定要掌握!!!