C 语言基础 3 - 选择结构

引言

在高级语言编程(特别是C语言编程)中,使用选择结构(也称为条件结构或分支结构)是非常重要的,原因有以下几点:

  1. 实现不同的逻辑路径
    • 选择结构允许程序根据条件判断执行不同的代码路径。这可以使程序根据输入、状态或计算结果动态地调整其行为。
  2. 增强代码的可读性和可维护性
    • 通过使用条件语句(如if-else),可以将复杂的逻辑分解为更小的、易于理解和维护的部分。这有助于程序员更容易地阅读和修改代码。
  3. 控制程序流程
    • 选择结构是控制程序流程的基本工具之一。通过检查条件,程序可以决定何时执行特定的代码块,从而确保程序按照预期的方式运行。
  4. 提高程序的灵活性
    • 使用选择结构,可以编写更灵活的程序,这些程序能够根据不同的输入和条件执行不同的操作。这提高了程序的通用性和适应性。
  5. 错误处理和异常管理
    • 选择结构常用于错误处理和异常管理。例如,程序可以检查某个操作是否成功,并根据结果采取相应的措施(如重试、记录错误或终止程序)。
  6. 优化性能
    • 在某些情况下,使用选择结构可以避免不必要的计算或操作,从而提高程序的性能。例如,通过条件判断,可以跳过某些不必要的循环或函数调用。
  7. 实现复杂的逻辑
    • 许多复杂的逻辑操作(如排序、搜索和决策制定)都需要使用选择结构。这些结构使程序能够处理复杂的输入和条件,并产生相应的输出。

在C语言中,选择结构主要通过if语句、else if语句和else语句来实现。例如:

#include <stdio.h>

int main() {
    int number;
    printf("请输入一个数字: ");
    scanf("%d", &number);

    if (number > 0) {
        printf("这个数字是正数。\n");
    } else if (number < 0) {
        printf("这个数字是负数。\n");
    } else {
        printf("这个数字是零。\n");

选择结构

单分支结构——if 语句

  • 当表达式满足某个条件时,执行特定的语句块。其中表达式可以是任意表达式,语句可以是一条语句,也可以是多个语句。

执行过程:先判断表达式是否为真,如果为真,那么执行语句,如果为假,那么跳过语句执行后面的程序。

  • 示例:if (x > 0) { /* 执行语句块 */ }

  • 以下代码段的 执行结果是( )
#include<stdio.h>
int main()
{
    int  x=10,y=11,z=12;
    if( y> z )
        x=y; y=z; z=x;
    printf("x=%d y=%d z=%d\n", x, y, z );
    return 0;
}

A``x=11 y=12 z=11

<font style="color:#DF2A3F;">B</font>``x=10 y=12 z=10

C``x=11 y=11 z=10

D``x=10 y=10 z=12

解析:

  • 由于 if 语句的条件块没有用大括号 {} 包围,只有 x = y; 这一条语句属于 if 语句的条件块。
    • y = z;z = x; 这两条语句不属于 if 语句的条件块,而是顺序执行的语句。
    • 因此,最终输出的结果是 x=10 y=12 z=10

如果你希望 y = z;z = x; 也只在 if 语句的条件为真时执行,应该使用大括号 {} 将它们包围起来

#include<stdio.h>
int main()
{
    int x = 10, y = 11, z = 12;
  
    if (y > z) 
    {
        x = y;
        y = z;
        z = x;
    }
    printf("x=%d y=%d z=%d\n", x, y, z);
    return 0;
}

双分支结构——if…else 语句

  • 当满足某个表达式条件时执行一个语句块,否则执行另一个语句块。其中表达式可以是任意表达式,语句可以是一条语句,也可以是多个语句。

执行过程:先判断表达式是否为真,如果为真,那么执行语句块1,如果为假,那么执行语句块2,语句块1和语句块2 只能执行其中一个,是互斥的关系。

  • 示例:if (a > b) { /* 语句块1 */ } else { /* 语句块2 */ }

Delta = b * b - 4 * a * c;
if(Delta>=0)
{
	Delta = sqrt(Delta); 
	x1 = (-b + Delta) / (2 * a); 
    x2 = (-b - Delta) / (2 * a); 
    printf("方程有两个实数根为\nx1 = %.2f,\nx2 = %.2f\n", x1, x2); 
}
else{
	 printf("该方程式无实数解!\n");
}

多分支结构——多if…else 语句

  • 多 if…else if 实现:通过多个 if…else 语句判断多个条件。

其中表达式可以是任意表达式,语句可以是一条语句,也可以是多个语句。执行过程:先判断表达式1如果为真,那么执行语句1;否则判断表达式2如果为真,那么执行语句2;…否则判断表达式n如果为真,那么执行语句n;否则执行语句n+1。语句1、语句2…语句n和语句n+1 只能执行其中一个,表达式是互斥的关系。示例如下:

if(表达式1?){
     /* 语句块1 */
}
else if(表达式2?){
    /* 语句块2 */
}
else if(表达式3?){
    /* 语句块3 */
}
   
else if(表达式n?){
     /* 语句块n */
}
else{
     /* 语句块n+1 */
}

  • 【实例】从键盘上输入C语言课程成绩,按分数段评定出成绩的相应等级,90以上为“excellent”,80~89为“good”,70~79为“medium”,60~69为“pass”,59以下为“fail”。
    1. 定义一个实型变量score;
    2. 输入一个实数给score;
    3. 利用多分支结构判断条件,执行相应语句。
#include  "stdio.h"
void main()
{ 
    float score;
    scanf ( "%f " ,&score);
  
    if (score>=90)
        printf(" excellent\n ");
    else if (score>=80)
        printf(" good\n ");
    else if (score>=70) 
        printf("medium\n");
    else if (score>=60)
        printf("pass\n");
    else 
        printf(" fail\n");
}
  • if() else 的歧义性与语句块:
//现象示例
if ( a>0)
   x=0;
   y=1;
else 
   x=2;
   y=3;

//歧义:
y=1; 到底是不是if中的语句
y=3;到底是不是else中的

  • switch**…case 实现**:当判断条件为整数或字符时,使用 switch…case 语句更简洁、高效。示例:

    先计算表达式的值,然后依次与每一个case中的常量表达式的值进行比较,若有相等的,则从该case开始依次往下执行,若没有相等的值,则从default开始往下执行。执行过程中遇到break语句就跳出该swtich语句,否则一直按顺序继续执行下去,也就是会执行其它case 后面的语句, 直到遇到“}”符号才停止。

switch (表达式E)
{ 
    case 'A': /* 语句块1 */ break; 
    case 'B': /* 语句块2 */ break;
        ...
    case 'N': /* 语句块n */ break;
    default: /* 默认语句块 */ break; 
}

注意:

  • 每个 case 标签后的语句块通常以 break 语句结束,以防止“贯穿”到下一个 case 语句。如果省略 break,则程序会继续执行下一个 case 语句,直到遇到 break 或 switch 语句结束。
    • 表达式E和case后的常量表达式的值的类型应该一致,应该是**整型字符型**,不允许是浮点型。

  • 例如,安排周1到周日的活动
#include <stdio.h>
void main()
{
    int week;
    //while(1){ //无限循环用于测试代码
    printf("请用数字输入星期几week的值\n");
    scanf("%d",&week);
    if (week==1)
        printf("The first day of Workday\n");
    else if(week==2)
        printf("Workday\n");
    else if(week==3)
        printf("Workday\n");
    else if(week==4)
        printf("Workday\n");
    else if(week==5)
        printf("end of Workday\n");
    else if(week==6)
        printf("Weekend\n");
    else if(week==7)
        printf("Weekend\n");
    else
        printf("error\n");
    //}
}
#include <stdio.h>
void main()
{
    int week;
    //while(1){ //无限循环用于测试代码
    printf("请用数字输入星期几week的值\n");
    scanf("%d",&week);
    switch(week){
        case 1:
        case 2:
        case 3:
        case 4:
        case 5: printf("Workday\n"); break;
        case 6:
        case 7: printf("Weekend\n"); break;
        default: printf("error\n"); break;
        return;
    }
    //}
}
  • 如果用switch语句编程求分段函数的值,你可以想到几种表达式的构造方法?
f(x) =\begin{cases} x & \text x < 2 \\ x^2+1 & \text 2 \leq x < 6 \\ \sqrt{x+1} & \text 6 \leq x <10 \\ \frac{1}{x+1} & \text x \geq 10 \end{cases}
#include <stdio.h>
#include <math.h>
void main()
{
    int x;
    double y;
    while(1){
        printf("请输入x的值\n");
        scanf("%d",&x);
        if(x>=0)
            break;
        else
            printf("输入错误,请输入正确的x值\n");
    }
        switch(x)
        {
            case 0:
            case 1: y=(double)x;break;
            case 2:
            case 3:
            case 4:
            case 5: y=x*x+1.0;break;
            case 6:
            case 7:
            case 8:
            case 9: y=sqrt(x+1.0);break;
            default: y=1/(x+1.0);break;
        }
        printf("x=%d,y=%lf\n",x,y);
}

条件运算符(三元运算符)

  • 条件运算符 condition ? expr1 : expr2;是唯一的三目运算符,用于根据条件选择两个值中的一个。
    • condition是一个表达式,其结果必须为整数类型(在C中,非零值通常被视为真,零被视为假)。
    • expr1是当condition为真时要计算并返回的值或表达式。
    • expr2是当condition为假时要计算并返回的值或表达式。
  • 示例:int max = (a > b) ? a : b;,这里,(a > b)是条件表达式。如果a大于b,则条件为真,max被赋值为a。否则,条件为假,max被赋值为b
#include <stdio.h>

void main()
{
    int a,b,max;
    double y;
    //while(1){ //无限循环用于测试代码
        printf("请输入a,b的值\n");
        scanf("%d%d",&a,&b);
        max = (a > b) ? a : b;
        printf("max=%d\n",max);
    //}   
}
  • 注意: 这个运算符在需要根据某个条件快速选择两个值之一时非常有用,可以使代码更加简洁和易读。然而,它应该谨慎使用,以避免在复杂的条件逻辑中造成混淆。对于非常复杂的条件,使用 if-else语句可能更清晰易懂。

作业-选择语句代码示例

早餐订单程序

分别用 if..else 和 Switch 编写如下早餐订单,客户输入:周 1、2、3、4、5、6、7:
程序输出:

  • 周一,牛奶,面包
  • 周二,稀饭、咸菜
  • 周三、周五,包子,稀饭
  • 周六,烤鸡腿,面包
  • 其它时间,不提供早餐

使用 if-else 语句编写的早餐订单程序

#include <stdio.h>  

int main() {  
    int day;  

    printf("请输入周几(1-7):");  
    scanf("%d", &day);  

    if (day >= 1 && day <= 7) {  
        if (day == 1) {  
            printf("周一早餐订单:牛奶,面包\n");  
        } else if (day == 2) {  
            printf("周二早餐订单:稀饭,咸菜\n");  
        } else if (day == 3 || day == 5) {  
            printf("周三、周五早餐订单:包子,稀饭\n");  
        } else if (day == 6) {  
            printf("周六早餐订单:烤鸡腿,面包\n");  
        } else {  
            printf("该时间,不提供早餐\n");  
        }  
    } else {  
        printf("输入无效,请输入1-7之间的数字\n");  
    } 
    return 0;  
}

使用 switch 语句编写的早餐订单程序

#include <stdio.h>  

int main() {  
    int day;  

    printf("请输入周几(1-7):");  
    scanf("%d", &day);  

    if (day >= 1 && day <= 7) {  
        switch (day) {  
            case 1: printf("周一早餐订单:牛奶,面包\n");  break;  
            case 2: printf("周二早餐订单:稀饭,咸菜\n");  break;  
            case 3:  
            case 5: printf("周三、周五早餐订单:包子,稀饭\n"); break;  
            case 6: printf("周六早餐订单:烤鸡腿,面包\n"); break;  
            default: printf("该时间,不提供早餐\n"); break;  
        }  
    } else {  
        printf("输入无效,请输入1-7之间的数字\n");  
    }  
    return 0;  
}

求解一元二次方程

/*  用#include 引入程序包:
  1.标准输入输出stdio.h
  2.数学库:math.h, 里面有开平方sart(x)的函数
*/
#include <stdio.h>
#include <math.h>


int main()   // 声明一个主函数
{
	// 下面声明计算中用的变量
	double a, b, c; // 声明 一元二次方程的三个系数变量为双精度浮点数
	double  x1, x2; // 声明 一元二次方程的两个根,为双精度浮点数变量
	double  Delta;  // 声明一个中间临时变量,用于计算b*b-4*a*c
	//  变量声明区结束


	// 接收用户的输入,计算机得到:a,b,c三个值
	printf("请输入一元二次方程的三个系数:\n");  //输入前的提示

	printf("请输入系数 a = \t"); //输入的提示
	scanf("%lf", &a);  //输入语句

	printf("请输入系数 b = \t");   //输入的提示
	scanf("%lf", &b);   //输入语句

	printf("请输入系数 c = \t");  //输入的提示
	scanf("%lf", &c);  //输入的提示

	//验证一下a,b,c三个系数是否输入正确?

	printf("a=%.2f,\nb=%.2f,\nc=%.2f\n", a, b, c);

	// 输入部分结束

	 //计算机开始计算:
	 //1.先计算出delta的值;
	Delta = b * b - 4 * a * c;

	// 分别考虑a,b,c和delta 的情况,分别做根的计算
	if (fabs(a) >= 0.00000001)   //判断a是否为0? 为安全起见,最好用 if (abs(a) < 0.0000001),即,a小于一个很小的数
		//abs(x)是math.h里额一个函数,即,求出x的绝对值
	{

		if (Delta < 0)  //判断是否有实数解?
		{
			printf("该方程式无实数解!\n");

			/* 当Delta小于0时,方程无实数解,但是可以有虚数解。
			realpart = - b/(2*a); //实部
			mipart = sqrt(-Delta) / (2*a);
			printf("方程有两个共轭复根:\n");
			printf("x1 = %.2f+%.5fi\n",realpart,mipart);
			//人为地加了i,以表示虚部
			printf("x2 = %.2f-%.5fi\n",realpart,mipart);
			*/
		}
		else if (fabs(Delta) < 0.0000001) //安全起见,用if (abs(Delta) < 0.0000001), Delta小于一个很小的数即Delta=0
		{
			x1 = x2 = -b / (2 * a);
			printf("方程有两个相等的根:\nx1=x2 = %.2f\n", x1); //输出 计算结果
		}
		else
		{
			Delta = sqrt(Delta); // sqrt是math.h里的函数,用来开平方
			x1 = (-b + Delta) / (2 * a); //得到第一个根
			x2 = (-b - Delta) / (2 * a); //得到第一个根
			printf("方程的两个根为\nx1 = %.2f,\nx2 = %.2f\n", x1, x2); //输出 计算结果
		}
	}
	else if (fabs(b) >= 0.00000001)  //安全起见,用if (abs(b) > 0.0000001), 即,b大于一个很小的数即,b不为0
	{
		x1 = -c / b;
		printf("该方程是一元一次方程,根 x =%.2f\n", x1); //输出 计算结果
	}
	else if (fabs(c) < 0.0000001)//安全起见,用if (abs(c) < 0.0000001), 即,c小于一个很小的数即c=0
		printf("x可以是任意值。\n"); //输出 计算结果
	else
		printf("该方程不成立。\n"); //输出 计算结果

	return 0;
}

计算特定公式值的程序 P = 2 \cos\frac{2 \pi}{3} \left(x\right) + \sin\frac{\pi}{2}\left( x\right)

输入:x=1~51,计算公式:2cos(2π/3x)+sin(π/2x)客户多次分别输入:x=1,x=3,x=5,x=7,x=9,x=11, 打印出如下计算公式的值:

P = 2 \cos\frac{2 \pi}{3} \left(x\right) + \sin\frac{\pi}{2}\left( x\right)

进一步,考虑:如何打印出从 x=1 到 x=51 所有奇数情况下的 P 值

计算特定 x 值对应的 P 值

#include <stdio.h>  
#include <math.h>  

#define PI 3.14159265358979323846  

int main() {  
    int x;  
    double P;
  
        // 用户输入的特定x值  
        printf("请输入特定的x值:\n");  
        scanf("%d", &x);

        // 打印特定x值对应的P值 
        P = 2 * cos((2 * PI / 3) * x) + sin((PI / 2) * x);  
        printf("x = %d, P = %.2lf\n", x, P);  

        // 打印从x=1到x=51所有奇数情况下的P值  
        printf("\nFor all odd x values from 1 to 51:\n");  
        for (x = 1; x <= 51; x += 2) {  
            P = 2 * cos((2 * PI / 3) * x) + sin((PI / 2) * x); 
            printf("x = %d, P = %.2f\n", x, P);  
        }  
  
    return 0;  
}

备注:

因个人习惯和能力所限,该文档内容若存在表述不合理或错误之处,请大家留言多多指正

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明