第五章 选择控制结构

分治策略:任务分解细化

程序设计语言:为了让计算机执行由高级语言编写的程序指令,必须把这些指令从高级语言形式转换成计算机能理解的机器语言形式,这种转换是由编译器来完成的

算法:为解决一个具体问题而采取的确定、有限、有序、可执行的操作步骤

数据结构+算法=程序(这个公式仅对面向过程的语言成立)

数据结构是计算机存储、组织数据的方式,指相互之间存在一种或多种特定关系的数据元素的集合

算法是对操作或行为的描述,算法代表着用系统的方法描述解决问题的策略

算法的描述方式:

  1. 自然语言描述(通俗易懂;冗长,不易直接转化为程序)
  2. 流程图描述(形象直观、一目了然,易于理解和发现程序中存在的错误;所占篇幅较大)
  3. NS结构化流程图描述
  4. 伪码描述

关系运算符

  • <
  • >
  • <=
  • >=
  • ==
  • !=

注意:==是比较,=是赋值,将“==”误写为“=”在C语言语法上是允许的,不会提示错误,但将导致错误的运行结果

条件表达式:用非0值表示“真”,用0值表示“假”

//L5-1(单分支控制)

#include  <stdio.h>
main()
{
int a, b, max;
printf("Input a, b:");
scanf("%d,%d", &a, &b);
if (a > b) max = a;
if (a <= b) max = b;
printf("max = %d\n", max);
}
//运行结果
Input a, b:3,5
max = 5

//L5-2(双分支控制)

#include  <stdio.h>
main()
{
int a, b, max;
printf("Input a, b:");
scanf("%d,%d", &a, &b);
if (a > b) max = a;
else max = b; /* 相当于a<=b的情况 */
printf("max = %d\n", max);
}

//L5-3(条件运算符)

#include  <stdio.h>
main()
{
int a, b, max;
printf("Input a, b:");
scanf("%d,%d", &a, &b);
max = a > b ? a : b;/* 用条件表达式计算两整数的最大值*/
printf("max = %d\n", max);
}

用一对花括号将一组逻辑相关的语句括起来,称为复合语句(类似于Verilog中的begin end)

//L5-4

#include  <stdio.h>
#include <stdlib.h>
#include <math.h>
#define EPS 1e-6
main()
{
float a, b, c, disc, p, q;
printf("Please enter the coefficients a,b,c:");
scanf("%f,%f,%f", &a, &b, &c);
if (fabs(a) <= EPS) /* a=0时,输出"不是二次方程" */
//浮点数并非真正意义上的实数,只是其在某种范围内的近似,因此也就只能用近似的方法将实数与0进行比较
{
printf("It is not a quadratic equation!\n");
exit();//exit是C语言提供的标准库函数,作用是终止整个程序的执行,强制返回操作系统
//调用函数exit()需要在程序开头包含头文件<stdlib.h>
}
disc = b * b - * a * c; /* 计算判别式 */
p = - b / ( * a);
q = sqrt(fabs(disc)) / ( * a);
if (fabs(disc) <= EPS) /* 判别式等于0时,输出两相等实根 */
{
printf("x1 = x2 = %.2f\n", p);
}
else
{
if (disc > EPS) /* 判别式大于0时,输出两不等实根 */
{
printf("x1 = %.2f, x2 = %.2f\n", p+q, p-q);
}
else /* 判别式小于0时,输出两共轭复根 */
{
printf("x1 = %.2f+%.2fi, ", p, q);
printf("x2 = %.2f-%.2fi\n", p, q);
}
}
}

用于多路选择的switch语句(类似于Verilog中的case语句)

//L5-5

#include  <stdio.h>
main()
{
int data1, data2;
char op;
printf("Please enter an expression:");
scanf("%d%c%d", &data1, &op, &data2); /* 输入运算表达式 */
switch (op) /* 根据输入的运算符确定执行的运算 */
{
case '+': /* 加法运算 */
printf("%d + %d = %d \n", data1, data2, data1 + data2);
break;//只有switch语句和break语句配合使用,才能形成真正意义上的多分支
case '-': /* 减法运算 */
printf("%d - %d = %d \n", data1, data2, data1 - data2);
break;
case '*': /* 乘法运算 */
printf("%d * %d = %d \n", data1, data2, data1 * data2);
break;
case '/': /* 除法运算 */
if ( == data2) /* 为避免除0错误,检验除数是否为0 */
printf("Division by zero!\n");
else
printf("%d / %d = %d \n", data1, data2, data1 / data2);
break;
default: /* 处理非法运算符 */
printf("Invalid operator! \n");
}
}

每个case后常量的次序发生改变时,不影响程序的运行结果,但不能有重复的case出现

从执行效率角度考虑,一般将发生频率高的情况放在前面

//L5-6

#include  <math.h>
#include <stdio.h>
main()
{
float data1, data2;
char op;
printf("Please enter the expression:\n");
scanf("%f %c%f", &data1, &op, &data2); /* %c前有一个空格 */
switch (op)
{
case '+':
printf("%f + %f = %f \n", data1, data2, data1 + data2);
break;
case '-':
printf("%f - %f = %f \n", data1, data2, data1 - data2);
break;
case '*':
case 'x':
case 'X':
printf("%f * %f = %f \n", data1, data2, data1 * data2);
break;
case '/':
if (fabs(data2) <= 1e-) /* 实数与0比较 */
printf("Division by zero!\n");
else
printf("%f / %f = %f \n", data1, data2, data1 / data2);
break;
default:
printf("Invalid operator! \n");
}
}

逻辑运算符

  • !:逻辑非
  • &&:逻辑与
  • ||:逻辑或

运算符&&和||都具有“短路”特性

程序测试:

  • 程序测试是确保程序质量的一种有效手段
  • 穷尽测试、抽样检查
  • 程序测试只能证明程序有错,而不能证明程序无错
  • 程序测试的目的是为了尽可能多的发现程序中的错误

测试用例:

  • 白盒测试(结构测试):测试程序的内部结构已知,按程序的内部逻辑设计测试用例
  • 黑盒测试(功能测试):不考虑程序内部的逻辑结构和处理过程,只检查程序的功能是否符合它的功能说明
  • 结合使用:选择有限数量的重要路径进行白盒测试,对重要的功能需求进行黑盒测试

//L5-7

#include <stdio.h>
#include <math.h>
#define EPS 1e-1
main()
{
float a, b, c;
int flag = ;
printf("Input a,b,c:");
scanf("%f,%f,%f", &a, &b, &c);
if (a+b>c && b+c>a && a+c>b)
{
if (fabs(a-b)<=EPS && fabs(b-c)<=EPS && fabs(c-a)<=EPS)
{
printf("等边"); /* 等边 */
flag = ; /* 置标志变量flag为0值 */
}
else if (fabs(a-b)<=EPS || fabs(b-c)<=EPS|| fabs(c-a)<=EPS)
{
printf("等腰"); /* 等腰 */
flag = ; /* 置标志变量flag为0值 */
}
if (fabs(a*a+b*b-c*c)<=EPS || fabs(a*a+c*c-b*b)<=EPS
|| fabs(c*c+b*b-a*a)<=EPS)
{
printf("直角");
flag = ;
}
if (flag)
{
printf("一般");
}
printf("三角形\n");
}
else
{
printf("不是三角形\n");
}
}
//测试结果
Input a,b,c:3,4,5
直角三角形
Input a,b,c:4,4,5
等腰三角形
Input a,b,c:,3,4,6
不是三角形
Input a,b,c:3,4,9
不是三角形
Input a,b,c:10,10,14.14
等腰直角三角形
Input a,b,c:4,4,4
等边三角形

边界测试:

在选用测试用例时,不仅要选用合理的输入数据,还应选用不合理的以及某些特殊的输入数据或者临界的点,对程序进行测试,称为边界测试

//L5-8

#include <stdio.h>
main()
{
int score, mark;
printf("Please enter score:");
scanf("%d", &score);
if (score< || score>)
{
mark = -;
}
else
{
mark = score / ;
}
switch (mark)
{
case :
case :
printf("%d--A\n", score);
break;
case :
printf("%d--B\n", score);
break;
case :
printf("%d--C\n", score);
break;
case :
printf("%d--D\n", score);
break;
case :
case :
case :
case :
case :
case :
printf("%d--E\n", score);
break;
default:
printf("Input error!\n");
}
}

//5-9

#include  <stdio.h>
main()
{
int a, b, max;
printf("Input a, b:");
scanf("%d,%d", &a, &b);
max = a > b ? a : b;
printf("max = %d\n", max);
}

//5-10

#include  <stdio.h>
main()
{
int a, b, max, ret;
printf("Input a, b:");
ret = scanf("%d,%d",&a, &b); /* 记录scanf函数的返回值 */
if (ret != ) /* 根据scanf函数返回值,判断输入数据个数或者格式是否错误 */
{
printf("Input data quantity or format error!\n");
while(getchar() != '\n'); /* 清除输入缓冲区中的错误数据 */
}
else /* 此处可以是正确读入数据后应该执行的操作 */
{
max = a > b ? a : b;
printf("max = %d\n", max);
}
}

虽然函数scanf()不进行参数类型匹配检查,但是通过检验scanf()的返回值是否为应读入的数据项数,可以判断输入的数据项数和格式(包括输入格式错误、存在非法字符、无数据可读等)是否正确

位运算符:

  • 位运算就是对字节或字内的二进制数位进行测试、抽取、设置或移位等操作
  • 其操作对象不能是float、double、long double等其他数据类型,只能是char和int类型
  • ~:按位取反
  • <<,>>:左移位、右移位(无论是左移位还是右移位,从一端移走的位不移入另一端,移出的位的信息都丢失了)
  1. 算术移位
  2. 逻辑移位
  • &:按位与,可用于对字节中的某位清零
  • ^:按位异或,可用于对字节中的某位置1
  • |:按位或

注意:按位取反是用补码进行计算的。

如12为0000000000001100,取反得到补码1111111111110011,反码为1111111111110010,原码为1000000000001101,即为-13

//L5-11

#include  <stdio.h>
main()
{
int x=12, y=8;
printf("\n%5d%5d%5d", !x, x||y, x&&y);
printf("\n%5u%5d%5d", ~x, x|y, x&y);
printf("\n%5d%5d%5d\n", ~x, x|y, x&y);
}
//运行结果
0 1 1
4294967283 12 8
-13 12 8

 
 
 
 
 

C语言程序设计(五) 选择控制结构的更多相关文章

  1. 160809208沈昊辰c语言程序设计实验选择结构设计

    <C语言程序设计>实验报告 学 号 160809208 姓 名 沈昊辰 专业.班 计科16-2班 学    期 2016-2017 第1学期 指导教师 黄俊莲 吴喆 实验地点 C区二层机房 ...

  2. C语言程序设计入门学习五步曲(转发)

    笔者在从事教学的过程中,听到同学抱怨最多的一句话是:老师,上课我也能听懂,书上的例题也能看明白,可是到自己动手做编程时,却不知道如何下手.发生这种现象的原因有三个: 一.所谓的看懂听明白,只是很肤浅的 ...

  3. 160809209_李梦鑫_C语言程序设计实验2+选择结构程序设计_进阶

    <C语言程序设计>实验报告 学 号 160809209 姓 名 李梦鑫 专业.班 计科16-2班 学    期 2016-2017 第1学期 指导教师 黄俊莲 吴喆 实验地点 C05 机 ...

  4. 《C语言程序设计教程》学习笔记

    <C语言程序设计教程>--朱鸣华.刘旭麟等 第一章 C语言概述 1.C语言的特点: 1)兼具高级.低级语言的双重能力(C语言允许直接访问物理地址,能够进行位操作,能实现汇编语言的大部分功能 ...

  5. C语言程序设计第4堂作业

    大家注意:本次作业稍有增加,由于放假期间大家空闲时间比较充足,将之前学习过程中遗留的问题必须在假期解决.   本次课学习主要内容: 分支结构中的二分支结构.多分支结构和else-if语句 掌握字符型数 ...

  6. 《C语言程序设计》编程总结汇总

    <C语言程序设计>编程总结汇总 院系: 专业年级: 班级名称: 学号: 姓名: 指导教师: 完成时间: 自我评价: 计算机科学与技术专业教研室 2018 年秋季学期 第四周编程总结 题目4 ...

  7. C语言程序设计50例(经典收藏)

    本篇文章是对C语言程序设计的50个小案例进行了详细的分析介绍,需要的朋友参考下 [程序1]题目:有1.2.3.4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?1.程序分析:可填在百位.十 ...

  8. 《C语言程序设计(第四版)》阅读心得(一)

    本篇开始写我个人觉得谭浩强老师的<C语言程序设计(第四版)>中之前没有认识到,或者忘了的知识.因为本科学过,所以有些简单的东西就没有放进来了,所以可能并不是太全面. 第一章程序设计与语言 ...

  9. 2019年春季学期《C语言程序设计II》课程总结

    2019年春季学期<C语言程序设计II>课程总结 1.课程情况 教学内容 课堂小结 作业安排 优秀作业 备注 1.开学谈心 2.测验数据类型.运算符与表达式的自学情况,并讲解测验题目3.第 ...

随机推荐

  1. Java 获取Enumeration类型的集合

    学习到java的io流中关于序列流SequenceInputStream使用,其中把3个以上的流串联起来操作, 使用的参数是生成运行时类型为 InputStream 对象的 Enumeration 型 ...

  2. Esp8266和HomeKit

    Summary 没有找到合适的简单解决方案,将Esp8266控制的设备连接到HomeKit.所以参照EspEasy实现 HomeKit和Esp8266连接. 连接方式: Raspberry Zero ...

  3. Leetcode刷题记录 旋转矩阵

    https://leetcode-cn.com/problems/spiral-matrix/submissions/ class Solution(object): def spiralOrder( ...

  4. Bar条形图

    import matplotlib.pyplot as plt import numpy as np n = 12 X = np.arange(n) Y1 = (1 - X / float(n)) * ...

  5. python调用adb命令进行手机操作

    Python中执行cmd命令可以用到os和subprocess两个模块. 区别在于os是阻塞式的,subprocess是非阻塞式的,所以一般我们使用subprocess是比较适合的. 接下来我先举一个 ...

  6. 【转载】Oracle Spatial中SDO_Geometry详细说明

    转载只供个人学习参考,查看请前往原出处:http://www.cnblogs.com/upDOoGIS/archive/2009/05/20/1469871.html 相关微博:oracle 创建SD ...

  7. IP不是万能药 为何有蜘蛛侠等大片的索尼要放弃电影

    ​ 为何有蜘蛛侠等大片的索尼要放弃电影"> 近年来,国内狂炒"IP"这一概念,比如动漫.网络文学.小说.游戏等,甚至围绕IP制造出内容矩阵.从一个IP延伸至多个领域 ...

  8. 达拉草201771010105《面向对象程序设计(java)》第十五周学习总结

    达拉草201771010105<面向对象程序设计(java)>第十四周学习总结 第一部分:理论知识 JAR文件: 1.Java程序的打包:程序编译完成后,程序员 将.class文件压缩打包 ...

  9. 通过python脚本读取多台虚机硬件信息

    主要通过fabric模块实现 import fabric ''' hosts = [] ,): host = "192.168.75." + str(i) hosts.append ...

  10. 完全依赖QML实现播放器

    前言 一直听闻QML无比强大好用,工作中需要扣一个同时播放视频的Demo,所以就趁这个机会研究了一下. 效果图和源码 源码仓库 主要设计 主页面QML import QtQuick 2.12 impo ...