前言
本章我们带来几个经典得C语言练习题。
不要认为之前学过C语言,刷过这些题就不愿意再做题了。对待技术,我们永远要怀以一种空杯心态。
温故而知新,可以为师矣。
老师说,每道题都要尝试用不同得解法,去思考更多的思路,摸索最优解法,久之,技术便得到质的变化。
参考资料:C 库函数 – islower() | 菜鸟教程 (runoob.com)
题目
第一题
从键盘上输入一个字符串,将小写字母变成大写字母。
考点:
1 从键盘中输入一个字符串
常用方法
#include <stdio.h>
#define MAX_LENGTH 100
int main() {
char str[MAX_LENGTH];
printf("请输入一个字符串:");
scanf("%s", str);
printf("您输入的字符串是:%s\n", str);
return 0;
}
其他方法
#include <stdio.h>
#define MAX_LENGTH 100
int main() {
char str[MAX_LENGTH];
printf("请输入一个字符串:");
fgets(str, sizeof(str), stdin);
printf("您输入的字符串是:%s\n", str);
return 0;
}
解释:
fgets(str, sizeof(str), stdin) 是一个用于从标准输入(键盘)读取一行字符串的函数调用。
具体含义如下:
- str 是一个字符数组,用于存储读取的字符串。
- sizeof(str) 是用于获取字符数组 str 的大小,即它可以容纳的最大字符数。
- stdin 是一个标准输入流,表示从键盘读取输入。
- fgets() 函数会在读取到换行符(包括换行符)或达到指定的最大字符数(sizeof(str)-1)时停止读取。它会将读取到的字符串存储在 str 中,并在字符串末尾添加一个空字符 \0。
2 小写字母转大写字母
常用方法
将小写字母转换为大写字母的经常是通过 ASCII 码进行转换。在 ASCII 码表中,小写字母的值范围是 97 到 122,而对应的大写字母的值范围是 65 到 90。通过将小写字母的 ASCII 值减去 32,可以得到对应的大写字母的 ASCII 值。
例如
#include <stdio.h>
int main() {
char lowercase = 'a';
char uppercase = lowercase - 32;
printf("小写字母:%c\n", lowercase);
printf("对应的大写字母:%c\n", uppercase);
return 0;
}
其他方法
在C语言中,可以使用标准库函数toupper(int c)将小写字母转换为大写字母,使用islower(int c)检查给定的字符是否为小写字母。确保包含 ctype.h 头文件,它包含了 toupper 和islower函数的声明。
(1)toupper函数:
原型:int toupper(int c);
功能:将给定的字符转换为大写字母形式。
参数:c是一个int类型的整数,通常是一个字符。
返回值:转换后的大写字母,作为一个int类型的整数。
例如
#include <stdio.h>
#include <ctype.h>
int main() {
char lowercase = 'a';
char uppercase = toupper(lowercase);
printf("小写字母:%c\n", lowercase);
printf("对应的大写字母:%c\n", uppercase);
return 0;
}
(2)islower函数:
原型:int islower(int c);
功能:检查给定的字符是否为小写字母。
参数:c是一个int类型的整数,通常是一个字符。
返回值:如果给定字符为小写字母,则返回非零值(真);否则返回0(假)。
#include <stdio.h>
#include <ctype.h>
int main() {
char ch = 'a';
if (islower(ch)) {
printf("%c 是小写字母\n", ch);
} else {
printf("%c 不是小写字母\n", ch);
}
return 0;
}
第一题代码
方法一
#include <stdio.h>
#include <string.h>
int main() {
char str[100];
printf("请输入一个字符串:");
fgets(str, sizeof(str), stdin);
int length = strlen(str);
for (int i = 0; i < length; i++) //遍历字符数组
{
if (str[i] >= 'a' && str[i] <= 'z')
{
str[i] = str[i] - 32; // 将小写字母转换为大写字母
}
}
printf("转换后的字符串为:%s", str);
return 0;
}
方法二
#include <stdio.h>
#include <ctype.h>
int main() {
char str[100];
printf("请输入一个字符串: ");
fgets(str, sizeof(str), stdin);
int i = 0;
while (str[i] != '\0')
{
if (islower(str[i]))
{
str[i] = toupper(str[i]);
}
i++; //换种方法遍历字符数组
}
printf("转换后的字符串为: %s\n", str);
return 0;
}
第二题
从键盘上输入一个字符串,将字符串中的abc删除。
思路
(1)如果这道题的目的是把字符串中的所有a、b、c字符都删除,得到一个新的字符串。
我的思路是只申请一个字符数组,遍历此数组,把除了a、b、c以外的所有字符都留下。具体实现代码如下:
#include <stdio.h>
#include <string.h>
void remove_abc(char *str)
{
int len = strlen(str);
int i, j = 0;
for (i = 0; i < len; i++) //遍历字符数组
{
if (str[i] != 'a' && str[i] != 'b' && str[i] != 'c')
{
str[j++] = str[i]; //str[j++]是先把j原来的值用掉再自加,这里是把留下来的字符又放回原数组,重新对数组赋值了
}
}
str[j] = '\0'; // 在新的字符串末尾加上结束标志符
}
int main()
{
char str[100]; //申请一个字符数组
printf("请输入字符串: ");
scanf("%s", str);
remove_abc(str);
printf("删除abc后的字符串为: %s\n", str);
return 0;
}
(2)如果这道题的要求是把字符串中的“abc”删除,而不是把单个的a、b、c字符删除,那么这道题可以使用指针处理。
#include <stdio.h>
#include <string.h>
void removeABC(char *str)
{
int len = strlen(str);
char *src = str;
char *dest = str; //申请的两个指针指向同一地址
while (*src)
{
if (*src == 'a' && *(src+1) == 'b' && *(src+2) == 'c') //判断连续的abc字符串
{
src += 3; //从字符a开始将指针后移到3个位置,跨越掉abc这部分
}
else
{
*dest++ = *src++;
}
}
*dest = '\0';
}
int main()
{
char str[100];
printf("请输入一个字符串: ");
scanf("%[^\n]%*c", str);
removeABC(str);
printf("删除'abc'后的字符串为: %s\n", str);
return 0;
}
tips
第三题
在 C 语言中,int 类型的取值范围通常是 -2147483648 到 2147483647,进行 11 位及以上数字的加法运算,(超过了 int 类型的表示范围)。
(1)我们使用字符数组来表示大数,并实现了自定义的 addStrings 函数来进行字符串形式的大数加法运算。该函数通过逆序遍历两个输入字符串,并模拟手工加法的方式进行计算,将结果存储在 result 字符数组中。
(2)在 main 函数中,我们声明了两个字符数组变量 num1 和 num2,分别存储了两个 11 位数字的字符串表示。然后,我们调用 addStrings 函数将它们相加,并将结果存储在 result 字符数组中。最后,使用 %s 格式化字符串打印出结果。
(3)这个简单的示例只适用于非负整数的加法运算,并且没有处理输入的有效性检查、溢出等情况。在实际应用中,你可能需要根据具体需求进行更完善的实现。
#include <stdio.h>
#include <string.h>
#define MAX_DIGITS 100
void addStrings(char* num1, char* num2, char* result) {
int len1 = strlen(num1);
int len2 = strlen(num2);
int carry = 0;
int i, j, k;
// 逆序遍历两个字符串,从个位数开始相加
for (i = len1 - 1, j = len2 - 1, k = 0; i >= 0 || j >= 0 || carry; i--, j--, k++) {
int digit1 = (i >= 0) ? num1[i] - '0' : 0;
int digit2 = (j >= 0) ? num2[j] - '0' : 0;
int sum = digit1 + digit2 + carry;
result[k] = sum % 10 + '0'; // 当前位的数字
carry = sum / 10; // 进位
}
// 反转结果字符串
int len = k;
for (i = 0, j = len - 1; i < j; i++, j--) {
char temp = result[i];
result[i] = result[j];
result[j] = temp;
}
result[len] = '\0';
}
int main() {
char num1[MAX_DIGITS] = "12345678901"; // 第一个 11 位数字
char num2[MAX_DIGITS] = "98765432109"; // 第二个 11 位数字
char result[MAX_DIGITS + 1]; // 结果字符串,预留一位存储结束符 '\0'
addStrings(num1, num2, result);
printf("Sum: %s\n", result);
return 0;
}