C语言-程序结构

选择结构程序设计

(1)用if语句实现选择结构

选择题

  1. 阅读以下程序:
#include <stdio.h>
int main(void)
{
    int x;
    scanf("%d", &x);
    if (x-- < 5)
        printf("%d", x);
    else
        printf("%d", x++);
}
  1. 程序运行后,如果从键盘上输人5,则输出结果是( )。
    A: 3
    B: 4
    C: 5
    D: 6
    在这里插入图片描述
  2. 有如下程序
#include <stdio.h>
int main(void)
{
    int a = 2, b = -1, c = 2;
    if (a < b)
        if (b < 0)
            c = 0;
        else
            c++;
    printf("%d\n", c);
}

该程序的输出结果是
A: 0
B: 1
C: 2
D:
在这里插入图片描述

1.1 if语句的一般形式

作用:根据所指定的条件是否满足,决定从给定的两组操作选择其中之一

if语句的三种格式:
  1. 简化形式:

第一种形式为基本形式 if(表达式) 语句; 其语义是:如果表达式的值为真,则执行其后的语句, 否则不执行该语句。其过程可表示为

if(表达式) 语句块 
如:  if(x>y) printf(“%d”,x); 
2. 一般形式 :

如果表达式的值为真,则执行语句1,否则执行语句2 。

  if (表达式)                     
       语句块1                            
   else                                       
      语句块2

例如(假代码):

 if(year>month)
    year+month;
    else if (year>month)
    {
        /* code */
         year+month;
    }
    else if (year>month)
    {
        /* code */
    }
    
    else
  1. 嵌套形式
    • 含义:一条if语句重又包含另一个if语句称为if语句的嵌套.
    • 格式:
    if( 表达式1)
    else if(表达式2 ) 语句块1
    else if( 表达式3) 语句块3
    … …
    else if (表达式m) 语句m
    else 语句块m+1

执行过程:先判断表达式1的值,若为真,则执行语句1,跳过其它语句,若为假,则判断表达式2,依此类推
其语义是:依次判断表达式的值,当出现某个值为真时, 则执行其对应的语句。然后跳到整个if语句之外继续执行程序。 如果所有的表达式均为假,则执行语句n 。 然后继续执行后续程序

(2)用switch语句实现多分支选择结构

C语言还提供了另一种用于多分支选择的switch语句, 其一般形式为:

switch(表达式){ 
    case 常量表达式1:  语句1;
    case 常量表达式2:  语句2;case 常量表达式n:  语句n;
    default:  语句n+1;
}

其语义是:计算表达式的值。 并逐个与其后的常量表达式值相比较,当表达式的值与某个常量表达式的值相等时,
即执行其后的语句,然后不再进行判断,继续执行后面所有case后的语句。如表达式的值与所有case后的常量表达式均不相同时,则执行default后的语句。

C语言还提供了一种break语句,专用于跳出switch语句,break 语句只有关键字break,没有参数。
在每一case语句之后增加break 语句, 使每一次执行之后均可跳出switch语句,从而避免输出不应有的结果。

在使用switch语句时还应注意以下几点:

  1. 在case后的各常量表达式的值不能相同,否则会出现错误。
  2. 在case后,允许有多个语句,可以不用{}括起来。
  3. 各case和default子句的先后顺序可以变动,而不会影响程序执行结果。
  4. default子句可以省略不用。

关系运算符和表达式

在程序中经常需要比较两个量的大小关系, 以决定程序下一步的工作。比较两个量的运算符称为关系运算符。 在C语言中有以下关系运算符:

    < 小于

<= 小于或等于
  > 大于
  >= 大于或等于
  == 等于
  != 不等于

关系运算符都是双目运算符,其结合性均为左结合。

关系运算符的优先级低于算术运算符,高于赋值运算符。

在六个关系运算符中,<,<=,>,>=的优先级相同,高于==和**!=**,==和!=的优先级相同。

关系表达式

关系表达式的一般形式为: 表达式 关系运算符 表达式

例如:a+b>c-d,x>3/2,‘a’+1<c,-i-5*j==k+1;都是合法的关系表达式。由于表达式也可以又是关系表达式。因此也允许出现嵌套的情况

例如:a>(b>c),a!=(c==d)等。关系表达式的值是“真”和“假”,用“1”和“0”表示。

如: 5>0的值为“真”,即为1。(a=3)>(b=5)由于3>5不成立,故其值为假,即为0。

运算符与表达式

循环结构程序设计

有的时候,我们可能需要多次执行同一块代码。一般情况下,语句是按顺序执行的:函数中的第一个语句先执行,接着是第二个语句,依此类推。

编程语言提供了更为复杂执行路径的多种控制结构。

循环语句允许我们多次执行一个语句或语句组,下面是大多数编程语言中循环语句的流程图

(1)while和do while循环结构

while 循环

当给定条件为真时,重复语句或语句组。它会在执行循环主体之前测试条件。

while 循环的语法

while (表达式)
{
        语句;
}

当表达式为真,则执行下面的语句;语句执行完之后再判断表达式是否为真,如果为真,再次执行下面的语句;然后再判断表达式是否为真……就这样一直循环下去,直到表达式为假,跳出循环。这个就是while 的执行顺序。

while语句可以分为while循环头和while循环体:while头由关键字while和一个用做循环判断的表达式组成,while体是循环的主体操作,可以是一条语句,也可以是放在大括号“{}”内的复合语句。
在这里插入图片描述

求出用户输入数值内所有正整数和。
本例由用户输入一个值,通过while循环累加这个数值以内整数的和,循环的同时使i值递减,当i值递减到0时,循环结束。

#include <stdio.h>
int main()
{
    int n, i, iSum;            /*定义三个整型变量*/
    iSum = 0;                  /*给变量赋值*/
    printf("请输入一个整数:"); /*输出提示信息*/
    scanf("%d", &n);           /*要求输入一个数值*/
    i = n;
    while (i)                                        /*使用while循环*/
        iSum += i--;                                 /*进行求和运算*/
    printf("计算%d以内的整数总和为:%d\n", n, iSum); /*将结果输出*/
    return 0;
}

在这里插入图片描述

当循环条件恒为真时,就会出现死循环,使程序无法退出或者无法进入下一次循环。除非特殊情况,否则一定要避免死循环的产生。在设计循环结构时,要注意循环条件

技巧:

当编译器中运行代码时出现了死循环时,可以按+或者+组合键试试,大多情况下程序可以停下来。也可以调出任务管理结束进程。

while语句的空循环体

while循环语句是由判断while循环条件和一个循环体组成,如果循环体只是单行语句,那么while语句从while开始,到第一个分号“;”结束,while后面的第一个分号“;”便是while语句的结束标志。如果while(表达式)后面的循环体只有一个分号“;”,也就是说单行语句为空,这样的循环体就叫做空循环体。

while空循环体的一般形式如下:
while(表达式);

注意while循环语句常见错误

while循环语句的灵活多变常常会导致初学者因疏忽大意而出错,笔者为了能够使读者尽量减少出现不必要的错误,在本节将while循环语句容易出错的地方给读者进行详细的讲解。
  1. 大括号注意事项
    在上面已经提到while结构中循环体可以是单条语句,也可以是多条语句形成的复合语句。也就是说如果循环体是需要多条语句形容一个程序,那么一定要用大括号“{}”将多条语句括起来,形成一个语句块,也就是复合语句。
    如果忽略了大括号的用途,语句块没有用大括号括起来,则while语句的范围只到while后面的第一个分号处结束,程序就会得不到预计的效果。
  2. 分号注意事项
    while(表达式)后面是没有分号的,如果不小心加上分号,系统也不会出现编译错误,但是程序却会不停的执行空操作,形成空循环体,无法执行“while(表达式);”后面的程序。

使用while语句求n!

3!=321,5!=54321,依此类推n!=n*(n-1)*……21,使用while语句求n!。

#include<stdio.h>
int main(){
	int i=2,n;		/*定义变量i,n为基本整型并为i赋初值2*/
	float fac=1;		/*定义fac为单精度型并赋初值1*/
	printf("please input an interger>=0.\n");
	scanf("%d",&n);	/*使用scanf函数获取n的值*/
	if(n==0||n==1)	/*当n为0或1的时候输出阶层为1*/
	{
		printf("factorial is 1.\n");
		return 0;
	}
	while(i<=n)		/*当满足输入的数值大于等于i时执行循环体语句*/
	{
		fac=fac*i;	/*实现求阶层的过程*/
		i++;	/*变量i自加*/
	}
	printf("factorial of %d is:%.2f.\n",n,fac);	/*输出n和fac最终的值*/
	return 0;
}

在这里插入图片描述

使用while为用户提供菜单显示

在使用程序时,根据程序的功能会有许多的选项,为了使用户可以方便的观察到菜单的选项,要将其菜单进行输出。在本实例中,利用while将菜单进行循环输出,这样可以使用户更为清楚的知道每一项选择所对应的操作。

#include<stdio.h>
int main()
{
	int iSelect=1;			/*定义变量,表示菜单的选项*/
	while(iSelect!=0)		/*检验条件,循环显示菜单*/
	{			/*显示菜单内容*/
		printf("---------Menu---------\n");
		printf("----Sell----------1\n");
		printf("----Buy-----------2\n");
		printf("----ShowProduct---3\n");
		printf("----Out-----------0\n");
		scanf("%d",&iSelect);	/*输入菜单的选项*/
		switch(iSelect)							/*使用switch语句,检验条件进行相应的处理*/
		{
		case 1:		/*选择第一项菜单的情况*/
			printf("you are buying something into store\n");
			break;
		case 2:		/*选择第二项菜单的情况*/
			printf("you are selling to consumer\n");
			break;
		case 3:		printf("checking the store\n");
			break;
		case 0:		/*选择退出项菜单的情况*/
			printf("the Program is out\n");
			break;
		default:		/*默认处理*/
			printf("You put a wrong selection\n");
			break;
		}
	}
	return 0;
}

在这里插入图片描述

(2)for 循环结构

for循环语句的一般语法形式:

for(表达式1;表达式2;表达式3)
		    循环体;

for循环流程图:
在这里插入图片描述
工作原理

1、计算表达式1的值,通常为循环变量赋初值;
2、计算表达式2的值,即判断循环条件是否为真,若值为真则执行循环体一次, 否则跳出循环;
3、计算表达式3的值,这里通常写更新循环变量的赋值表达式,然后转回第2步重复执行;

注意事项:
for语句中的三个表达式都可以是逗号表达式
逗号表达式就是通过“,”运算符隔开的多个表达式组成的表达式
逗号表达式从左往右计算。逗号运算符在 C 语言运算符中的优先级最低
for 循环中有三个表达式
for 语句中的各个表达式都可以省略
分号分隔符不能省略

for(i = 0 , j = max ; i <=max ; i++, j--)
     printf(“\n%d  +  %d  =  %d”,i, j, i + j);

在这里插入图片描述

三种循环语句的比较

在这里插入图片描述

(3)continue语句和break语句的使用

在这里插入图片描述
在这里插入图片描述

格式:break;

功能:当break语句用于switch语句中时,可使程序跳出 switch语句而执行switch以后的语句;当break语句用于
循环语句中时,可使程序从循环体中跳出,即提前结束循 环,接着执行循环体之后的语句。

说明:

(1)break语句只能用于循环语句和switch语句中。
(2)break语句只能终止并跳出最近一层的循环结构或switch语句。

格式:continue;

功能:结束本次循环,跳过循环体中尚未执行的语句,进行 下一次是否执行循环体的判断

说明:

(1)continue语句只能用于循环语句中。
(2)continue语句与break语句的区别:continue语句只结束本次循环,而不是终止整个循环的执行。而break语句则是结束循环,不再进行条件判断。

循环的嵌套

一个循环体内包含另一个完整的循环结构,称为循环的嵌套

(1)while( ) (2)do
{ …… { ……
while( ) do
{……} {……}while( );
} }while( );
(3)for( ; ; ) (4)while( )
{ …… { ……
for( ; ; ) do
{……} {……}while( );
} }
(5)for( ; ; ) (6)for( ; ; )
{ …… { ……
while( ) do
{……} {……}while( );
}

说明:

(1)一个循环体必须完整地嵌套在另一个循环体内,不能出现交叉。
(2)多重循环的执行顺序是:外层循环控制变量每取得一个值时,内循环要完成一个遍历,然后再取得下一个外层循环控制变量的值。
(3)并列循环允许使用相同的循环控制变量,但嵌套循环不允许。

例如:利用双重循环编写C程序实现下述功能:1!+2!+3!+……+n! (n=1~10)。

#include <stdio.h>
int main(void)
{
    int i, j, p, s = 0;
    for (i = 1; i <= 10; i++)
    {
        p = 1;
        for (j = 1; j <= i; j++)
            p = p * j;
        s = s + p;
    }
    printf("1!+2!+3!+……+10! = %ld \n", s);
}

在这里插入图片描述
编写C程序实现下述功能:输出3~100之间的所有素数

#include <stdio.h>
int main(void)
{
    int i, m;
    printf("请输入一个整数:");
    scanf("%d", &m);
    for (i = 2; i <= m - 1; i++)
        if (m % i == 0)
            break;
    if (i > m - 1)
        printf("%d是素数\n", m);
    else
        printf("%d不是素数\n", m);
}

在这里插入图片描述

(5)用循环实现的常用算法,如递推、迭代、枚举等

  1. 程序功能:有一对兔子,从出生后第3个月起每个月都生一对兔子。小兔子长到第3个月起每个月又生一对兔子。假设所有兔子都不死,请编程计算并输出第n个月时的兔子总对数为多少,n从键盘输入
#include <stdio.h>
int main(void)
{
    int n, i, m = 0, a = 1, b = 1;

    scanf("%d", &n);

    if (n == 1 || n == 2)

        printf("1");

    else

    {
        for (i = 3; i <= n; i++)

        {
            m = a + b;

            a = b;

            b = m;
        }

        printf("%d", m);
    }

    return 0;
}

在这里插入图片描述
在这里插入图片描述

#include <stdio.h>
#include <math.h>
int main(void)
{
    float solution(float a, float b, float c, float d);
    float a, b, c, d;
    printf("input a,b,c,d:");
    scanf("%f,%f,%f,%f", &a, &b, &c, &d);
    printf("The solution is: x=%10.7f\n", solution(a, b, c, d));
}
float solution(float a, float b, float c, float d)
{
    float x = 1, x0, f, f1;
    do
    {
        x0 = x;
        f = ((a * x0 + b) * x0 + c) * x0 + d;
        f1 = (3 * a * x0 + 2 * b) * x0 + c;
        x = x0 - f / f1;
    } while (fabs(x - x0) >= 1e-5);
    return x;
}

在实际编程中,有些数据的取值往往是有限的,只能是非常少量的整数,并且最好为每个值都取一个名字,以方便在后续代码中使用,比如一个星期只有七天,一年只有十二个月,一个班每周有六门课程等。

以每周七天为例,我们可以使用#define命令来给每天指定一个名字:

#include <stdio.h>

#define Mon 1
#define Tues 2
#define Wed 3
#define Thurs 4
#define Fri 5
#define Sat 6
#define Sun 7

int main(){
    int day;
    scanf("%d", &day);
    switch(day){
        case Mon: puts("Monday"); break;
        case Tues: puts("Tuesday"); break;
        case Wed: puts("Wednesday"); break;
        case Thurs: puts("Thursday"); break;
        case Fri: puts("Friday"); break;
        case Sat: puts("Saturday"); break;
        case Sun: puts("Sunday"); break;
        default: puts("Error!");
    }
    return 0;
}

在这里插入图片描述

#define命令虽然能解决问题,但也带来了不小的副作用,导致宏名过多,代码松散,看起来总有点不舒服。C语言提供了一种枚举(Enum)类型,能够列出所有可能的取值,并给它们取一个名字。

枚举类型的定义形式为:

enum typeName{ valueName1, valueName2, valueName3, … };

enum是一个新的关键字,专门用来定义枚举类型,这也是它在C语言中的唯一用途;typeName是枚举类型的名字;
valueName1,valueName2, valueName3, …是每个值对应的名字的列表。注意最后的;不能少。
#include <stdio.h>

int main()
{
    enum week
    {
        Mon = 1,
        Tues,
        Wed,
        Thurs,
        Fri,
        Sat,
        Sun
    } day;
    scanf("%d", &day);
    switch (day)
    {
    case Mon:
        puts("Monday");
        break;
    case Tues:
        puts("Tuesday");
        break;
    case Wed:
        puts("Wednesday");
        break;
    case Thurs:
        puts("Thursday");
        break;
    case Fri:
        puts("Friday");
        break;
    case Sat:
        puts("Saturday");
        break;
    case Sun:
        puts("Sunday");
        break;
    default:
        puts("Error!");
    }
    return 0;
}
需要注意的两点是:
  1. 枚举列表中的 Mon、Tues、Wed 这些标识符的作用范围是全局的(严格来说是 main() 函数内部),不能再定义与它们名字相同的变量。

  2. Mon、Tues、Wed 等都是常量,不能对它们赋值,只能将它们的值赋给其他的变量。

枚举和宏其实非常类似:宏在预处理阶段将名字替换成对应的值,枚举在编译阶段将名字替换成对应的值。我们可以将枚举理解为编译阶段的宏。
C语言枚举类型(C语言enum用法)详解

c语言枚举法经典例题

判断一个数字是否为质数

质数(prime number)又称素数,有无限个。一个大于1的自然数,除了1和它本身外,不能被其他自然数整除

#include <stdio.h>

int main()
{
    int a = 0;   // 素数的个数
    int num = 0; // 输入的整数

    printf("输入一个整数:");
    scanf("%d", &num);

    for (int i = 2; i < num; i++)
    {
        if (num % i == 0)
        {
            a++; // 素数个数加1
        }
    }

    if (a == 0)
    {
        printf("%d是素数。\n", num);
    }
    else
    {
        printf("%d不是素数。\n", num);
    }

    return 0;
}
#include <stdio.h>
#include <math.h>
void main(){
    int m;  // 输入的整数 
    int i;  // 循环次数
    int k;  // m 的平方根 

    printf("输入一个整数:");
    scanf("%d",&m);

    // 求平方根,注意sqrt()的参数为 double 类型,这里要强制转换m的类型 
    k=(int)sqrt( (double)m );
    for(i=2;i<=k;i++)
        if(m%i==0)
            break;

    // 如果完成所有循环,那么m为素数
    // 注意最后一次循环,会执行i++,此时 i=k+1,所以有i>k 
    if(i>k)
        printf("%d是素数。\n",m);
    else
        printf("%d不是素数。\n",m);

    return 0;
}

c语言枚举法经典例题_【实战练习】上几道C语言的下酒菜!经典例题,巩固基础!.

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值