所有的语句类型:

  1. 表达式语句 (最常见)
  2. 选择语句: if, switch
  3. 重复语句: while, do-while, for
  4. 跳转语句: break, continue, goto, return
  5. 复合语句: 把几条语句组合成一条语句
  6. 空语句: 不执行任何操作的语句

5.1 逻辑表达式

C语言不区分bool类型:

  • 真 == 非零
  • 假 == 0

5.1.1 关系运算符 (relational operator)

特性说明代码
关系运算符类型<, >, <=, >=
默认值真值为1, 假值为0
允许整数与浮点数比较1 < 2.5
优先级: 关系 < 算数
结合性: 左结合
i < j < k 相当于 (i < j) < k其中(i < j), 真产生1, 假产生0

5.1.2 判等运算符 (equality operator)

特性说明代码
判等运算符类型==, !=
优先级: 判等 < 关系 < 算数
结合性: 左结合性

5.1.3 逻辑运算符 (logical operator)

特性说明代码
逻辑运算符类型!, &&, ||
逻辑运算符的数值1. 表达式为0, !结果为1
2. ab均为非零值, 则a && b结果为1
3. ab任意一个为非零, 则a || b结果为1
&&||的短路特性1. 优先级计算左操作数的值
2. 如果表达式可以仅由左操作数的值推断出来, 将不计算右操作数的值
3. 与的左为假
4. 或的左为真
(i != 0) && (j / i > 0)
1. 如果i为0, 则无需计算j / i, 虽然有除零错误, 但是不会执行
2. 如果i不为0, 则需要计算后续表达式的值, 无除零错误
优先级:
1. !与一元正负号优先级相同
2. || < && < 判等 < 关系 < 算数
结合性: 左结合性

5.2 if语句

if (表达式)
    语句

5.2.1 复合语句

if (表达式) { // 花括号整体就是复合语句
    多条语句
}

5.2.2 else子句

if (i > j)
    max = i;
else
    max = j;

// 嵌套if
// if-else本质上是单一语句, 所以外层if-else无需加上花括号来表示复合语句.
// 扩展: if只能接受一条语句, 加上花括号后整体为一条复合语句

if (i > j)
    if (i > k)
        max = i;
    else
        max = k;
else
    if (j > k)
        max = j;
    else
        max = k;

5.2.3 级联式if语句 (不是特殊的语句)

if (n < 0)
    printf("n is less than 0.\n");
else
    if (n == 0)
        printf("n is equal to 0.\n");
    else
        printf("n is greater than 0.\n");

// 级联式if本质: 将else下的if语句与自身对齐, 并丢掉缩进

if (n < 0)
    printf("n is less than 0.\n");
else if (n == 0)
    printf("n is equal to 0.\n");
else
    printf("n is greater than 0.\n");

(程序) 计算股票经纪人的佣金

broker.c

#include <stdio.h>

int main(void) {
    float commission, value;

    printf("Enter value of trade: ");
    scanf("%f", &value);

    if (value < 2500.00f)
        commission = 30.00f + 0.017f * value;
    else if (value < 6250.00f)
        commission = 56.00f + .0066f * value;
    else if (value < 20000.00f)
        commission = 76.00f + .0034f * value;
    else if (value < 50000.00f)
        commission = 100.00f + .0022f * value;
    else if (value < 500000.00f)
        commission = 155.00f + 0.0011f * value;
    else   
        commission = 255.00f + .0009f * value;
    
    if (commission < 39.00f)
        commission = 39.00f;
    
    printf("Commission: $%.2f\n", commission);

    return 0;
}

5.2.4 "悬空else"的问题

思考: else子句属于哪一个if?

C标准: else子句属于离它最近的, 且还未与其他else匹配的if语句.

当前实例中的else属于内层if, 与其缩进没有任何关系.

if (y != 0)
    if (x != 0)
        result = x / y;
else
    printf("Error: y is equal to 0\n");

// 实际逻辑

if (y != 0)
    if (x != 0)
        result = x / y;
    else
        printf("Error: y is equal to 0\n"); // 错误

// 正确逻辑的书写方式
if (y != 0) {
    if (x != 0)
        result = x / y;
} else
    printf("Error: y is equal to 0\n");

5.2.5 条件运算符 (conditional operator)

  • 条件运算符有三个表达式, 是三元运算符 (ternary operator).
  • 使用场景: return语句, 宏定义
表达式1 ? 表达式2 : 表达式3

int i, j, k;
i = 1;
j = 2;
k = i > j ? i : j;
k = (i >= 0 ? i : 0) + j;

5.2.6 C89中的布尔值

// 声明一个int变量, 赋值为0或者1
// 声明TRUE和FALSE常量

#define TRUE 1
#define FALSE 0

int flag;
flag = TRUE;
flag = FALSE;

5.2.7 C99中的布尔值 (建议使用stdbool.h包)

// 方法一: C99提供_Bool类型
// 是一个无符号整型, 且只能赋值为0或者1
// _Bool的算数运算合法 (但是不建议)

// 方法二: 包含<stdbool.h>

bool flag = true;

...

flag = false;

5.3 switch语句

特性说明代码
switch功能更加简洁, 开销更低的级联式if语句
switch表达式只能是整形表达式, 因为C语言中可以将char作为整型处理, 所以可以使用字符判定, 但是不能使用浮点数和字符串
语句case中的多条语句无需使用花括号括起来
switch对分支顺序没有要求特别是default不一定要放置在最后
多分支->单组语句case 4:
case 1: 语句
default可以不存在
break作用switch运行特性: 基于跳转的顺序执行, 跳转完成后执行case以下所有的语句

break可以起到分隔的作用
switch (表达式) {
    case 常量表达式: 语句
    ...
    case 常量表达式: 语句
    default: 语句
}

(程序) date

#include <stdio.h>

int main(void) {
    int month, day, year;

    printf("Enter date (mm/dd/y): ");
    scanf("%d /%d /%d", &month, &day, &year);

    printf("Dated this %d", day);

    switch (day) {
        case 1: case 21: case 31:
        printf("st"); break;

        case 2: case 22:
        printf("nd"); break;

        case 3: case 23: 
            printf("rd"); break;
        default: printf("th"); break;
    }

    printf(" day of ");

    switch (month) {
        case 1: printf("January"); break;
        case 2: printf("February"); break;
        case 3: printf("March"); break;
        case 4: printf("April"); break;
        case 5: printf("May"); break;
        case 6: printf("June"); break;
        case 7: printf("July"); break;
        case 8: printf("August"); break;
        case 9: printf("September"); break;
        case 10: printf("October"); break;
        case 11: printf("November"); break;
        case 12: printf("December"); break;
    }

    printf(", 20%.2d.\n", year);

    return 0;
}

练习题

答案链接:

  • http://knking.com/books/c2/answers/c5.html
  • https://github.com/williamgherman/c-solutions/tree/master/05

记号说明:

  • 加粗(错误): 表示错误的答案或者遗漏的知识点
  • 在代码块中(错误): 表示错误的答案

Practice1

列代码片段给出了关系运算符和判等运算符的示例。假设i 、 j 和k 都是int型变量,请给出每道题的输出结果。

// 1

i = 2; j = 3; 
k = i * j == 6; 
printf("%d", k);

// 2

i = 5; j = 10; k = 1; 
printf("%d", k > i < j);

// 3

i = 3; j = 2; k = 1; 
printf("%d", i < j == j < k);

// 4

i = 3; j = 4; k = 5; 
printf("%d", i % j + i < k);

回答:

题1

k = ((i * j) == 6);
k = (6 == 6);
k = 1;
1

题2
((k > i) < j)
(0 < j)
(0 < 10)
1

题3
((i < j) == (j < k))
(0 == 0)
1

题4
(((i % j) + i) < k)
((3 + 3) < 5)
(6 < 5)
0

Practice2

下列代码片段给出了逻辑运算符的示例。假设i 、j 和k 都是 int 型变量,请给出每道题的输出结果。

// 1

i = 10; j = 5; 
printf("%d", !i < j);

// 2

i = 2; j = 1; 
printf("%d", !!i + !j);

// 3

i = 5; j = 0; k = -5; 
printf("%d", i && j || k);

// 4

i = 1; j = 2; k = 3; 
printf("%d", i < j || k);

回答:

Question1
(!i) < j
(!10) < 5
0 < 5
1

Question2
(!!i) + (!j)
(!(!i)) + (!j)
(!(!2)) + (!1)
(!0) + 0
1 + 0
1

Question3
((i && j) || k)
((5 && 0) || -5)
(0 || -5)
1

Question4
(i < j) || k
((i < j) || k)
((1 < 2) || 3)
(1 || 3)
1

Practice3 *

下列代码片段给出了逻辑表达式的短路行为的示例。假设i 、 j 和k 都是int型变量,请给出每道题的输出结果。

// 1

i = 3; j = 4; k = 5; 
printf("%d", i < j || ++j < k); 
printf("%d %d %d", i, j, k);

// 2

i = 7; j = 8; k = 9; 
printf("%d", i - 7 && j++ < k); 
printf("%d %d %d", i, j, k);

// 3

i = 7; j = 8; k = 9; 
printf("%d", (i = j) || (j = k)); 
printf("%d %d %d", i, j, k);

// 4

i = 1; j = 1; k = 1; 
printf("%d", ++i || ++j && ++k); 
printf("%d %d %d", i, j, k);
Question1
i < j || ++j < k
(i < j) || ((++j) < k) // (++j)的优先级是最高的, 所以先执行
(i < j) || (5 < 5)
(3 < 5) || (5 < 5)
1 || 0
1 3 5 5 (错误)

订正: 
1 3 4 5 (短路特性有两个, 一个是&&左为假, 另一个是||左为真)

Question2
i - 7 && j++ < k
(i - 7) && ((j++) < k) // 问题: 括号是否是序列点
(7 - 7) && (8 < 9) // 序列点决定j++是8还是9, 但是因为前面i一定是7所以最终结果都是0
0 7 9 9 (错误)

订正: 
0 7 8 9 (由于&&的短路特性, 所以j++ < k不会执行) 
序列点: &&, ||, 条件运算符, 逗号, 函数调用, (while, for中的条件检查), return

Question3
(i = j) || (j = k) // 注意是赋值计算, 整体表达式的值等于右侧表达式
i = 8 || j = 9 // 优先执行左侧表达式
8 || 9
1 8 9 9 (错误)

订正: 
1 8 8 9 (左侧为真, 右侧不执行)

Question4
++i || ++j && ++k
(++i || (++j && ++k))
(++i || (2 & 2))
(2 || 1)
1 2 2 2 (错误)

订正: 
1 2 1 1 (左侧为真, 右侧不执行)

Practice4 *

编写一个表达式,要求这个表达式根据i 是否小于、等于或大于j ,分别取值为-1、0或+1。

i < j ? -1 : (i > j ? 1 : 0)

答案:

(i > j) - (i < j);

Practice5 *

下面的if 语句在C语言中是否合法?

如果合法,那么当n 等于0时语句做些什么?

if (n >= 1 <= 10) 
    printf ("n is between 1 and 10\n");

回答: 合法

0 >= 1 <= 10
((0 >= 1) <= 10)
(0 <= 10)
1
if判断为真, 会打印
n is between 1 and 10

Practice6 *

下面的if 语句在C语言中是否合法?

如果合法,那么当n 等于5时语句做些什么?

if (n == 1 - 10) 
    printf ("n is between 1 and 10\n");

回答: 合法

n == 1 - 10
n == -9
5 == -9
0
不会打印字符串

Practice7

如果i的值为17,下面的语句显示的结果是什么?如果i 的值为-17,下面的语句显示的结果又是什么?

printf ("%d\n", i >= 0 ? i : -i);

回答:

17的情况
17 >= 0 ? i : -i
i
17

-17的情况
-17 >= 0 ? i : -i
-i
17

Practice8

下面的if语句不需要这么复杂,请尽可能地加以简化。

if (age >= 13) 
    if (age <= 19) 
        teenager = true; 
    else 
        teenager = false; 
else if (age < 13) 
    teenager = false;
if (age >= 13 && age <= 19)
    teenager = true;
else
    teenager = false;

答案:

teenager = age >= 13 && age <= 19;

Practice9

下面两个if 语句是否等价?如果不等价,为什么?

if (score >= 90)
    printf("A");
else if (score >= 80)
    printf("B");
else if (score >= 70)
    printf("C");
else if (score >= 60)
    printf("D");
else
    printf("F");
if (score < 60)
    printf("F");
else if (score < 70)
    printf("D");
else if (score < 80)
    printf("C");
else if (score < 90)
    printf("B");
else
    printf("A");

回答: 等价

Practice10 *

下面的代码片段的输出结果是什么?(假设i 是整型变量。)

i = 1; 
switch (i % 3) { 
    case 0: printf("zero"); 
    case 1: printf("one"); 
    case 2: printf("two"); 
}
onetwo

Practice11

下面的表格给出了美国佐治亚州的电话区号以及每个地区最大的城市。

编写一个switch 语句,其控制表达式是变量area_code 。

  • 如果area_code 的值在表中,switch 语句打印出相应的城市名;
  • 否则switch 语句显示消息"Area code not recognized "。

使用5.3节讨论的方法,使switch 语句尽可能简单。

区号主要城市
229Albany
404Atlanta
470Atlanta
478Macon
678Atlanta
706Columbus
762Columbus
770Atlanta
912Savannah

回答:

#include <stdio.h>

int main(void) {
    int area_code;

    printf("Enter area code: ");
    scanf("%d", &area_code);

    switch(area_code) {
        case 299: printf("Albany\n"); break;
        case 404: 
        case 470: 
        case 678: 
        case 770: printf("Atlanta\n"); break;
        case 478: printf("Macon\n"); break;
        case 706: 
        case 762: printf("Columbus\n"); break;
        case 912: printf("Savannah\n"); break;
        default: printf("Area code not recognized\n"); break;
    }

    return 0;
}

代码题

code1-num

编写一个程序,确定一个数的位数:

假设输入的数最多不超过4位。

提示 :利用if 语句进行数的判定。例如,

  • 如果数在0到9之间,那么位数为1;

  • 如果数在10到99之间,那么位数为2。

    Enter a number: 374

    The number 374 has 3 digits

代码如下

#include <stdio.h>

int main(void) {
    int num, tmp;
    int digit = 0;

    printf("Enter a number: ");
    scanf("%d", &num);
    tmp = num;

    while (num % 10) {
        digit++;
        num /= 10;
    }
    printf("\nThe number %d has %d digits.\n", tmp, digit);
    
    return 0;
}

编译并运行

Enter a number: 274

The number 274 has 3 digits.

code2-time

编写一个程序,要求用户输入24小时制的时间,然后显示12小时制的格式:

注意不要把12:00显示成0:00。

Enter a 24-hour time: 21:11 
Equivalent 12-hour time: 9:11 PM

代码如下

#include <stdio.h>

int main(void) {
    int hour, minute;

    printf("Enter a 24-hour time: ");
    scanf("%d:%d", &hour, &minute);

    printf("\nEquivalent 12-hour time: ");
    if (hour <= 12) {
        printf("%d:%d AM\n", hour, minute);
    } else if (hour > 12) {
        printf("%d:%d PM\n", hour % 12, minute);
    }

    return 0;
}

编译并运行

Enter a 24-hour time: 12:11

Equivalent 12-hour time: 12:11 AM

code3-stock

修改5.2节的broker.c 程序,同时进行下面两种改变。

  1. 不再直接输入交易额,而是要求用户输入股票的数量和每股的价格。
  2. 增加语句用来计算经纪人竞争对手的佣金(少于2000股时佣金为每股33美元+3美分,2000股或更多股时佣金为每股33美元+2美分)。在显示原有经纪人佣金的同时,也显示出竞争对手的佣金。

代码如下

#include <stdio.h>

float brokerA(float value) {
    float commission;

    if (value < 2500.00f)
        commission = 30.00f + 0.017f * value;
    else if (value < 6250.00f)
        commission = 56.00f + .0066f * value;
    else if (value < 20000.00f)
        commission = 76.00f + .0034f * value;
    else if (value < 50000.00f)
        commission = 100.00f + .0022f * value;
    else if (value < 500000.00f)
        commission = 155.00f + 0.0011f * value;
    else   
        commission = 255.00f + .0009f * value;
    
    if (commission < 39.00f)
        commission = 39.00f;

    return commission;
}

float brokerB(int stock) {
    if (stock < 2000)
        return 33.00f + 0.03f * stock;
    else 
        return 33.00f + 0.02f * stock;
}

int main(void) {
    int stock;
    float price;

    printf("Enter the number of stocks: ");
    scanf("%d", &stock);
    printf("Enter the price: ");
    scanf("%f", &price);

    float interestA = brokerA(stock * price);
    float interestB = brokerB(stock);

    printf("\nA's interest = %f\n\n", interestA);
    printf("B's interest = %f\n", interestB);

    return 0;
}

编译并运行

Enter the number of stocks: 2000
Enter the price: 1

A's interest = 64.000000

B's interest = 73.000000

code4-wind

下面是用于测量风力的蒲福风力等级的简化版本。

编写一个程序,要求用户输入风速(海里/小时),然后显示相应的描述。

速率(海里 / 小时)描述
小于1Calm (无风)
1~3Light air (轻风)
4~27Breeze (微风)
28~47Gale (大风)
48~63Storm (暴风)
大于63Hurricane (飓风)

代码如下

#include <stdio.h>

int main(void) {
    int v;

    printf("Enter the speed of wind: ");
    scanf("%d", &v);

printf("\n");
    if (v < 1) 
        printf("Calm\n");
    else if (v < 3) 
        printf("Light air\n");
    else if (v < 27) 
        printf("Breeze\n");
    else if (v < 47) 
        printf("Gale\n");
    else if (v < 63) 
        printf("Storm\n");
    else 
        printf("Hurricane\n");

    return 0;
}

编译并运行

Enter the speed of wind: 23

Breeze

code5-state

在美国的某个州,单身居民需要担负下面表格列出的所得税。

编写一个程序,要求用户输入需纳税的收入,然后显示税金。

收入(美元)税金
未超过750收入的1%
750~2 2507.50美元加上超出750美元部分的2%
2 250~3 75037.50美元加上超出2 250美元部分的3%
3 750~5 25082.50美元加上超出3 750美元部分的4%
5 250~7 000142.50美元加上超出5 250美元部分的5%
超过7 000230.00美元加上超出7 000美元部分的6%

代码如下

#include <stdio.h>

int main(void) {
    float income, tax;

    printf("Enter the income: ");
    scanf("%f", &income);

    if (income < 750.0f) {
        tax = income * 0.01;
    } else if (income < 2250) {
        tax = 7.50f + (income - 750) * 0.02;
    } else if (income < 3750) {
        tax = 37.5f + (income - 2250) * 0.03;
    } else if (income < 5250) {
        tax = 82.50f + (income - 3750) * 0.04;
    } else if (income < 7000) {
        tax = 142.50f + (income - 5250) * 0.05;
    } else {
        tax = 230.00f + (income - 7000) * 0.06;
    }

    printf("\nThe tax = %.2f\n", tax);

    return 0;
}

编译并运行

Enter the income: 750

The tax = 7.50

code6-upc

修改4.1节的upc.c 程序,使其可以检测UPC的有效性。在用户输入UPC后,程序将显示VALID 或NOT VALID 。

代码如下

#include <stdio.h>

int main(void) {
    int d, i1, i2, i3, i4, i5, j1, j2, j3, j4, j5;
    int first_sum, second_sum, total, check;

    printf("Enter the first (single) digit: ");
    scanf("%1d", &d);
    printf("Enter first group of five digits: ");
    scanf("%1d%1d%1d%1d%1d", &i1, &i2, &i3, &i4, &i5);
    printf("Enter second group of five digits: ");
    scanf("%1d%1d%1d%1d%1d", &j1, &j2, &j3, &j4, &j5);
    printf("Enter check digit: ");
    scanf("%1d", &check);

    first_sum = d + i2 + i4 + j1 + j3 + j5;
    second_sum = i1 + i3 + i5 + j2 + j4;
    total = 3 * first_sum + second_sum;

    if (check == 9 - (total - 1) % 10)
        printf("VALID\n");
    else
        printf("NOT VALID\n");

    return 0;
}

编译并运行

Enter the first (single) digit: 0
Enter first group of five digits: 13800 
Enter second group of five digits: 15173
Enter check digit: 5
VALID

code7-max-min

编写一个程序,从用户输入的4个整数中找出最大值和最小值:

要求尽可能少用if 语句。 提示 :4条if语句就足够了

Enter four integers: 21 43 10 35 

Largest: 43 
Smallest: 10

代码如下

#include <stdio.h>

void exchange(int * a, int * b) {
    int tmp;
    tmp = *a;
    *a = *b;
    *b = tmp;
}

int main(void) {
    int arr[4];

    printf("Enter four integers: ");
    scanf("%d%d%d%d", arr, arr + 1, arr + 2, arr + 3);

    if (arr[0] > arr[3])
        exchange(arr, arr + 3);
    if (arr[1] > arr[2])
        exchange(arr + 1, arr + 2);
    if (arr[0] > arr[1])
        exchange(arr, arr + 1);
    if (arr[2] > arr[3])
        exchange(arr + 2, arr + 3);

    printf("\nLargest: %d\n", arr[3]);
    printf("Smallest: %d\n", arr[0]);

    return 0;
}

编译并运行

Enter four integers: 21 43 10 35

Largest: 43
Smallest: 10

code8-city

下面的表格给出了一个城市到另一个城市的每日航班信息。

编写一个程序,要求用户输入一个时间(用24小时制的时分表示)。程序选择起飞时间与用户输入最接近的航班,显示出相应的起飞时间和抵达时间。

提示 :把输入用从午夜开始的分钟数表示。将这个时间与表格里也用从午夜开始的分钟数表示的起飞时间相比。例如,13:15从午夜开始是13×60+15 = 795分钟,与下午12:47(从午夜开始是767分钟) 最接近。

Enter a 24-hour time: 13:15 

Closest departure time is 12:47 p.m., arriving at 3:00 p.m.
编号起飞时间抵达时间
08:00 a.m.10:16 a.m.
19:43 a.m.11:52 a.m.
211:19 a.m.1:31 p.m.
312:47 p.m.3:00 p.m.
42:00 p.m.4:08 p.m.
53:45 p.m.5:55 p.m.
67:00 p.m.9:20 p.m.
79:45 p.m.11:58 p.m.

代码如下

#include <stdio.h>
/*
* 核心思想: 简化比较过程, 全部转化为类似时间戳的格式, 单位为分钟
* 比较: 使用时间戳比较
* 打印: 转换为12小时制
*/

// 24小时->时间戳
int timestamp(int hour, int minute) {
    return hour * 60 + minute;
}

int main(void) {
    int hour, minute, option;
    int Dhour[8] = {8, 9, 11, 12, 2, 3, 7, 9};
    int Dminute[8] = {0, 43, 19, 47, 0, 45, 0, 45};
    int Dflag[8] = {0, 0, 0, 1, 1, 1, 1, 1};
    int Ehour[8] = {10, 11, 1, 3, 4, 5, 8, 11};
    int Eminute[8] = {16, 52, 31, 0, 8, 55, 20, 58};
    int Eflag[8] = {0, 0, 1, 1, 1, 1, 1, 1};
    char* arr[2] = {"a.m.", "p.m."};

    printf("Enter a 24-hour time: ");
    scanf("%d:%d", &hour, &minute);

    int ts = timestamp(hour, minute);

    if (ts < timestamp(8, 0)) {
        if (timestamp(24, 0) - (timestamp(21, 45) - ts) < (timestamp(8, 0) - ts))
            option = 7;
        else
            option = 0;
    } else if (ts < timestamp(9, 43)) {
        if (ts - timestamp(8, 0) < timestamp(9, 43) - ts)
            option = 0;
        else
            option = 1;
    } else if (ts < timestamp(11, 19)) {
        if (ts - timestamp(9, 43) < timestamp(11, 19) - ts)
            option = 1;
        else
            option = 2;
    } else if (ts < timestamp(12, 47)) {
        if (ts - timestamp(11, 19) < timestamp(12, 47) - ts)
            option = 2;
        else 
            option = 3;
    } else if (ts < timestamp(14, 00)) {
        if (ts - timestamp(12, 47) < timestamp(14, 00) - ts)
            option = 3;
        else
            option = 4;
    } else if (ts < timestamp(15, 45)) {
        if (ts - timestamp(14, 00) < timestamp(15, 45) - ts)
            option = 4;
        else
            option = 5;
    } else if (ts < timestamp(19, 00)) {
        if (ts - timestamp(15, 45) < timestamp(19, 00) - ts)
            option = 5;
        else
            option = 6;
    } else if (ts < timestamp(21, 45)) {
        if (ts - timestamp(19, 00) < timestamp(21, 45) - ts)
            option = 6;
        else
            option = 7;
    }  else {
        option = 7;
    }

    printf("\nClosest departure time is %.2d:%.2d %s, arriving at %.2d:%.2d %s\n", Dhour[option], Dminute[option], arr[Dflag[option]], Ehour[option], Eminute[option], arr[Eflag[option]]);

    return 0;
}

编译并运行

Enter a 24-hour time: 13:15

Closest departure time is 12:47 p.m., arriving at 03:00 p.m.

code9-date

编写一个程序,提示用户输入两个日期,然后显示哪一个日期更早:

Enter first date (mm/dd/yy): 3/6/08 

Enter second date (mm/dd/yy): 5/17/07 

5/17/07 is earlier than 3/6/08

代码如下

#include <stdio.h>

int main(void) {
    int Fyear, Fmonth, Fday, Syear, Smonth, Sday;
    int flag; // 0表示first, 1表示second

    printf("Enter first date (mm/dd/yy): ");
    scanf("%d/%d/%2d", &Fmonth, &Fday, &Fyear);
    
    printf("Enter second date (mm/dd/yy): ");
    scanf("%d/%d/%2d", &Smonth, &Sday, &Syear);

    if (Fyear > Syear) {
        flag = 1;
    } else if (Fyear < Syear) {
        flag = 0;
    } else {
        if (Fmonth > Smonth) {
            flag = 1;
        } else if (Fmonth < Smonth) {
            flag = 0;
        } else {
            if (Fday > Sday) {
                flag = 1;
            } else if (Fday < Sday) {
                flag = 0;
            } else {
                flag = 2;
            }
        }
    }

    switch (flag) {
        case 0: printf("\n%d/%d/%.2d is earlier than %d/%d/%.2d\n", Fmonth, Fday, Fyear, Smonth, Sday, Syear); break;
        case 1: printf("\n%d/%d/%.2d is earlier than %d/%d/%.2d\n", Smonth, Sday, Syear, Fmonth, Fday, Fyear); break;
        case 2: printf("\nSame\n");
    }

    return 0;
}

编译并运行

Enter first date (mm/dd/yy): 3/6/08
Enter second date (mm/dd/yy): 5/17/07

5/17/07 is earlier than 3/6/08

code10-grade

利用switch 语句编写一个程序,把用数字表示的成绩转化为字母表示的等级。

使用下面的等级评定规则:A为90~100,B为80~89,C为70~ 79,D为60~69,F为0~59。如果成绩高于100或低于0显示出错消息。

提示 :把成绩拆分成2个数字,然后使用switch 语句判定十位上的数字。

Enter numerical grade: 84 

Letter grade: B

代码如下

#include <stdio.h>

int main(void) {
    int grade;
    char mark;

    printf("Enter numerical grade: ");
    scanf("%d", &grade);

    grade /= 10;

    switch(grade) {
        case 10: case 9: mark = 'A'; break;
        case 8: mark = 'B'; break;
        case 7: mark = 'C'; break;
        case 6: mark = 'D'; break;
        default: mark = 'F';
    }

    printf("\nLetter grade: %c\n", mark);

    return 0;
}

编译并运行

Enter numerical grade: 84

Letter grade: B