目录
01. 二维数组
02. 奇偶性
03. 指针与变量
04. 员工薪资
05. 整型值(%4d 进行格式化)
06. 求三个数中的最大值和最小值
07. 同一字母次数统计
08. 字符串回文判断
09. 闰年判断
10. 交换两个双精度数
01. 二维数组
#include <stdio.h>
int main() {
int a[3][3] = { // 定义一个3x3的二维数组a,并初始化
{1, 4, 17},
{3, 6, 19},
{2, 5, 18}
};
int i, s = 0; // 定义变量i和s,并将s初始化为0
// 使用for循环计算对角线元素的和
for (i = 0; i <= 2; i++) {
s = s + a[i][2 - i]; // 累加对角线元素的值到变量s
}
printf("s=%d\n", s); // 输出变量s的值
return 0;
}
【代码详解】
- 首先,定义了一个 3x3 的二维数组 a,并对其进行初始化。
- 接着,声明了变量 i 和 s 并将 s 初始化为 0。
- 进入 for 循环,从 i=0 开始,迭代到 i<=2 为止。在每次迭代中,计算 a[i][2 - i] 的对角线元素,并将其累加到变量 s 上。
- 循环结束后,使用 printf 输出变量 s 的值。
- 最后,程序返回 0,表示正常执行完毕。
【执行结果】
- 在给定的数组a中,对角线元素包括 1,6 和 18。
- 因此,这些元素的和是 1 + 6 + 18 = 25。
- 所以,输出的结果为 s=25。
s=25
02. 奇偶性
#include <stdio.h>
int main() {
int i;
for(i = 0; i < 5; i++) {
switch(i % 2) { // 对i取模2的结果进行switch判断
case 0: // 如果结果为0
printf("1"); // 输出1
break; // 跳出switch语句
case 1: // 如果结果为1
printf("0"); // 输出0
}
}
}
【代码详解】
- 首先,声明了一个变量 i。
- 进入 for 循环,从 i=0 开始,迭代到 i<5 为止。每次迭代,i 自增 1。
- 在每次循环迭代中,使用 switch 语句对 i 取模 2 的结果进行判断。
- 当 i 被 2 整除时(i % 2 的结果为 0),执行 case 0 的代码块,即输出 1。
- 当 i 除以 2 有余数时(i % 2 的结果为 1),执行 case 1 的代码块,即输出 0。
- 最后,循环结束,程序执行完毕。
根据上述逻辑,当循环迭代 5 次时,输出结果为 10101。
【循环逻辑】
- 在第一次循环迭代时,i 的值为 0,0 对 2 取模的结果为 0,因此执行 case 0 的代码块,输出 “1”。
- 在第二次循环迭代时,i 的值为 1,1 对 2 取模的结果为 1,因此执行 case 1 的代码块,输出 “0”。
- 在第三次循环迭代时,i 的值为 2,2 对 2 取模的结果为 0,因此执行 case 0 的代码块,输出 “1”。
- 在第四次循环迭代时,i 的值为 3,3 对 2 取模的结果为 1,因此执行 case 1 的代码块,输出 “0”。
- 在第五次循环迭代时,i 的值为 4,4 对 2 取模的结果为 0,因此执行 case 0 的代码块,输出 “1”。
【数学逻辑】
- 对于循环迭代变量 i 的取值范围为 0 到 4(i < 5)。
- 在每次迭代中,计算 i 除以 2 的余数(i % 2)。
- 如果余数为 0,表示 i 可以被 2 整除,即 i 是偶数。
- 如果余数为 1,表示 i 除以 2 有余数,即 i 是奇数。
- 根据 i 的奇偶性,输出相应的数字:当 i 为偶数时输出 “1”,当 i 为奇数时输出 “0”。
- 根据循环迭代次数为 5 次,依次检查:0,1,2,3,4。
- 根据上述数学公式,依次输出:1,0,1,0,1。
- 因此,输出结果为:“10101”。
【执行结果】
10101
03. 指针与变量
#include <stdio.h>
int main() {
int x = 20, y = 40, *p; // 声明整型变量x和y,并定义指针变量p
p = &x; // 将指针p指向变量x
printf("%d,", *p); // 输出p所指向的变量的值,即x的值
*p = x + 10; // 修改p所指向的变量的值为x+10
p = &y; // 将指针p指向变量y
printf("%d\n", *p); // 输出p所指向的变量的值,即y的值
*p = y + 20; // 修改p所指向的变量的值为y+20
printf("%d,%d\n", x, y); // 输出变量x和y的值
return 0;
}
【代码详解】
- 首先,声明了整型变量x和y,并将x初始化为20,y初始化为40。
- 声明了指针变量p,用于存储变量的内存地址。
- 将指针p指向变量x,即将p赋值为x的地址。此后,p指向了x变量。
- 使用printf输出*p的值,即指针p所指向的变量的值,这里输出20。
- 修改指针p所指向的变量的值为x+10,即将指针p指向的变量(即x)的值修改为30。
- 将指针p指向变量y,即将p赋值为y的地址。此后,p指向了y变量。
- 使用printf输出*p的值,即指针p所指向的变量的值,这里输出40。
- 修改指针p所指向的变量的值为y+20,即将指针p指向的变量(即y)的值修改为60。
- 使用printf输出变量x和y的值,这里分别输出了x的值60和y的值60。
在代码执行过程中,指针p的值发生了变化,但它一直指向的是x和y这两个变量。对p的修改实际上是修改了p所指向的变量的值。
【执行结果】
20,40 30,60
04. 员工薪资
#include <stdio.h>
#include <string.h>
#define _CRT_SECURE_NO_WARNINGS // 禁止显示 C4996 错误
struct worker {
char name[15];
int age;
float pay;
};
int main() {
struct worker x; // 声明 worker 结构体类型的变量 x
const char* t = "Lilei"; // 使用 const char * 来接收字符串常量 "Lilei"
int d = 20; // 声明整型变量 d,赋值为 20
float f = 100; // 声明浮点型变量 f,赋值为 100
strcpy_s(x.name, sizeof(x.name), t); // 将字符串 t 复制给结构体变量 x 的 name 成员
x.age = d * 2; // 将 d 的两倍赋值给结构体变量 x 的 age 成员
x.pay = f * d; // 将 f 乘以 d 的结果赋值给结构体变量 x 的 pay 成员
printf("%s\t%d\t%.0f\n", x.name, x.age, x.pay);
// 输出结构体变量 x 的 name、age 和 pay 成员的值,并分别用制表符分隔
return 0;
}
【代码详解】
- 首先,包含了
<stdio.h>
和<string.h>
头文件,分别用于输入输出和字符串处理。- 定义了一个结构体 worker,含有三个成员:name (字符数组类型,用于存储工人姓名),age (整型,用于存储工人年龄) 和 pay (浮点型,用于存储工人薪水)。
- 在
main
函数中声明了一个 worker 类型的变量 x。- 声明了一个指针变量 t,指向字符串 “Lilei”。
- 声明了整型变量 d,赋值为 20。
- 声明了浮点型变量 f,赋值为 100。
- 使用
strcpy
函数将字符串 t 复制到结构体变量 x 的 name 成员中。- 将 d 的两倍赋值给结构体变量 x 的 age 成员。
- 将 f 乘以 d 的结果赋值给结构体变量 x 的 pay 成员。
- 使用
printf
函数输出结构体变量 x 的 name、age 和 pay 成员的值。“\t” 是制表符,用于分隔输出。【特别注意】
- 此代码使用
strcpy_s
函数将字符串常量"Lilei"
复制给了结构体变量x
的name
成员。strcpy_s
是一种更安全的字符串复制函数,可以防止缓冲区溢出的问题。在使用strcpy_s
时,需要指定目标字符串的大小,这里使用了sizeof(x.name)
来获取name
字符数组的大小。- 需要注意的是,使用
#define _CRT_SECURE_NO_WARNINGS
宏来禁止 C4996 错误的显示,这样可以避免strcpy_s
报出错误。但请注意,这只适用于某些编译器,具体取决于您使用的编译器。- C4996 错误:C4996 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
- C4996 错误:它指示
strcpy
函数被视为不安全。这是因为strcpy
函数可能导致缓冲区溢出问题。为了解决这个问题,建议使用更安全的函数strcpy_s
。【执行结果】
- 输出结果为 “Lilei 40 2000”,其中 name 成员输出为 “Lilei”,age 成员输出为 40,pay 成员输出为 2000。
Lilei 40 2000
05. 整型值(%4d
进行格式化)
#include <stdio.h>
int f(int a) {
int b = 4; // 声明整型变量 b,赋值为 4
static int c = 4; // 声明静态整型变量 c,赋值为 4
b++; // b 自增 1
c++; // c 自增 1
return (a + b + c); // 返回 a、b、c 三个变量的和
}
int main() {
int a = 4; // 声明整型变量 a,赋值为 4
int i;
for (i = 0; i < 3; i++) {
printf("%4d", f(a)); // 输出函数 f 的返回值,并按照 %4d 进行格式化
}
return 0;
}
【代码详解】
- 这段代码的功能是定义了一个返回整型值的函数
f
和一个主函数main
。- 首先,包含了
<stdio.h>
头文件,用于输入输出。- 定义了一个返回整型值的函数
f
,接受一个整型参数a
。- 在函数
f
中,声明了一个整型变量b
,赋值为 4,表示局部变量。还声明了一个静态整型变量c
,也赋值为 4,表示静态变量。注意,静态变量会在每次函数调用后保持其值不变。静态变量的生命周期会持续到程序的结束。b++
表示将b
自增 1,相当于b = b + 1
。c++
表示将c
自增 1,相当于c = c + 1
。- 最后,函数
f
返回a + b + c
的值。- 在
main
函数中,声明了一个整型变量a
,赋值为 4。另外声明了一个整型变量i
。- 使用 for 循环,将
i
从 0 递增到 2(共执行 3 次循环)。- 在循环内部,通过
printf
函数输出调用函数f
的返回值,并按照%4d
进行格式化,保证输出结果占据 4 个字符的宽度。%4d
是格式化字符串,表示输出一个整数占据 4 个字符的宽度,不足的地方用空格填充。【执行结果】
在运行程序时,输出结果为:14 15 16。这是因为循环执行了 3 次,每次调用函数
f(a)
的返回值都不同。具体地:- 第一次调用时,函数
f(a)
返回结果为 14。- 第二次调用时,函数
f(a)
返回结果为 15。- 第三次调用时,函数
f(a)
返回结果为 16。由于使用了
%4d
的格式化字符串,输出结果被限制在 4 个字符的宽度内,所以结果只显示了后两位数字。14 15 16
06. 求三个数中的最大值和最小值
#include <stdio.h>
void maxmin(int a, int b, int c, int* m, int* n)
{
int t; // 用于交换变量值的临时变量
// 比较 a 和 b 的大小,进行交换
if (a < b)
{
t = a; // 保存 a 的值
a = b; // 将 b 的值赋给 a
b = t; // 将之前保存的 a 的值赋给 b
}
// 比较 a 和 c 的大小,进行交换
if (a < c)
{
t = a; // 保存 a 的值
a = c; // 将 c 的值赋给 a
c = t; // 将之前保存的 a 的值赋给 c
}
// 比较 b 和 c 的大小,进行交换
if (b < c)
{
t = b; // 保存 b 的值
b = c; // 将 c 的值赋给 b
c = t; // 将之前保存的 b 的值赋给 c
}
*m = a; // 将最大值赋给 m
*n = c; // 将最小值赋给 n
}
int main()
{
int a, b, c, max, min;
printf("Please input a b c:\n");
scanf_s("%d %d %d", &a, &b, &c);
maxmin(a, b, c, &max, &min); // 将 max 和 min 作为指针传入函数
printf("a = %d, b = %d, c = %d\n", a, b, c);
printf("max = %d, min = %d\n", max, min);
return 0;
}
【代码详解】
这段代码用于求给定三个数中的最大值和最小值。
- 标准输入输出的头文件:
#include <stdio.h>
- 这是一个函数定义,函数名为
maxmin
。它接受四个参数:a
、b
、c
是要比较的三个数,m
和n
是指向存储最大值和最小值的变量的指针:void maxmin(int a, int b, int c, int* m, int* n)
- 定义了一个整型变量
t
,用于辅助交换变量的值:int t; // 用于交换变量值的临时变量
- 这是一个条件语句,用于比较
a
和b
的值。如果a
小于b
,则交换它们的值,即将 a
的值赋给 t
,将 b
的值赋给 a
,将 t
的值赋给b
。if (a < b) { t = a; a = b; b = t; }
- 同样的逻辑被应用在下面两个条件语句中,分别对
a
、c
和 b
、c
进行比较和交换,这两行将最大值赋给指针m
所指向的变量,将最小值赋给指针 n
所指向的变量:*m = a; // 将最大值赋给m *n = c; // 将最小值赋给n
- 这是程序的主函数,程序从这里开始执行:
int main()
- 定义了变量
a
、b
、c
、max
和min
,用于存储用户输入的数以及最大值和最小值;这两行代码用于向用户输出提示信息,并使用scanf_s
函数从用户输入中获取三个整数值,分别存储在 a
、b
和 c
中:printf("Please input a b c:\n"); scanf_s("%d %d %d", &a, &b, &c);
- 调用了
maxmin
函数,并传递了 a
、b
、c
以及 max
和 min
的地址作为参数。这样,在 maxmin
函数内部对 max
和 min
的修改将反映在主函数中maxmin(a, b, c, &max, &min); // 将max和min作为指针传入函数
- 用于输出结果,分别显示用户输入的三个数以及其中的最大值和最小值:
printf("a = %d, b = %d, c = %d\n", a, b, c); printf("max = %d, min = %d\n", max, min);
- 表示程序正常结束,返回值为 0:
return 0;
【执行结果】
- 示例键盘输入任意 3 个整数:88 50 100
Please input a b c: 88 50 100 a =88, b = 50, c = 100 max=100, min = 50
07. 同一字母次数统计
【题目】统计从键盘输入的字符($ 作为结束)中每个小写英文字母出现的个数,
n[0]、n[1]、···、n[25] 分别存放小写字母 a、b、···、z
#include "stdio.h"
int main()
{
int n[26] = {0}, k;
char c;
while ((c = getchar()) != '$') // 使用 getchar() 函数从键盘读取字符,将其赋给变量 c。当读取到字符'$'时,循环结束
{
if (c >= 'a' && c <= 'z') // 判断输入字符是否为小写字母
{
n[c - 'a'] += 1; // 根据字符c减去字符'a'的 ASCII 码值,作为索引更新对应的 n[] 元素值
}
}
for (k = 0; k < 26; k++) // 循环遍历 n[] 数组,输出统计结果
{
printf("%c: %d\n", k + 'a', n[k]);
}
return 0;
}
【代码详解】
这段代码的功能是统计从键盘输入的字符(以
$
作为结束标志)中每个小写英文字母的出现次数,并输出统计结果。首先,在
main
函数中,我们声明了一个整型数组 n[26]
用于存储每个小写英文字母出现的个数。初始值都被设置为 0。然后,使用
while
循环来读取字符,每次从键盘读取一个字符并将其赋值给变量 c
。在循环中,判断当前读取的字符 c
是否为$
,如果是则循环结束。对于每个读取到的字符
c
,我们检查它是否是小写字母。如果是,就通过将字符 c
减去字符 'a'
的 ASCII 码值,得到一个索引值,然后将对应的 n
数组元素加 1,以统计出现次数。最后,使用
for
循环遍历数组 n[]
,并使用 printf
函数输出统计结果,格式为每个小写字母及其出现次数。【执行结果】
- 示例键盘输入任意大小写字母,不限输入字数,支持换行,以 $ 作为结束符,回车:
GKghuhGihibjgviy giuiuEYUGhgjjj$
- 执行结果:
GKghuhGihibjgviy giuiuEYUGhgjjj$ a: 0 b: 1 c: 0 d: 0 e: 0 f: 0 g: 4 h: 4 i: 5 j: 4 k: 0 l: 0 m: 0 n: 0 o: 0 p: 0 q: 0 r: 0 s: 0 t: 0 u: 3 v: 1 w: 0 x: 0 y: 1 z: 0
08. 字符串回文判断
【题目】 从键盘输入一个字符串,判断其是否是回文。
- 若是输出 “Yes”,否则输出 “No”。
- 回文是指正向、反向的拼写都一样。
【示例】
- ABCBA、aaaa 等是回文
- china、ABC 等不是回文
#include "stdio.h"
#include "string.h"
int main()
{
char string[80];
int i, j, n;
fgets(string, sizeof(string), stdin); // 从标准输入stdin读取一行字符串
n = strlen(string) - 1; // 统计字符串的长度,减去换行符'\n'
j = n - 1; // j指向字符串末尾(最后一个字符的位置)
for (i = 0; i < j; i++, j--)
{
if (string[i] != string[j]) // 判断当前字符和对称位置的字符是否相等
{
break;
}
}
if (i >= j) // 如果i大于等于j,则说明整个字符串都符合回文的特性
{
printf("Yes\n"); // 输出"Yes"
}
else
{
printf("No\n"); // 输出"No"
}
return 0;
}
【代码详解】
- 这段代码的功能是判断从标准输入中读取的一行字符串是否是回文。
- 首先,我们声明了一个大小为 80 的字符数组
string
,用于存储输入的字符串。- 接下来,使用
fgets
函数从标准输入 stdin 读取一行字符串,并将其存储在string
数组中。sizeof(string)
表示string
数组的大小,保证输入的字符串不会溢出。fgets
函数会读取一行字符串,包括换行符 ’\n’,并将其存储在 string
中。- 然后,我们使用
strlen
函数计算string
字符串的长度,需要注意的是要减去末尾的换行符 ’\n’,因此实际的字符串长度是strlen(string) - 1
。我们将其赋值给变量n
。- 接下来,我们将
j
初始化为n - 1
,即指向字符串末尾的位置(最后一个字符的位置)。- 然后,我们使用
for
循环和两个索引变量i
和j
,从字符串的首尾开始同时向中间移动。在循环中,我们比较当前索引位置i
和对称位置j
上的字符是否相等。如果发现不相等的情况,说明字符串不是回文,我们就退出循环。- 最后,我们使用条件语句进行判断。如果
i
大于等于j
,表示我们已经遍历了整个字符串并且没有发现不相等的字符,即该字符串是回文。在这种情况下,我们输出 "Yes";否则,我们输出 "No"。- 通过这个程序,我们可以判断从标准输入读取的一行字符串是否是回文。它遍历字符串并比较对称位置上的字符,只要有一个字符不相等,就可以确定字符串不是回文。如果所有字符都相等,则字符串是回文。
【执行结果】
- [ 示例 1 ]
- 示例键盘输入任意字符串,回车:
ABCBA
- 执行结果:
Yes
- [ 示例 2 ]
- 示例键盘输入任意字符串,回车:
china
- 执行结果:
No
09. 闰年判断
【题目】输入年份 year,如果是闰年,则输出 “ Yes!”,否则输出“ No!”。
【说明】每 400 年有 97 个闰年,即在 4 的倍数年份中除去第 100、200、300 三个年份
#include <stdio.h>
int main() {
int year;
printf("请输入年份: ");
scanf_s("%d", &year); // 使用 scanf_s 函数代替 scanf,输入年份
if (year % 400 == 0) {
printf("Yes!"); // 能被 400 整除的年份是闰年
} else if (year % 100 == 0) {
printf("No!"); // 能被 100 整除但不能被 400 整除的年份不是闰年
} else if (year % 4 == 0) {
printf("Yes!"); // 能被4整除但不能被 100 整除的年份是闰年
} else {
printf("No!"); // 其他年份不是闰年
}
return 0;
}
【代码详解】
这段代码用于判断输入的年份是否为闰年。
#include <stdio.h>
:包含了标准输入/输出库的头文件。
int main() { ... }
:main
函数是程序的入口点。
int year;
:声明一个整型变量year
,用于存储用户输入的年份。
printf("请输入年份: ");
:打印提示信息,要求用户输入年份。
scanf_s("%d", &year);
:使用scanf_s
函数读取用户输入的年份,并将其存储在变量year
中。
if (year % 400 == 0) { ... }
:如果年份能够被 400 整除,即year % 400
的结果为0,执行下面的代码块。打印"Yes!"表示是闰年。
else if (year % 100 == 0) { ... }
:如果年份不能被 400 整除,但能被 100 整除,即year % 100
的结果为0,执行下面的代码块。打印"No!"表示不是闰年。
else if (year % 4 == 0) { ... }
:如果年份不能被 400 和 100 整除,但能被 4 整除,即year % 4
的结果为0,执行下面的代码块。打印"Yes!"表示是闰年。
else { ... }
:如果年份不能被 400、100 和 4 整除,执行下面的代码块。打印"No!"表示不是闰年。
return 0;
:返回 0,表示程序正常结束。【执行结果】
- 示例键盘输入任意年份,整数,回车:
请输入年份: 2024 Yes!
10. 交换两个双精度数
【题目】在主函数中定义两个双精度变量 x,y,并输入。利用函数交换两个双精度数 x,y,并且要求函数的参数是指针类型。
#include <stdio.h>
// 函数声明:交换两个双精度数的值
void swap(double* num1, double* num2);
int main() {
double x, y;
// 输入两个双精度数
printf("请输入两个双精度数:\n");
scanf_s("%lf %lf", &x, &y); // 输入两个双精度数的值
printf("交换前的值:x = %.2lf, y = %.2lf\n", x, y); // 输出交换前的值
// 调用交换函数,传入指针参数
swap(&x, &y); // 传入两个双精度数的地址
printf("交换后的值:x = %.2lf, y = %.2lf\n", x, y); // 输出交换后的值
return 0;
}
// 函数定义:交换两个双精度数的值
void swap(double* num1, double* num2) {
double temp;
// 使用临时变量交换两个双精度数的值
temp = *num1;
*num1 = *num2;
*num2 = temp;
}
【代码详解】
上述代码通过指针参数来交换两个双精度数的值。
swap
函数的定义使用指针num1
和num2
作为参数,通过临时变量实现了交换的功能。在
main
函数中,首先输入两个双精度数x
和y
,然后调用swap
函数来交换它们的值,最后打印交换前后的结果。上述的代码利用函数交换了两个双精度数
x
和y
,并且函数的参数类型是指针。这是通过将双精度数的地址传递给swap
函数来实现的。函数声明和定义中的参数类型double*
表示指向双精度数的指针。在
swap
函数中,通过使用临时变量和指针操作,交换了两个双精度数的值。通过传递x
和y
的地址(即指针)给swap
函数的参数num1
和num2
,我们可以在函数内部通过指针来修改这些变量的值。这种通过指针参数来实现值交换的方式可以有效地修改变量的值,而不需要返回任何值。这在需要修改传入变量的值时非常有用。
【执行结果】
示例键盘输入任意 2 个双精度数字,空格隔开,回车:
5.67 9.13 交换前的值:x = 5.67, y = 9.13 交换后的值:x = 9.13, y = 5.67