递归函数
第1关:计算学生年龄
#include <stdio.h>
// 用递归的方式计算第 n 个学生的年龄
int calcAge(int n) {
if (n == 1) {
return 10; // 基准情况:第一个学生的年龄是10岁
} else {
return calcAge(n - 1) + 2; // 递归调用,每个学生比前一个学生大2岁
}
}
int main() {
int n;
scanf("%d", &n); // 从标准输入读取学生的序号
printf("%d\n", calcAge(n)); // 打印第 n 个学生的年龄
return 0;
}
第2关:用递归的思想计算阶乘
#include<stdio.h>
int fac(int n) {
/*******begin********/
if (n <= 1) // 当n为1或者更小时,返回1,因为1的阶乘是1
return 1;
else
return n * fac(n - 1); // 否则返回n乘以n-1的阶乘,这是递归调用
/*******end**********/
}
int main() {
int n;
int ret;
scanf("%d", &n); // 读取用户输入的整数n
ret = fac(n); // 调用阶乘函数
printf("%d", ret); // 输出阶乘结果
return 0;
}
第3关:猴子吃桃
#include <stdio.h>
// 递归函数计算第n天的桃子数
int taoshu(int n) {
if (n == 10) {
return 1;
} else {
return (taoshu(n + 1) + 1) * 2;
}
}
int main() {
int result = taoshu(1);
printf("%d\n", result); // 输出第一天的桃子数
return 0;
}
函数
第1关:求和
#include <stdio.h>
// 函数声明
int sum_of_series(int n);
int main() {
int n;
scanf("%d", &n);
printf("%d\n", sum_of_series(n));
return 0;
}
// 函数定义
int sum_of_series(int n) {
return n * (n + 1) / 2;
}
第2关:回文数计算
#include <stdio.h>
// 函数声明
int is_palindrome(int num);
int main() {
// 遍历区间[200, 3000]
for (int i = 200; i <= 3000; i++) {
// 检查当前数字是否是回文数
if (is_palindrome(i)) {
// 如果是回文数,则输出
printf("%d\n", i);
}
}
return 0;
}
// 函数定义:检查一个数是否是回文数
int is_palindrome(int num) {
int original_num = num;
int reversed_num = 0;
// 反转数字
while (num > 0) {
reversed_num = reversed_num * 10 + num % 10;
num /= 10;
}
// 如果反转后的数字与原数字相同,则是回文数
return original_num == reversed_num;
}
第3关: 编写函数求表达式的值
#include <stdio.h>
double calculate_s(int n) {
double s = 1.0;
for (int i = 1; i <= n; i++) {
double numerator = 1.0;
double denominator = 1.0;
for (int j = 1; j <= i; j++) {
numerator *= j;
denominator *= (2 * j + 1);
}
s += numerator / denominator;
}
return s;
}
int main() {
int n;
scanf("%d", &n);
printf("%.10f\n", calculate_s(n));
return 0;
}
第4关:阶乘数列
#include <stdio.h>
// 函数声明
long long factorial(int n);
int main() {
int n;
scanf("%d", &n);
long long sum = 0;
for (int i = 1; i <= n; i++) {
sum += factorial(i);
}
printf("%lld\n", sum);
return 0;
}
// 函数定义:计算阶乘
long long factorial(int n) {
long long result = 1;
for (int i = 2; i <= n; i++) {
result *= i;
}
return result;
}
第5关:亲密数
#include <stdio.h>
// 函数声明
int sum_of_factors(int num);
int main() {
// 用于存储已经找到的亲密数对
int found[3001] = {0};
// 遍历所有可能的数对
for (int a = 1; a <= 3000; a++) {
int b = sum_of_factors(a);
if (b > a && b <= 3000 && sum_of_factors(b) == a) {
// 检查是否已经找到过这对亲密数
if (!found[a]) {
printf("(%d,%d)", a, b);
found[a] = 1;
}
}
}
return 0;
}
// 函数定义:计算一个数的所有因子之和
int sum_of_factors(int num) {
int sum = 0;
for (int i = 1; i <= num / 2; i++) {
if (num % i == 0) {
sum += i;
}
}
return sum;
}
第6关:公约公倍数
#include <stdio.h>
// 函数声明
long long int gcd(long long int a, long long int b);
long long int lcm(long long int a, long long int b);
int main() {
long long int a, b;
// 读取输入
scanf("%lld %lld", &a, &b);
// 检查输入是否包含负数
if (a < 0 || b < 0) {
printf("Input Error\n");
} else {
// 计算并输出最大公约数和最小公倍数
printf("%lld %lld\n", gcd(a, b), lcm(a, b));
}
return 0;
}
// 函数定义:计算两个整数的最大公约数
long long int gcd(long long int a, long long int b) {
while (b != 0) {
long long int temp = b;
b = a % b;
a = temp;
}
return a;
}
// 函数定义:计算两个整数的最小公倍数
long long int lcm(long long int a, long long int b) {
return (a * b) / gcd(a, b);
}
第7关:素数判断
#include <stdio.h>
// 函数声明
int isPrime(int num);
int main() {
int num;
scanf("%d", &num);
if (isPrime(num)) {
printf("%d是一个素数\n", num);
} else {
printf("%d不是一个素数\n", num);
}
return 0;
}
// 函数定义
int isPrime(int num) {
if (num <= 1) {
return 0; // 小于等于1的数不是素数
}
for (int i = 2; i * i <= num; i++) {
if (num % i == 0) {
return 0; // 如果num能被i整除,则num不是素数
}
}
return 1; // 如果num不能被任何小于等于其平方根的数整除,则num是素数
}
#include <stdio.h>
// 函数声明
int isPrime(int num);
int main() {
int num;
scanf("%d", &num);
if (isPrime(num)) {
printf("%d是一个素数\n", num);
} else {
printf("%d不是一个素数\n", num);
}
return 0;
}
// 函数定义
int isPrime(int num) {
if (num <= 1) {
return 0; // 小于等于1的数不是素数
}
for (int i = 2; i * i <= num; i++) {
if (num % i == 0) {
return 0; // 如果num能被i整除,则num不是素数
}
}
return 1; // 如果num不能被任何小于等于其平方根的数整除,则num是素数
}
第8关:最大公约数
#include<stdio.h>
// 函数原型声明
int MaxCommonFactor(int a, int b);
int main() {
int a, b;
// 输入两个整数
scanf("%d,%d", &a, &b);
// 调用函数并输出最大公约数
printf("%d\n", MaxCommonFactor(a, b));
return 0;
}
// 求最大公约数的函数实现
int MaxCommonFactor(int a, int b) {
if(a <= 0 || b <= 0) { // 如果输入不正确,返回-1
return -1;
}
int temp;
// 辗转相除法
while(b) {
temp = a % b;
a = b;
b = temp;
}
return a;
}
指针基础
第1关:利用指针找最大值
#include <stdio.h>
int main() {
int a, b;
int *p1, *p2, *pmax;
scanf("%d %d", &a, &b);
// 指针变量指向相应的变量
p1 = &a;
p2 = &b;
// 比较并找出最大值
if (*p1 > *p2) {
pmax = p1;
} else {
pmax = p2;
}
// 输出最大值
printf("max=%d\n", *pmax);
return 0;
}
第2关:调用函数求两个数的和与差
#include <stdio.h>
// 自定义函数 sum_diff,用于计算和与差
void sum_diff(float op1, float op2, float *psum, float *pdiff) {
*psum = op1 + op2; // 计算和
*pdiff = op1 - op2; // 计算差
}
int main() {
float op1, op2;
float sum, diff;
// 输入两个实数
scanf("%f %f", &op1, &op2);
// 调用 sum_diff 函数计算和与差
sum_diff(op1, op2, &sum, &diff);
// 输出和与差
printf("The sum is %g\n", sum);
printf("The diff is %g\n", diff);
return 0;
}
第3关:循环后移
#include <stdio.h>
// 函数声明,循环后移数组元素
void move(int *x, int n, int m);
int main() {
int n, m;
// 输入数组的大小和移动的位置数
scanf("%d %d", &n, &m);
int arr[1000]; // 假设数组最多包含1000个元素
// 输入数组的元素
for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
// 调用函数进行循环后移
move(arr, n, m);
// 输出调整后的数组
printf("After moved:");
for (int i = 0; i < n; i++) {
if (i == 0) {
printf("%d", arr[i]); // 第一个数字前没有空格
} else {
printf(" %d", arr[i]); // 其他数字前有空格
}
}
printf("\n");
return 0;
}
// 函数定义,循环后移数组元素
void move(int *x, int n, int m) {
int temp[1000]; // 临时数组用于存储移动后的结果
// 计算新位置
for (int i = 0; i < n; i++) {
temp[(i + m) % n] = x[i];
}
// 将临时数组的内容复制回原数组
for (int i = 0; i < n; i++) {
x[i] = temp[i];
}
}
指针进阶
第1关:输出若干个学生成绩中的最高分.要求用指针函数实现
#include <stdio.h>
// 函数声明,返回指向最高分的指针
int* max_score(int scores[], int n);
int main() {
int n;
int scores[1000];
// 输入学生数量
scanf("%d", &n);
// 输入学生成绩
for (int i = 0; i < n; i++) {
scanf("%d", &scores[i]);
}
// 调用函数求最高分
int *max = max_score(scores, n);
// 输出最高分
printf("%d\n", *max);
return 0;
}
// 函数定义,返回指向最高分的指针
int* max_score(int scores[], int n) {
int *max = &scores[0];
for (int i = 1; i < n; i++) {
if (scores[i] > *max) {
max = &scores[i];
}
}
return max;
}
第2关:采用指针变量表示地址的方法输入输出数组中的个元素
#include <stdio.h>
int main() {
int n;
int arr[1000]; // 假设数组最多包含1000个元素
// 输入数组的大小
scanf("%d", &n);
// 输入数组的元素
for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
// 用指针变量输出数组的元素
for (int i = 0; i < n; i++) {
printf("%d", *(arr + i)); // 用指针表示数组元素的地址
if (i < n - 1) {
printf(" "); // 在元素之间添加空格
}
}
printf("\n"); // 输出换行符
return 0;
}
第3关:用指针实现数组循环移动
#include <stdio.h>
// 函数声明,循环右移数组元素
void move(int *x, int n, int m);
int main() {
int n, m;
// 输入数组的大小和移动的位置数
scanf("%d %d", &n, &m);
int arr[1000]; // 假设数组最多包含1000个元素
// 输入数组的元素
for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
// 调用函数进行循环右移
move(arr, n, m);
// 输出调整后的数组
for (int i = 0; i < n; i++) {
printf("%d", arr[i]);
if (i < n - 1) {
printf(" ");
}
}
printf("\n");
return 0;
}
// 函数定义,循环右移数组元素
void move(int *x, int n, int m) {
int temp[1000]; // 临时数组用于存储移动后的结果
// 计算新位置
for (int i = 0; i < n; i++) {
temp[(i + m) % n] = x[i];
}
// 将临时数组的内容复制回原数组
for (int i = 0; i < n; i++) {
x[i] = temp[i];
}
}
指针及其应用
第1关:数组倒置
#include "stdio.h"
#define N 10
void reverse(int *p, int a, int b) {
int c;
/***** 请在以下一行填写代码 *****/
// 当 a 小于 b 时,继续循环
while (a < b) {
c = *(p + a); // 将 p[a] 的值存储在 c 中
/***** 请在以下一行填写代码 *****/
// 将 p[b] 的值赋给 p[a]
*(p + a) = *(p + b);
*(p + b) = c; // 将 c 的值赋给 p[b]
a++; // 增加 a 的值
/***** 请在以下一行填写代码 *****/
b--; // 减少 b 的值
}
}
int main() {
int a[N], i;
for (i = 0; i < N; i++)
/***** 请在以下一行填写代码 *****/
// 读取输入的整数并存储在数组 a 中
scanf("%d", &a[i]);
reverse(a, 0, N - 1); // 调用 reverse 函数,倒置数组 a 的元素
for (i = 0; i < N; i++) {
/***** 请在以下一行填写代码 *****/
// 输出数组 a 的元素
if (i == N - 1) {
printf("%d", a[i]);
} else {
printf("%d ", a[i]);
}
}
printf("\n"); // 输出换行符
return 0; // 程序结束
}
第2关:字符排序
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int fun(char *s, int num) {
char ch;
int i, j;
// 对中间的5个字符进行排序
for (i = 1; i < 6; i++) {
for (j = i + 1; j < 6; j++) {
/***** 请在以下一行填写代码 *****/
// 如果 s[i] 的 ASCII 码小于 s[j] 的 ASCII 码,则交换它们的位置
if (*(s + i) < *(s + j)) {
ch = *(s + j);
*(s + j) = *(s + i);
*(s + i) = ch;
}
}
}
return 0; // 函数结束
}
int main() {
char s[10]; // 定义字符数组 s,用于存储输入的字符串
// 读取输入的字符串
scanf("%s", s);
/***** 请在以下一行填写代码 *****/
// 调用 fun 函数,对字符串进行排序
fun(s, strlen(s));
// 输出排序后的字符串
printf("%s", s);
return 0; // 程序结束
}
第3关:找最长串
#include <stdio.h>
#include <string.h>
#define N 5
#define M 81
char* fun(char (*sq)[M]) {
int i;
char *sp;
sp = sq[0]; // 初始化 sp 为第一个字符串的地址
for (i = 1; i < N; i++) { // 从第二个字符串开始比较
if (strlen(sp) < strlen(sq[i])) {
sp = sq[i]; // 如果当前字符串长度大于 sp 指向的字符串长度,则更新 sp
}
}
return sp; // 返回最长字符串的地址
}
int main() {
char str[N][M], *longest;
int i;
for (i = 0; i < N; i++) {
scanf("%s", str[i]); // 读取 N 个字符串
}
printf("The %d string :\n", N);
for (i = 0; i < N; i++) {
puts(str[i]); // 输出 N 个字符串
}
longest = fun(str); // 调用 fun 函数,获取最长字符串的地址
printf("The longest string :\n");
puts(longest); // 输出最长的字符串
return 0; // 程序结束
}
第4关:星号转移
#include <stdio.h>
void fun(char *a) {
int i = 0, n = 0; // 定义变量 i 和 n,分别用于遍历字符串和统计前导 * 号的个数
char *p;
p = a;
// 统计前导 * 号的个数
while (*p == '*') {
n++;
/***** 请在以下一行填写代码 *****/
p++;
}
// 将非 * 号的字符移到字符串的前面
while (*p) {
/***** 请在以下一行填写代码 *****/
a[i] = *p;
i++;
p++;
}
// 将统计的 * 号移到字符串的尾部
while (n != 0) {
a[i] = '*';
i++;
/***** 请在以下一行填写代码 *****/
n--;
}
a[i] = '\0'; // 添加字符串结束符
}
int main() {
char s[81]; // 定义字符数组 s,用于存储输入的字符串
int n = 0;
// 读取输入的字符串
scanf("%s", s);
// 调用 fun 函数,处理字符串
fun(s);
// 输出处理后的字符串
printf("The string after oveing: \n");
puts(s);
return 0; // 程序结束
}
常见字符串处理函数
第1关:比较两个字符串的大小
#include <stdio.h>
#include <string.h>
int main() {
char a[] = "computer";
char b[20];
// 输入字符串"compare"
printf("");
scanf("%s", b);
// 比较字符串a和b
if (strcmp(a, b) > 0) {
printf("%s\n", a);
} else {
printf("%s\n", b);
}
return 0;
}
第2关:合并两个字符串
#include <stdio.h>
void strc(char s[], char t[]) {
int i = 0, j = 0;
while (*s != '\0')
/*******begin********/
{
s++;
}
/*******end**********/
while (*t != '\0')
{
/*******begin*******/
*s = *t;
s++;
t++;
/*******end*********/
}
*s = '\0';
}
int main() {
char s[80] = {"hello "}, t[80];
gets(t);
strc(s, t);
puts(s);
return 0;
}
第3关:在字符数组中找出最小的字符串
#include <stdio.h>
#include <string.h>
int main() {
int i; // 定义循环变量 i
char min[80], str[80]; // 定义两个字符数组 min 和 str,用于存储字符串
// 读取第一个字符串,并将其存储到 str 中
scanf("%s", str);
// 将第一个字符串复制到 min 中,作为初始的最小字符串
strcpy(min, str);
/***********begin***********/
// 循环读取剩余的 4 个字符串
for (i = 1; i < 5; i++) {
// 读取下一个字符串,并将其存储到 str 中
scanf("%s", str);
// 使用 strcmp 函数比较当前字符串和 min 字符串
// 如果当前字符串比 min 小,则更新 min
if (strcmp(str, min) < 0) {
strcpy(min, str); // 将当前字符串复制到 min 中
}
}
/**********end***********/
// 输出最小的字符串
printf("Min is:%s", min);
return 0; // 程序结束
}
第4关:找最长字符串
#include <stdio.h>
#include <string.h>
int main() {
int i; // 定义循环变量 i
char str[80], max[80]; // 定义两个字符数组 str 和 max,用于存储字符串
// 读取第一个字符串,并将其存储到 str 中
scanf("%s", str);
// 将第一个字符串复制到 max 中,作为初始的最长字符串
strcpy(max, str);
/***********begin**************/
// 循环读取剩余的 4 个字符串
for (i = 1; i < 5; i++) {
// 读取下一个字符串,并将其存储到 str 中
scanf("%s", str);
// 使用 strlen 函数比较当前字符串和 max 字符串的长度
// 如果当前字符串比 max 长,则更新 max
if (strlen(str) > strlen(max)) {
strcpy(max, str); // 将当前字符串复制到 max 中
}
}
/***********end*************/
// 输出最长的字符串
printf("%s", max);
return 0; // 程序结束
}
第5关:字符串排序
#include <stdio.h>
#include <string.h>
int main() {
char *name[] = {"blue", "yellow", "red", "black", "green"}; // 定义字符串数组
char *temp; // 定义临时指针变量,用于交换字符串
int i, j; // 定义循环变量 i 和 j
/*************begin*************/
// 使用冒泡排序法对字符串数组进行排序
for (i = 0; i < 5 - 1; i++) {
for (j = 0; j < 5 - 1 - i; j++) {
// 使用 strcmp 函数比较相邻的两个字符串
if (strcmp(name[j], name[j + 1]) > 0) {
// 如果前一个字符串大于后一个字符串,则交换它们的位置
temp = name[j];
name[j] = name[j + 1];
name[j + 1] = temp;
}
}
}
/**************end*************/
// 输出排序后的字符串数组
for (i = 0; i < 5; i++) {
printf("%s ", name[i]);
}
return 0; // 程序结束
}
第6关:判断字符串是否是“回文”
#include <stdio.h>
#include <string.h>
int main() {
int i, k;
char line[80];
// 读取输入的字符串
gets(line);
// 获取字符串的长度
k = strlen(line);
// 初始化变量 i 和 k
i = 0;
k = k - 1;
/*************begin**********/
// 循环比较字符串的开始和结束位置的字符
while (i < k) {
// 如果字符不一致,则跳出循环
if (line[i] != line[k]) {
break;
}
// 移动开始位置向后
i++;
// 移动结束位置向前
k--;
}
/***************end***********/
// 判断是否为回文
if (i >= k)
printf("yes");
else
printf("no");
return 0; // 程序结束
}