任何简单或者复杂的算法都可以由顺序结构、选择结构和循环结构这三种基本结构组合而成。所以这三种结构被称为程序设计的三种基本结构,也是程序化程序设计必须采用的结构。
5.1 概念普及
5.1.1 结构化程序设计
结构化程序设计由迪克斯特拉(E.W.dijkstra)在1969年提出,以模块化设计为中心,将软件系统划分为若干功能模块,各模块按要求单独编程,再由各模块连接,组合构成相应的软件系统。该方法强调程序的结构性,所以容易做到易读,易懂。
结构化程序设计的原则可表示为:程序=(算法)+(数据结构)。
算法是一个独立的整体,数据结构(包含数据类型与数据)也是一个独立的整体。两者分开设计,以算法(函数或过程)为主。
按照结构化程序设计的观点,任何算法功能都可以通过由程序模块组成的三种基本程序结构的组合: 顺序结构、选择结构和循环结构来实现。
结构化程序设计的基本思想是采用"自顶向下,逐步求精"的程序设计方法和"单入口单出口"的控制结构。
自顶向下、逐步求精的程序设计方法从问题本身开始,经过逐步细化,将解决问题的步骤分解为由基本程序结构模块组成的结构化程序框图;
"单入口单出口"的思想认为一个复杂的程序,如果它仅是由顺序、选择和循环三种基本程序结构通过组合、嵌套构成,那么这个新构造的程序一定是一个单入口单出口的程序。据此就很容易编写出结构良好、易于调试的程序来。
结构化程序设计方法的主要原则可以概括为自顶向下、逐步求精、模块化及限制使用goto语句,总的来说可使程序结构良好、易读、易理解、易维护。
基本结构
(1)顺序结构
顺序结构表示程序中的各操作是按照它们出现的先后顺序执行的。
选择结构表示程序的处理步骤出现了分支,它需要根据某一特定的条件选择其中的一个分支执行。选择结构有单选择、双选择和多选择三种形式。
循环结构表示程序反复执行某个或某些操作,直到某条件为假(或为真)时才可终止循环。在循环结构中最主要的是:什么情况下执行循环?哪些操作需要循环执行?循环结构的基本形式有两种:当型循环和直到型循环。
(4)当型循环
表示先判断条件,当满足给定的条件时执行循环体,并且在循环终端处流程自动返回到循环入口;如果条件不满足,则退出循环体直接到达流程出口处。因为是"当条件满足时执行循环",即先判断后执行,所以称为当型循环。
(5)直到型循环
表示从结构入口处直接执行循环体,在循环终端处判断条件,如果条件不满足,返回入口处继续执行循环体,直到条件为真时再退出循环到达流程出口处,是先执行后判断。因为是"直到条件为真时为止",所以称为直到型循环。
设计方法
(1)自顶向下
程序设计时,应先考虑总体,后考虑细节;先考虑全局目标,后考虑局部目标。不要一开始就过多追求众多的细节,先从最上层总目标开始设计,逐步使问题具体化。
对复杂问题,应设计一些子目标作为过渡,逐步细化。
一个复杂问题,肯定是由若干稍简单的问题构成。模块化是把程序要解决的总目标分解为子目标,再进一步分解为具体的小目标,把每一个小目标称为一个模块。
所谓编码就是把已经设计好的算法用计算机语言表示,即根据已经细化的算法正确写出计算机程序。结构化的语言(如 Pascal,C,QBASIC等)都有与三种基本结构对应的语句。
结构化程序设计的优点
(1)自顶向下逐步求解的方法符合人类解决复杂问题的普遍规律,因此可以显著提高软件开发工程的成功率和出产率。
(2)用先全局后局部、先整体后细节、先抽象后具体的逐步求精过程开发出的程序有清晰地层次结构,因此容易阅读和理解。
(3)不使用GOTO语句仅是使用单入口、单出口的控制结构,使得程序的静态结构和它的动态执行情况比较一致。因此程序容易阅读额理解,开发时也比较容易保证程序的正确性,即使出现错误也比较容易诊断和修正。
(4)控制结构有确定的逻辑结构,编写程序代码只限于很少几种直截了当的方式,因此源程序清晰流畅,易读易懂而且容易测试。
(5)程序清晰和模块化使得修改和重新设计一个软件时可重用的代码量最大。
(6)程序的逻辑结构清晰,有利于程序正确性验证。
5.1.2 非结构化程序设计
非结构化程序设计是历史上最早的能够创造图灵完备算法的程序设计模式。 在它之后,历史上又出现了结构化(过程化)程序设计、面向对象程序设计。
非结构化语言是高级语言发展的第一阶段,编程风格比较随意,只要符合语法规则即可,而且也没有严格的规范要求,程序中的流程可以随意跳转。此外,很多开发人员为了追求程序执行的效率而采用了很多“小技巧”,使程序变得难以阅读和维护。早期的BASIC、COBOL、FORTRAN等都是非结构化语言。
5.2 分支语句
5.2.1 分支语句的几种形式
5.2.2 if 结构
语法:
if(boolean_expression)
{
// 如果布尔表达式为真将执行的语句
}
流程:
示例:
#include <iostream>
using namespace std;
int main()
{
int age;
std::cout << "请输入小明的年龄:";
std::cin >> age;
if (age >= 18)
{
std::cout << "^_^小明已经是成年人了!" << endl;
return 0;
}
std::cout << "小明还是祖国的花朵^_^!" << endl;
return 0;
}
5.2.3 if_else 结构
语法:
if(boolean_expression)
{
// 如果布尔表达式为真将执行的语句
}
else
{
// 如果布尔表达式为假将执行的语句
}
流程:
示例:
#include <iostream>
using namespace std;
int main()
{
int age;
std::cout << "请输入小明的年龄:";
std::cin >> age;
if (age >= 18)
{
std::cout << "^_^小明已经是成年人了!" << endl;
}
else
{
std::cout << "小明还是祖国的花朵^_^!" << endl;
}
return 0;
}
5.2.4 if_else if 结构
语法:
if(expression1)
{
// 如果布尔表达式1为真将执行的语句
}
else if (expression2)
{
// 如果布尔表达式2为真将执行的语句
}
流程:
示例:
#include <iostream>
using namespace std;
int main()
{
int age;
std::cout << "请输入小明的年龄:";
std::cin >> age;
if (age < 6)
{
std::cout << "^_^小明在上幼稚园;" << endl;
}
else if (age == 6)
{
std::cout << "小明是一年级的小学生了!" << endl;
}
else if (age == 7)
{
std::cout << "小明是二年级的小学生!" << endl;
}
else
{
std::cout << "小明是大学生了!" << endl;
}
return 0;
}
5.2.5 嵌套 if 结构
语法:
if( boolean_expression 1)
{
// 当布尔表达式1 为真时执行
if(boolean_expression 2)
{
// 当布尔表达式 2 为真时执行
}
}
示例:
#include <iostream>
using namespace std;
int main()
{
int score = 0;
std::cout << "请输入小明的数学成绩:";
std::cin >> score;
if (score >= 60)
{
if (score >= 85)
{
std::cout << "^_^成绩优秀!" << endl;
}
else if (score >= 70)
{
std::cout << "成绩良好!" << endl;
}
else
{
std::cout << "成绩一般!" << endl;
}
}
else
{
std::cout << "不及格!" << endl;
}
return 0;
}
5.3 逻辑表达式
表达式是由一个或者多个运算对象(操作数、表达式)构成,运算对象(操作数、表达式)之间可以通过运算符连接起来。对表达式求值最后都会得到一个结果。
逻辑表达式是由一个或多个运算对象(操作数、表达式)与逻辑表达式组成的。
假设变量 A 的值为 1,变量 B 的值为 0,则:
运算符 | 描述 | 实例 |
&& | 逻辑与运算符。如果两个操作数都 true,则条件为 true。 | (A && B) 为 false。 |
|| | 逻辑或运算符。如果两个操作数中有任意一个 true,则条件为 true。 | (A || B) 为 true。 |
! | 逻辑非运算符。用来逆转操作数的逻辑状态,如果条件为 true 则逻辑非运算符将使其为false。 | !(A && B) 为 true。 |
5.3.1 逻辑OR运算符:||
exprl || expr2的值 | ||
expr1 == true | expr1 == false | |
expr2 == true | true | true |
expr2 == false | true | false |
expr1、expr2只要有一个为真,则结果为真 逻辑OR运算符||的结合性为从左到右 |
#include <iostream>
using namespace std;
int main()
{
char ch;
cout << "请输入待判定字符(y或n):";
cin >> ch;
if (ch == 'y' || ch == 'Y')
cout << "你输入了 " << ch << " ,结果正确!" << endl;
else if (ch == 'n' || ch == 'N')
cout << "你输入了 " << ch << " ,结果正确!" << endl;
else
cout << "输入错误,操作结束!" << endl;
return 0;
}
5.3.2 逻辑AND运算符:&&
exprl || expr2的值 | ||
expr1 == true | expr1 == false | |
expr2 == true | true | false |
expr2 == false | false | False |
expr1、expr2只有两个都为真,结果才为真 逻辑AND运算符&&的结合性为从左到右 |
#include <iostream>
using namespace std;
int main()
{
int age;
int month;
cout << "能否正常入学核验,请输入年龄及出生月份(年龄、月份必须为整数):" << endl;
cout << "请输入年龄:";
cin >> age;
cout << "请输入月份:";
cin >> month;
if (age > 6)
cout << "你早该上学了!" << endl;
else if (age == 6 && month < 9)
cout << "可以正常入学!" << endl;
else if (age == 6 && month > 8)
cout << "请于下一年入学!" << endl;
else
cout << "还未到入学年龄!" << endl;
return 0;
}
5.3.3 逻辑NOT运算符:!
!expr1 | |
expr1 == true | false |
expr1 == false | true |