第81题:
题目:809*??=800*??+9*?? 其中??代表的两位数, 809*??为四位数,8*??的结果为两位数,9*??的结果为3位数。求??代表的两位数,及809*??后的结果。
分析:使用两个循环,分别遍历两位数的所有可能值。对于每个两位数 ’ i ’ 。我们计算出 809 * ?? 的结果并存储在result_809变量中,同时计算8 * ?? 和 9 * ??的结果,并分别存储在result_8和result_9两个变量中。然后检查符合条件的情况,result_809是一个四位数,result_8是一位数,result_9是一位数,result_809 = 800 * i + 9 * i。
int main() {
for (int i = 10; i < 100; i++) {
int result_809 = 809 * i;
int result_8 = 8 * i;
int result_9 = 9 * i;
if (result_809 >= 1000 && result_809 <= 9999 && result_8 >= 10 && result_8 <= 99 &&
result_9 >= 100 && result_9 <= 999 && result_809 == 800 * i + 9 * i)
{
printf("??代表的两位数是: %d\n", i);
printf("809*??的结果是: %d\n", result_809);
break;
}
}
return 0;
}
第82题:
题目:八进制转换为十进制
分析:首先输入一个数,这个数要以十进制输入,但你在程序中应当把这个数当做八进制的数来处理。用10来取余,然后将取出来的余数乘以8的0次方,然后将输入的数除以10用来降位,不停循环。
int OctalToDecimal(int number)
{
int decimal = 0;
int base = 1;
while (number > 0)
{
int digit = number % 10; //取最右边的一位
decimal += digit * base;
base *= 8; //每次循环 base * 8
number /= 10; //移除最右边的一位
}
return decimal;
}
int main()
{
int OctalNumber;
printf("请输入一个八进制数:");
scanf("%d", &OctalNumber);
int DecimalNumber = OctalToDecimal(OctalNumber);
printf("转换后的十进制数为:%d\n", DecimalNumber);
return 0;
}
第83题:
题目:求0—7所能组成的奇数个数。
分析:本题本质上是一个数学分析求和的题,一位数时:4,二位数:74,三位数:78*4,四位数到8位数依次乘以8,然后相加求和即可。
int main()
{
long sum = 4 ,s = 4;
int j;
for (j = 2; j <= 8; j++)
{
if (j <= 2)
s *= 7;
else
s *= 8;
sum += s;
}
printf("共%d个", sum);
return 0;
}
第84题:
题目:一个偶数总能表示为两个素数之和
分析:假设该偶数能由两个素数组成。使用二分搜索法,先定义一个函数用于判断是否是素数。判断时每次变化为 i 的平方。因为如果一个数由平方组成那么该数不会是素数。其次再进行查找两个数时,从输入的偶数除以2开始左右查找,不断向中间靠近。
#include <stdio.h>
// 判断是否为素数
int is_prime(int num)
{
if (num <= 1)
return 0;
//平方减少查找次数
for (int i = 2; i * i <= num; i++)
{
if (num % i == 0)
return 0;
}
return 1;
}
// 寻找两个素数之和等于给定偶数
void find_prime_sum(int even_num)
{
if (even_num <= 2 || even_num % 2 != 0)
{
printf("输入无效");
return;
}
for (int i = even_num / 2; i>= 2; --i)
{
if (is_prime(i) && is_prime(even_num - i))
{
printf("%d = %d + %d\n", even_num, i, even_num - i);
return;
}
}
printf("无法找到两个素数之和等于%d\n", even_num);
}
int main()
{
int even_num = 24;
find_prime_sum(even_num);
return 0;
}
第85题:
题目:判断一个素数能被几个9整除
解析:首先需要判断输入是否素数。接下,仔细理解题意,应该是输入的这素数能被9还是99还是999,更多的9整除。而不是这个素数去除以9,不要理解错题意了。这个很关键。
bool isPrime(int num)
{
if (num < 1)
return false;
for (int i = 2; i * i < num; i++)
{
if (num % i == 0)
return false;
}
return true;
}
int main()
{
int num;
printf("请输入一个素数");
if (scanf("%d", &num) != 1)
{
printf("输入无效, 必须输入一个整数。\n");
}
if (isPrime(num))
{
int n = 0;
int Divisor = 9;
while (Divisor % num != 0)
{
n++;
Divisor = Divisor * 10 + 9;
}
printf("%d能被%d个9整除", num, n);
}
else
{
printf("不是素数");
}
return 0;
}
第86题:
题目:两个字符串连接程序 。
分析:可以用string.h库中的strcat函数,去拼接字符串。但是这需要提前申请好两个字符串数组用于存储,最后再将一个拼接后的数组覆盖。但这很浪费空间,让我们使用动态分配内存的方式来实现不确定字符串长度的拼接
typedef struct Node
{
char data;
struct Node *next;
}Node;
// 函数用于将字符添加到链表末尾
void append(Node ** head, char data)
{
Node *newNode = (Node *)malloc(sizeof(Node));
newNode->data = data;
newNode->next = NULL;
if (*head == NULL)
{
*head = newNode;
}
else
{
struct Node *current = *head;
while (current->next != NULL)
{
current = current->next;
}
current->next = newNode;
}
}
// 函数用于将链表中的字符连接成串
char *concatentate(struct Node * head)
{
if (head == NULL)
{
return NULL;
}
int length = 0;
Node *current = head;
// 计算字符串长度
while (current != NULL)
{
length++;
current = current->next;
}
//分配足够的内存来存储字符串
char *result = (char *)malloc((length + 1) * sizeof(char));
current = head;
// 将链表中的字符复制到字符串中
for (int i = 0; i < length; i++)
{
result[i] = current->data;
current = current->next;
}
//添加终止符
result[length] = '\0';
return result;
}
int main()
{
Node *str1 = NULL;
Node *str2 = NULL;
printf("请输入第一个字符串:");
char ch;
while ((ch = getchar()) != '\n')
{
append(&str1, ch);
}
printf("请输入第二个字符串:");
while ((ch = getchar()) != '\n')
{
append(&str2, ch);
}
//连接两个链表
Node *concentated = str1;
Node *current = str1;
while (current != NULL && current->next != NULL)
{
current = current->next;
}
if (current != NULL)
{
current->next = str2;
}
else
{
concentated = str2;
}
char *result = concatentate(concentated);
printf("连接后的字符串是:%s\n", result);
// 释放链表和字符串内存
while (str1 != NULL)
{
Node *temp = str1;
str1 = str1->next;
free(temp);
}
//将str2指向NULL,避免重复释放内存
str2 = NULL;
free(result);
return 0;
}
第87题:
题目:回答结果(结构体变量传递)
分析:把结构体作为变量传递。分别是1、值传递,将结构体变量的副本传递给函数,这意味着函数操作的是结构体的拷贝;2、引用传递,将结构体变量的地址(指针)传递给函数,这意味着函数可以直接操作原始结构体,对原始结构体会有影响。
typedef struct Point
{
int x;
int y;
}Point;
// 值传递函数
void ByValue(Point point)
{
point.x = 10;
point.y = 20;
}
// 引用传递
void ByReference(Point *point)
{
point->x = 10;
point->y = 20;
}
int main()
{
Point p1 = { 1, 2 };
Point p2 = { 3, 4 };
// 值传递
ByValue(p1);
// 输出:x=1, y=2
printf("p1 after : x=%d, y=%d\n", p1.x, p1.y);
// 引用传递
ByReference(&p2);
// 输出:x=10, y=20
printf("p2 after : x=%d, y=%d\n", p2.x, p2.y);
return 0;
}
第88题:
题目:读取7个数(1—50)的整数值,每读取一个值,程序打印出该值个数的 *。
分析:循环读取7次数据,每次对读取的数据进行判断,然后根据该值打印出对应的星号。当然你可以用一个数组一次性输入7个数字,然后再打印。思路是类似的。
int main()
{
int count = 7;
for (int i = 0; i < count; i++)
{
int number;
printf("请输入1-50以内的整数");
while (scanf("%d", &number))
{
for (int j = 0; j < number; j++)
{
printf("*");
}
printf("\n");
}
}
return 0;
}
第89题:
题目:某个公司采用公用电话传递数据,数据是四位的整数,在传递过程中是加密的,加密规则如下: 每位数字都加上5,然后用和除以10的余数代替该数字,再将第一位和第四位交换,第二位和第三位交换。
分析:该题的重点就是将输入的4位整数进行拆分然后重组,主要是合理利用除与取余。
int encrypt(int num)
{
// 分离各个位数
int thousand = num / 1000;
int hundred = (num / 100) % 10;
int ten = (num / 10) % 10;
int one = (num % 10);
// 对每位数字加5,并取余10
thousand = (thousand + 5) % 10;
hundred = (hundred + 5) % 10;
ten = (ten + 5) % 10;
one = (one + 5) % 10;
// 交换第一位和第四位,第二位和第三位
int encryptedNum = hundred * 1000 + one * 100 + ten * 10 + thousand;
return encryptedNum;
}
int main()
{
int num;
printf("请输入一个四位整数:");
scanf("%d", &num);
if (num < 1000 || num > 9999)
{
printf("输入的不是四位整数。\n ");
}
else
{
int encryptedNum = encrypt(num);
printf("加密后的数字是:%d\n", encryptedNum);
}
}
第90题:
题目:专升本一题,读结果。
分析:看代码,分析结果是什么。这里主要用到数组指针的调用等基础知识。通过分析代码,可得出这段代码主要是用于将数组进行翻转。
#define M 5
int main()
{
int a[M]={1,2,3,4,5};
int i,j,t;
i=0;
j=M-1;
while(i<j)
{
t=*(a+i);
*(a+i)=*(a+j);
*(a+j)=t;
i++;
j--;
}
for(i=0;i<M;i++) {
printf("%d\n",*(a+i));
}
}
第91~93题:
题目:全是时间函数的调用相关
分析:可以自行学习下。这里对部分知识点进行介绍:
time_t(time_t *t)
struct tm *localtime(const time_t) 将time表示的时间转换为本地时间
struct tm *gmtime(const time_t *time) 类似于localtime 但是将时间转换为GMT
char *asctime(const struct tm *timeptr) 将struct tm 结构的时间转换为一个表示时间的字符串
char *ctime (const time_t *time) 将time表示的时间转换为一个表示时间的字符串
double difftime(time_time1, time_t time2): 计算time1和time2之间的时间差
int main()
{
time_t rawtime; // 获取原始时间
struct tm * timeinfo; // 将秒数转换为本地时间
time(&rawtime);
timeinfo = localtime(&rawtime);
printf("当前本地时间为: %s", asctime(timeinfo)); // 将本地时间转换为可读字符串
return 0;
}
第94题:
题目:写一个猜谜小游戏
分析:这个很常见的,我就随便举例了。
int main()
{
int numberToGuess;
int playerGuess;
int attempt = 0;
// 使用当前时间作为随机数种子
srand(time(NULL));
//生成随机数
numberToGuess = rand() % 100 + 1;
printf("欢迎参加猜谜游戏,请猜一个1-100的数字\n");
do {
printf("请输入你的猜测");
scanf("%d", &playerGuess);
attempt++;
if (playerGuess < numberToGuess)
printf("小了");
else if (playerGuess > numberToGuess)
{
printf("大了");
}
else
{
printf("猜对了!答案是%d,共用了%d", playerGuess, attempt);
}
} while (playerGuess != numberToGuess);
return 0;
}
第95题:
题目:简单的结构体应用实例。
分析:涉及一些结构体的基本操作
typedef struct Student {
char name[50];
int age;
}Student;
void InputInfo(Student *student)
{
printf("请输入学生姓名:\n");
scanf("%s", &student->name);
printf("请输入学生年纪:\n");
scanf("%d", &student->age);
}
void Display(const Student *student)
{
printf("学生姓名:%s\n", student->name);
printf("学生年纪:%d\n", student->age);
}
int main()
{
Student student1;
printf("请输入第一个学生的信息\n");
InputInfo(&student1);
Display(&student1);
return 0;
}
第96题:
题目:计算字符串中子串出现的次数 。
分析:采用string.h中的strstr(要在其中搜索的字符串,子字符串)。每找到一个子字符串向后移动一个子字符串的单位提高效率。
int countSubstr(const char *str, const char *substr)
{
int count = 0;
const char *ptr = str;
while ((ptr = strstr(ptr, substr)) != NULL)
{
count++;
ptr += strlen(substr);
}
return count;
}
int main()
{
const char *str = "This is a test. This test is a good test.";
const char *substr = "test";
int result = countSubstr(str, substr);
printf("一共有%d个 %s", result, substr);
return 0;
}
第97题:
题目:从键盘输入一些字符,逐个把它们送到磁盘上去,直到输入一个#为止。
分析:主要用到FILE的相关操作,以及在输入# 号时给出判定。
int main()
{
char filename[10];
char input;
printf("请输入文件名字:");
scanf("%s", filename);
FILE *file = fopen(filename, "w");
if (file == NULL)
{
printf("打开这个文件失败.\n");
return 1;
}
printf("请输入要写入文件的字符串. 输入 # to stop\n");
while (1)
{
scanf("%c", &input);
if (input == '#')
{
break;
}
fputc(input, file);
}
fclose(file);
printf("字符写入成功");
return 0;
}
第98题:
题目:从键盘输入一个字符串,将小写字母全部转换成大写字母,然后输出到一个磁盘文件"test"中保存。 输入的字符串以!结束。
分析:该题主要用到一个islower用于将小写转换为大写,还有使用toupper进行转换。
int main()
{
char c;
FILE *file;
file = fopen("test.txt", "w");
if (file == NULL)
{
printf("该文件不存在\n");
}
printf("请输入一个字符串,以感叹号结束!\n");
while (c=getchar() != '!')
{
if (islower(c))
{
c = toupper(c);
fputc(c, file);
}
else
{
fputc(c, file);
}
}
fclose(file);
printf("已经成功将结果保存在文件中啦!");
return 0;
}
第99题:
题目:有两个磁盘文件A和B,各存放一行字母,要求把这两个文件中的信息合并(按字母顺序排列),输出到一个新文件C中。
分析:由于我们不知道文件中存在多少个字符串,我们这里采用链表来管理此字符串
// 定义链表节点结构
// 由于我们不能确定链表中存在多少个字符串
#define MAXSIZE 100
typedef struct Node
{
char data[MAXSIZE];
struct Node *next;
}Node;
// 插入节点到链表
void insertNode(Node** head, char* data)
{
Node* newNode = (Node*)malloc(sizeof(Node));
// 动态分配内存并配置数据
// 请确保newNode->data 的大小足够容纳源字符串,以避免缓冲区溢出
strcpy(newNode->data, data);
newNode->next = NULL;
if (*head == NULL)
{
*head = newNode;
}
else
{
Node* current = *head;
while (current->next != NULL)
{
current = current->next;
}
current->next = newNode;
}
}
// 释放链表
void freeList(struct Node* head)
{
while (head != NULL)
{
Node* temp = head;
head = head->next;
// 释放动态分配的数据内存
free(temp);
}
}
// 比较函数用于排序
int compareStrings(const void *a, const void *b)
{
return strcmp(*(const char**)a, *(const char**)b);
}
int main()
{
FILE* file1;
FILE* file2;
FILE* file3;
Node* head = NULL;
// 打开文件A 和文件B 以及 新文件C
file1 = fopen("A.txt", "r");
file2 = fopen("B.txt", "r");
file3 = fopen("C.txt", "w");
if (file1 == NULL || file2 == NULL || file3 == NULL)
{
printf("无法打开文件\n");
return 1;
}
char buffer[100];
// 读取文件A的内容并插入链表
while (fgets(buffer, sizeof(buffer), file1) != NULL)
{
insertNode(&head, buffer);
}
// 读取文件B的内容并插入链表
while (fgets(buffer, sizeof(buffer), file2) != NULL)
{
insertNode(&head, buffer);
}
// 关闭文件A和文件B
fclose(file1);
fclose(file2);
// 将链表中内容按字母排序
int count = 0;
Node* current = head;
while (current != NULL)
{
count++;
current = current->next;
}
char** strings = (char**)malloc(count * sizeof(char *));
current = head;
for (int i = 0; i < count; i++)
{
strings[i] = current->data;
current = current->next;
}
qsort(strings, count, sizeof(char *), compareStrings);
// 将排序后的内容写入新文件C
for (int i = 0; i < count; i++)
{
fprintf(file3, "%s", strings[i]);
}
// 关闭文件C
fclose(file3);
// 释放链表和字符数组
freeList(head);
free(strings);
printf("合并完成");
return 0;
}
第100题:
题目:有五个学生,每个学生有3门课的成绩,从键盘输入以上数据(包括学生号,姓名,三门课成绩),计算出平均成绩,将原有的数据和计算出的平均分数存放在磁盘文件"stud.txt"中。
分析:建立结构体学生,然后循环输入数据。
#define STUDENTSIZE 5
#define NAMESIZE 20
#define IDSIZE 10
#define GRADE 3
typedef struct Student
{
char name[NAMESIZE];
char studId[IDSIZE];
float score[GRADE];
}Student;
void InputInfo(Student* stu)
{
printf("请输入学生姓名:\n");
scanf("%s", &stu->name);
printf("请输入学生ID:\n");
scanf("%s", &stu->studId);
printf("请按照语文、数学、英语输入成绩:\n");
for (int i = 0; i < GRADE ; i++)
{
scanf("%f", &stu->score[i]);
}
}
float CalcMean(Student* stu)
{
float mean;
float sum = 0;
for (int i = 0; i < GRADE; i++)
{
sum += stu->score[i];
}
mean = sum / 3;
return mean;
}
int main()
{
float result;
Student students[5];
FILE *file;
// 从键盘输入学生信息
printf("请输入5个学生的信息:\n");
for (int i = 0; i < STUDENTSIZE; i++)
{
InputInfo(&students[i]);
}
// 打开文件以写入数据
file = fopen("stud.txt", "w");
if (file == NULL)
{
printf("无法打开文件");
return 1;
}
fprintf(file, "学生号\t姓名\t成绩1\t成绩2\t成绩3\t平均成绩\n");
for (int i = 0; i < 5; i++)
{
result = CalcMean(&students[i]);
fprintf(file, "%s\t%s\t%.2f\t%.2f\t%.2f\t%.2f\n",
students[i].studId, students->name,
students[i].score[0], students[i].score[1], students[i].score[2], result);
}
// 关闭文件
fclose(file);
printf("数据已经保存到文件中");
return 0;
}
恭喜下自己吧,总算完成了C语言100道题的解析。希望学习的伙伴,我的代码能对你们有益。接下来会接着更新我对算法的学习与理解。还有自己做的项目理解(主要是论文搞定啦,太开心了)。