结构化程序设计
结构化程序设计的概念:是进行以模块功能和处理过程设计为主的详细设计的基本原则。结构化程序设计是面向过程程序设计的一个子集,它对写入的程序使用逻辑结构,使得理解和修改更有效更容易。
结构化程序设计的基本结构:
结构化程序是由若干个基本结构组合而成,每一个结构可以包含若干条语句和其他基本结构。结构化程序设计中包含三种基本的结构:顺序结构、选择结构和循环结构。
- 顺序结构:表示程序中的各操作是按照它们出现的先后线性,有序地执行。顺序结构的程序又称简单程序,这种结构的程序是顺序执行的,无分支,无转移,无循环,程序本身的逻辑很简单,它只依赖于计算机能够顺序执行指令的特点,依次执行个语句模块。
- 选择结构:表示程序的处理步骤出现了分支,它需要根据某一特定的条件选择其中的一个分支执行,选择结构有单选择、双选择和多选择三种形式。
- 循环结构:循环结构表示程序反复执行某个或某些操作,直到某条件为假(或为真)时才可终止循环。在循环结构中最主要的是:什么情况下执行循环?哪些操作需要循环执行?循环结构的基本形式有两种:当型循环和直到型循环。
结构化程序设计的不足:随着程序规模的扩大,难以理解、难以扩充、难以查错、难以重用。
- 在结构化程序设计中,函数和其所操纵的数据结构没有直观的联系。
- 程序理解难度与程序规模正相关:随着程序规模的增加,函数与被操作的数据结构之间的关系难以理解;函数之间的调用关系难以理解。
- 程序维护和扩充难度大:在结构化程序设计中没有封装和隐藏的概念,使得数据结构的变量都可以被直接访问,一旦发生改动,要修改所有变量访问语句。
- 错误发现难度大:数据结构和函数之间的复杂关系使得当数据结构中值出错时,难以找到发生错误的函数。
- 代码可重用率低:随着程序规模的扩大,由于函数和变量之间错综复杂的关系,很难抽取出整块代码进行重用。
面向对象的程序设计
面向对象的程序设计方法:客观事物的抽象过程
- 归纳客观事物的属性:将某类客观事物的共同特点归纳出来,形成一个数据结构,可以用多个变量描述事物的属性。
- 归纳客观事物的行为:将该类客观事物所能进行的行为也归纳出来,形成多个函数,这些函数可以用来操作数据结构。
面向对象程序设计的封装:通过某种语法形式,将客观事物抽象的数据结构和对应操作的函数捆绑在一起,形成一个类 (class),从而使得数据结构和操作函数呈现出清晰的关系,这称为封装。
面向对象程序设计的四个特点:抽象、封装、继承、多态
抽象出类的一个简单例子:计算矩形的周长和面积
矩形的属性:长和宽,可以用两个变量表示
矩形的行为:1. 设置长和宽的值 2. 计算周长 3. 计算面积 这三种行为可以分别使用一个函数来实现
矩形类:将上述矩形属性和行为封装在一起就形成了一个矩形类,长、宽变量称为该类的成员变量,三个函数称为该类的成员函数
class Rectangle{ public: int width, height; void Init(int width_, int height_){ width = width_; height = height_; } int Area(){ return width * height; } int Perimeter(){ return 2*(width + height); } };
通过类定义对象:C++ 中类的名字就是用户自定义类型的名字,使用方式和基本数据类型一样,通过类定义出来的变量,也成为类的实例即为对象。
int main(){
int w,h;
Rectangle rec; // 声明一个对象 rec
cin >> w >> h;
rec.Init(w,h);
cout << rec.Area() << endl << rec.Perimeter();
// 用指针访问对象成员
Rectangle r1, r2;
Rectangle* p1 = &r1;
Rectangle* p2 = &r2;
p1->w = 6;
p2->Init(5,4);
// 用引用访问对象成员
Rectangle r3;
Rectangle &rr = r3;
rr.w = 6;
rr.Init(5,4);
return 0;
}
对象的内存空间分配:对象所占用的内存空间大小等于所有成员变量的大小之和,成员函数不占用对象的内存空间,类的成员函数被所有对象共享。
类的定义
类的成员函数和类的定义分开:
class Rectangle{
public:
int width, height;
void Init(int width_, int height_){
width = width_;
height = height_;
}
int Area();
int Perimeter();
};
// :: 声明函数属于类成员
int Rectangle::Area(){
return width * height;
}
int Rectangle::Perimeter(){
return 2 *(width + height);
}
类成员的可访问范围:
在类的定义中,用关键字说明类成员可被访问的范围:
- private: 私有成员,可以被该类中的成员函数、友元函数访问,但不可以被子类的成员函数和该类的对象访问;
- 如果声明不写 public、protected、private,则默认为 private;
- 私有成员机制称为隐藏:目的在于强制对成员变量的访问一定要通过成员函数进行,这种机制使得在成员变量修改时,可以将修改范围缩小在成员函数中,而不需要修改整个项目中所有的成员变量访问语句。
- public:公有成员,可以被该类中的成员函数、子类的成员函数、友元函数访问,也可以由该类的对象访问,还可以被其他普通函数访问;
- protected:保护成员,可以被该类中的成员函数、子类的成员函数和友元函数访问,但不可以由该类的对象访问;
class Employee{
private:
char szName[30];
public:
int salary;
int setName(char* name);
int getName(char* name);
void averageSalary(Employee e1, Employee e2);
};
int Employee::setName(char* name){
strcpy(szName, name);
}
int Employee::getName(char* name){
strcpy(name,szName);
}
void Employee::averageSalary(Employee e1, Employee e2){
cout << e1.szName;
salary = (e1.salary + e2.salary) / 2;
}
int main(){
Employee e;
strcpy(e.szName, "Tom"); // 错误语句,szName是私有的,无法在类外访问
e.setName("Tom");
e.salary = 1000; // salary是公有的,可以类外访问
return 0;
}
成员函数的重载与参数缺省:和普通函数一样,类的成员函数也是可以重载和进行参数缺省的,但是要注意避免二义性,详情参考从 C 到 C++:03 C++的函数 。