This commit is contained in:
hairrrrr
2020-04-10 17:51:21 +08:00
parent ab2e829f6d
commit c5fdb003da
6 changed files with 192 additions and 0 deletions

View File

@@ -0,0 +1,45 @@
#include<stdio.h>
#define SIZE 5
void max_min(int a[], int len, int* max, int* min);
int main(void) {
int a[SIZE];
int max, min, i;
printf("Enter 5 numbers: ");
for (i = 0; i < SIZE; i++)
scanf("%d", &a[i]);
max_min(a, SIZE, &max, &min);
printf("Largest: %d\n", max);
printf("Smallest: %d\n", min);
return 0;
}
void max_min(int a[], int len, int* max, int* min) {
int i;
*max = *min = a[0];
for (i = 1; i < len; i++) {
// a[i] 如果比 *max 大 那肯定不会比 *min 小,反之也成立
if (a[i] > * max)
*max = a[i];
else if (a[i] < *min)
*min = a[i];
}
// 我自己写的,因为我这个算法每一次循环都要判断两次 if效率肯定不如上面的高
//for (i = 1; i < len; i++) {
// if (*max < a[i])
// *max = a[i];
// if (*min > a[i])
// *min = a[i];
//}
}

View File

@@ -0,0 +1,10 @@
#### 程序:找出数组中的最大元素和最小元素
与程序的交互如下:
```c
Enter 5 numbers:9 5 2 7 8
Largest: 9
Smallest: 2
```

View File

@@ -0,0 +1,16 @@
int read_line(char str[], int read_num) {
int ch, i = 0;
while ((ch = getchar()) != '\n' && ch != EOF) {
// i 大于 read_num 不执行操作,跳过后面的字符
if (i < read_num)
str[i++] = ch;
}
str[i] = '\0';
return i;
}
// ch 的类型是 int 而不是 char ,只是因为 getchar 把它读入的字符作为 int 类型的值返回。

View File

@@ -0,0 +1,25 @@
#### 3. 逐个字符读取字符串
因为对许多程序而言scanf 函数和 gets 函数都有风险而且不够灵活C 程序员经常会自己编写输入函数。通过每次读一个字符的方式读取字符串。
如果决定自己设计输入函数,那么需要考虑以下问题:
- 在开始存储字符串之前,函数应该跳过空白字符吗?
- 什么字符导致函数停止读取:换行符,任意空白字符,还是其他某种字符?需要存储这些字符还是忽略掉?
- 如果输入的字符串太长以至于无法存储,那么函数应该忽略额外的字符还是把它们留给下一次输入操作?
示例中,我们选择:不跳过空白字符,换行符结束,不存储换行符,忽略掉额外字符。
函数原型如下:
```c
int read_line(char str[], int read_num);
```
参数str 表示存储输入的数组read_num 表示读入字符的最大数量。
返回值:返回读入字符的个数。
使用 getchar 实现按字符读入。

View File

@@ -0,0 +1,20 @@
#### 程序:显示一个月的提醒列表
此程序会显示每一个月的每日提醒列表。用户需要输入一系列提醒,每条提醒都要有一个前缀来说明是那一个月中的那一天。当用户输入的是 0 而不是有效日期时,程序会显示出录入的全部提醒列表(按日期排序)。下面是会话示例:
```c
Enter day and reminder: 24 Suan's birstday
Enter day and reminder: 5 6:00 - Dinner with Marge
Enter day and reminder: 7 10:30 - Movie - "Chinatown"
Enter day and reminder: 0
Day Reminder:
5 6:00 - Dinner with Marge
7 10:30 - Movie - "Chinatown"
24 Suan's birstday
```
- 读入提醒使用我们写的 read_line 函数
- 将提醒存放在二维数组中,数组的每一行看作一个字符串。日期和提示消息都要放进去 。
- 日期我们用整型输入,然后转换为字符串放入二维数组的前面。
- 每次读入新的日期和提示消息后,将转为字符串的当前日期和二维数组每行前面表示日期的部分比较。如果当前日期字符串小于二维数组当前行的字符串,说明当前日期较小,应当插入到当前数组的行前一行。我们可以将二维数组从当前行到存放提示的最后一行每行依次向后移动一行,从而使得当前日期和提示可以插入二维数组的当前行。
- 打印二维数组

View File

@@ -0,0 +1,76 @@
#include<stdio.h>
#include<string.h>
#define MAX_REMIND 50
#define MSG_LEN 100
int read_line(char str[], int read_num);
int main(void) {
char reminders[MAX_REMIND][MSG_LEN + 3]; // 存放提示的数组
char day_str[3];//当前日期转换为字符串
char msg_str[MSG_LEN + 1]; //当前输入的提示消息
int day, num_remind = 0; // 日期和当前提示数
int i, j;
for (;;) {
if (num_remind == MAX_REMIND) {
printf("-- No space left --\n");
break;
}
printf("Enter day and reminder:");
scanf("%2d", &day); //每月的日期只用两个数表示即可,只读 2 个字段
if (day == 0)
break;
sprintf(day_str, "%2d", day); // 将 day 以 "%2d" 的格式写入 day_str 字符数组中。"%2d" 保证小于10的天占两位右对齐
read_line(msg_str, MSG_LEN);
// 寻找当前输入的提示应该放到提示数组的那个位置
for (i = 0; i < num_remind; i++) {
// 说明当前输入的日期应该排在此行前
if(strcmp(day_str, reminders[i]) < 0)
break;
}
// 将当前输入的提示插入到正确的位置
for (j = num_remind; j > i; j--) {
strcpy(reminders[j], reminders[j - 1]);
}
strcpy(reminders[i], day_str);
strcat(reminders[i], msg_str);// 刚好将 day_str 复制进去的空字符覆盖掉了
num_remind++;
}
printf("Day Reminder: \n");
for (i = 0; i < num_remind; i++)
printf("%s\n", reminders[i]);
return 0;
}
int read_line(char str[], int read_num) {
int ch, count = 0;
while ((ch = getchar()) != '\n') {
if (count < read_num) {
str[count++] = ch;
}
}
str[count] = '\0';
return count;
}