一、结构化程序设计
结构化程序设计方法,也称为面向过程的设计方法。它强调数据类型和程序结构,注重程序的易读性、可靠性和可维护性。
在结构化程序设计中,采用 自顶向下
、逐步求精
及模块化
的思想。
程序设计的过程基本上就是编写函数的过程。
程序基本上都含有顺序
、选择
和循环
3种基本控制结构。
程序化结构设计主要强调的就是程序的易读性。
基本思想:数据结构+算法=程序。
二、面向对象程序设计的概念和特点
是20世纪90年代以来软件开发方法的主流。
所谓面向对象的程序设计方法,就是使分析、设计和实现一个系统的方法尽可能地接近人们认识一个系统的方法。通常包括:面向对象的分析
、面向对象的设计
和面向对象的程序设计
。
对象具有两个特性:
1.状态:是指对象本身的信息,也称为属性。
2.行为:是对对象的操作。
类是面向对象程序设计方法中的程序主体。
面向对象的程序设计有:抽象
、封装
、继承
和多态
4个基本特点。
在面向对象程序设计中,将一组数据和这组数据有关的操作集合组装在一起形成对象,叫做抽象。
对象的特点:属性和操作。
把对象的属性和操作结合成一个独立的系统单位,并尽可能隐蔽对象的内部细节叫做封装。
C++语言通过建立用户定义的类来支持数据封装和信息隐藏。
继承是面向对象程序设计的一个重要特性,是软件复用的一种形式,它允许在原有类的集成上创建新的类。
多态是指不同种类的对象都具有名称相同的行为,而具体行为的实现方式却有所不同。
三、类的初步认识
在C++中,向int或double这样的类型是系统预定义的,称为基本数据类型。
类以数据为中心,把相关的一批函数组成为一体。
定义类以称为说明类。
在C++中,类定义的一般格式
class 类名
{
访问范围说明符:
成员变量1
成员变量2
...
成员函数声明1
成员函数声明2
...
访问范围说明符:
更多成员变量
更多成员函数声明
...
};
类以关键字class开始,后面是类名。类名的定义遵循一般的标识符命名规则,即字母、下划线和数字的组合,大小写敏感,但不能以数字开头,也不能和系统中使用的关键字完全相同。
类是具有唯一标识符的实体,类名不能重复。
访问范围说明符一共有public(公有)
、private(私有)
和protected(保护)
3种。
成员变量是类中的一类成员,个数不限,也称为数据成员。代表对象的属性。声明方式与普通变量的声明相同。
在C++98标准下,类中声明的任何成员不能使用auto、extern和register关键字进行修饰。
如果成员函数定义在类体外,则类体内必须要有函数原型,类体外函数定义的前面必须用“类名::"来限定
返回值类型 类名::成员函数名(参数列表)
{
成员函数的函数体
}
在一般情况下,将类的成员变量声明为私有的,以便隐藏数据。
程序2-1定义一个表示日期的类myDate。3个基本属性:年、月、日,用year、month和day表示。
程序2-1 定义日期类myDate
#include <iostream>
using namespace std;
class myDate
{
public:
myDate(); //构造函数
myDate(int,int,int); //构造函数
void setDate(int,int,int); //设置日期
void setDate(myDate); //设置日期
myDate getDate(); //获取日期
void setYear(int); //设置年
int getMonth();//获取月
void printDate() const; //打印日期
private:
int year,month,day; //成员变量,表示年、月、日
};
//在类体外定义成员函数
myDate::myDate()
{
year = 1997,month = 2,day = 12;
}
myDate::myDate(int y,int m,int d)
{
year = y;month = m;day = d;
}
void myDate::setDate(int y,int m,int d)
{
year=y;month=m;day=d;
return;
}
void myDate::setDate(myDate oneD)
{
year=oneD.year;month=oneD.month;day=oneD.day;
return;
}
myDate myDate::getDate()
{
return *this;
}
void myDate::setYear(int y){
year = y;
return;
}
int myDate::getMonth()
{
return month;
}
void myDate::printDate() const
{
cout<<year<<"/"<<month<<"/"<<day;
return;
}
程序2-2 定义学生类Student
class Student
{
public:
void setStudent(string,myDate); //设置学生信息
void setName(string); //设置学生姓名
string getName(); //获取姓名
void setBirthday(myDate); //设置生日
myDate getBirthday(); //获取生日
void printStudent() const; //打印信息
private:
string name; //姓名
myDate birthday; //生日
};
//在类体外定义成员函数
void Student::setStudent(string s,myDate d)
{
name = s;
birthday.setDate(d);
return;
}
void Student::setName(string n)
{
name = n;
return;
}
string Student::getName()
{
return name;
}
void Student::setBirthday(myDate d)
{
birthday.setDate(d);
return;
}
myDate Student::getBirthday()
{
return birthday;
}
void Student::printStudent() const
{
cout<<"姓名:"<<name<<"\t生日:";
birthday.printDate(); //调用类myDate的成员函数
cout<<endl;
}
四、类的示例程序剖析
(一)、程序结构
一个完整的C++程序包括以下儿部分。
●一个主函数,可以调用其他函数,但不能被调用,也称为主程序。
●用户定义的任意多个的类及全局函数。
●全局说明。在所有函数和类定义之外的变量说明及函数原型。
●注释。
●头文件。
从逻辑关系上看,典型的C++程序的结构包括类的定义
、类中成员函数的实现
和主函数main
。
成员变量一般均定义为私有访问权限,仅能在本类内访问。如果要从类外访问,则需要为成员变量定义相应的访问函数,然后通过访问函数来访问私有的成员变量。
实现成员函数时要指明类的名称,
返回值类型 类名::函数成员名(参数表)
{
函数体
}
定义一个普通对象,即类变量的基本方法有两种。
(1)
类名 对象名;
或是
类名 对象名(参数);
或是
类名 对象名 = 类名(参数);
(2)
类名 *对象指针名 = new 类名;
或是
类名 *对象指针名 = new 类名();
或是
类名 *对象指针名 = new 类名(参数);
用new创建对象时返回的是一个对象指针,这个指针指向本类刚创建的这个对象。
C++分配给指针的仅仅是存储指针值的空间,而对象所占用的空间分配在堆上。
声明对象引用即变量别名的基本格式
类名 &对象引用名 = 对象;
声明对象指针,即指向对象的指针的基本格式
类名 对象指针名 = 对象的地址;
声明对象数组的格式
类名 对象数组名[数组大小];
同类型的对象之间可以相互赋值。例如,定义了类C后,
C a1,b1; //定义了C类的对象a1和b1
C *p = &a1; //定义了指向对象a1的C类类型的指针p
C &R = b1; //定义了C类类型对象b1的引用R
C A[3]; //定义了C类类型对象的数组A,含3个元素
程序运行中,创建对象就是为对象分配内存。
五、访问对象的成员
使用对象访问成员变量与调用成员函数
通过对象访问成员变量的一般格式:
对象名.成员变量名
调用成员函数的格式
对象名.成员函数名(参数表)
例如,可以写一个驱动程序。
程序2-3 验证类功能的驱动程序
#include <iostream>
#include <string>
#include "myDate.cpp";
#include "Student.cpp";
using namespace std;
int main() {
Student ss;
int y,m,d;
string name_;
cout<<"请输入学生的姓名和生日,生日以\”年 月 日\"的次序输入:";
cin>>name_>>y>>m>>d;
ss.setStudent(name_,myDate(y,m,d));
ss.printStudent();
return 0;
}
请输入学生的姓名和生日,生日以”年 月 日"的次序输入:
薛怀 1997 02 12
姓名:薛怀 生日:1997/2/12
使用指针访问对象的成员
如果是通过指针访问成员变量,则点运算符.换位箭头运算符->
指针->成员名
程序2-4 使用指针方式的驱动程序
#include <iostream>
#include <string>
#include "myDate.cpp";
#include "Student.cpp";
int main()
{
Student ss;
int y,m,d;
string name_;
Student *sp = &ss; //指向ss的指针sp
cout<<"请输入学生的姓名和生日,生日以\”年 月 日\"的次序输入:";
cin>>name_>>y>>m>>d;
sp->setStudent(name_,myDate(y,m,d));
sp->printStudent();
return 0;
}
使用引用访问对象的成员
可以在程序中直接定义引用并进行初始化。
程序2-5 使用引用方式的驱动程序
#include <iostream>
#include <string>
#include "myDate.cpp";
#include "Student.cpp";
int main()
{
Student ss;
int y,m,d;
string name_;
Student &sy = ss; //ss的别名sy
cout<<"请输入学生的姓名和生日,生日以\”年 月 日\"的次序输入:";
cin>>name_>>y>>m>>d;
sy.setStudent(name_,myDate(y,m,d));
sy.printStudent();
return 0;
}
六、类成员的可访问范围
访问范围说明符的含义
public的含义是公有的,使用它修饰的类的成员可以在程序的任何地方被访问。
private的含义是私有的,使用它修饰的类的成员仅能在本类内被访问。
protected的含义是保护的,它的作用介于public和private之间,使用它修饰的类的成员能在本类内及子类中被访问。
如果某个成员前面没有访问范围说明符,则默认该成员为私有成员。
例2-7 访问范围说明符
class Line
{
private:
double length;
public:
void setLength(double);
double getLength();
private:
double area;
bool isEmpty();
};
例2-8
class A
{
int m,n;
public:
int a,b;
int func1();
private:
int c,d;
void func2();
public:
char e;
int f;
int func3();
};
成员的访问
程序2-6 类成员的访问
#include <iostream>
using namespace std;
class Box
{
public: //公有的
double length;
void setWidth(double wid);
double getWidth();
private: //私有的
double width;
};
//类体外定义成员函数
double Box::getWidth()
{
return width;
}
void Box::setWidth(double wid)
{
width = wid;
}
int main()
{
Box box; //声明一个对象
//不使用成员函数设置长度
box.length = 10.0; //正确,因为length是公有的
cout<<"Length of box:"<< box.length<<endl; //输出Length of box:10
//不使用成员函数设置宽度
// box.width = 10.0; //错误,因为width是私有的
box.setWidth(10.0); //必须使用成员函数设置宽度
cout<<"Width of box:"<<box.getWidth()<<endl; //输出Width of box:10
return 0;
}
程序2-7 类成员访问示例
#include <iostream>
#include <string>
using namespace std;
class CEmployee
{
private:
string szName; //姓名
int salary; //工资
public:
void setName(string); //设置姓名
string getName(); //获取姓名
void setSalary(int); //设置工资
int getSalary(); //获取工资
int averageSalary(CEmployee); //计算两人的平均工资
};
void CEmployee::setName(string name)
{
szName = name;
}
string CEmployee::getName()
{
return szName;
}
void CEmployee::setSalary(int mon)
{
salary = mon;
}
int CEmployee::getSalary()
{
return salary;
}
int CEmployee::averageSalary(CEmployee e1)
{
return (salary + e1.getSalary())/2;
}
int main()
{
CEmployee eT,eY;
//eT.szName = "Tom1234567"; //编译错误,不能直接访问私有成员
eT.setName("Tom1234567"); //需要通过公有成员函数访问
//eT.salary = 5000; //编译错误,不能直接访问私有成员
eT.setSalary(5000);
cout<<eT.getName()<<endl;
eY.setName("Yong7654321"); //需要通过公有成员函数访问
eY.setSalary(3500);
cout<<eY.getName()<<endl;
cout<<"aver="<<eT.averageSalary(eY)<<endl;
return 0;
}
输出结果:
Tom1234567
Yong7654321
aver=4250
隐藏的作用
设置私有成员的机制叫做“隐藏”。目的是强制对私有成员变量的访问一定要通过公有成员函数进行。
假设需要修改程序2-7,例如,在系统内部对姓名统一加一个前缀“E-”,但不对外展示这个前缀,只需要修改函数setName()和getName()
void CEmployee::setName(string name)
{
szName = "E-" + name;
cout<<"name="<<szName<<endl;
}
string CEmployee::getName()
{
return szName.substr(2);
}
七、标识符的作用域与可见性
标识符的作用域是指标识符的有效范围,即它在程序中的存在区域。
标识符的可见性是指在程序的哪个区域里可以使用。
C++中标识符的作用域有函数原型作用域
、局部作用域(块作用域)
、类作用域
和命名空间作用域
。
函数原型作用域
是C++程序中最小的作用域。在声明函数原型时形参的作用范围就是函数原型作用域。例如
double ares(double radius);
局部作用域
程序中使用相匹配的一对大括号括起来的一段程序称为块。作用域局限在块内的称为局部作用域。
具有局部作用域的变量也称为局部变量。
类作用域
命名空间作用域
具有命名空间作用域的变量也称为全局变量。
对于在不同的作用域声明的标识符,可见性的一般原则如下:
●标识符要声明在前,引用在后。
●在同一个作用域中,不能声明同名的标识符。在没有互相包含关系的不同作用域中声明的同名标识符,互不影响。
●如果存在两个或多个具有包含关系的作用域,外层声明了一个标识符,而内层没有再次声明同名标识符,那么外层标识符在内层仍然可见。如果在内层声明了同名标识符,则外层标识符在内层不可见,这时称内层标识符隐藏了外层同名标识符,这种机制称为隐藏规则。
程序2-8 作用域隐藏规则
#include <iostream>
using namespace std;
int main()
{
int a = 1;
cout<<a<<"\n";
for(int i = 1;i<2;i++)
{
int a = 2;
cout<<a<<"\n";
}
cout<<a<<"\n";
return 0;
}
例题,输出程序结果
#include <iostream>
using namespace std;
class Test
{
int a,b;
int getmin()
{
return (a<b?a:b);
}
public:
int c;
void setValue(int x1,int x2,int x3)
{
a=x1;b=x2;c=x3;
}
int GetMin();
};
int Test::GetMin()
{
int d = getmin();
return (d = d<c?d:c);
}
int main()
{
Test t1;
t1.setValue(34,6,2);
cout<<t1.GetMin()<<endl;
}
输出结果:
2
#include <iostream>
using namespace std;
class MyClassType1
{
private:
int x,y;
public:
int getx()
{
return x;
}
int gety();
void setx(int x0)
{
x = x0;
}
void sety(int y0);
void displayx()
{
cout<<"x="<<x<<endl;
}
void displayy()
{
cout<<"y="<<y<<endl;
}
};
int MyClassType1::gety()
{
return y;
}
void MyClassType1::sety(int y0)
{
y = y0;
}
int main()
{
MyClassType1 obj1,*p,objArr[10];
obj1.setx(111);
cout<<obj1.getx()<<endl;
obj1.displayx();
p = new MyClassType1;
(*p).setx(56);
p->sety(78);
int k = (*p).getx();
int m = p->gety();
cout<<"k="<<k<<endl;
cout<<"m="<<m<<endl;
for(int i = 0;i<5;i++)
{
objArr[i].setx(i+10);
objArr[i].sety(i+20);
}
p = &objArr[9];
while(p>=&objArr[5])
{
p->setx(88);
p->sety(99);
p--;
}
for(int i = 0;i<10;i++)
{
cout<<objArr[i].getx()<<" "<<objArr[i].gety()<<endl;
}
}
输出结果:
111
x=111
k=56
m=78
10 20
11 21
12 22
13 23
14 24
88 99
88 99
88 99
88 99
88 99
程序设计
/*
* 04737 c++ 自学考试2019版 第二章课后练习
* 程序设计题 1
* 需求:设计并实现一个类Course.它代表学校中的一门课程.....
*/
//标准流
#include<iostream>
//标准字符
#include<string>
using namespace std;
class Course{
private:
//课程名
string courseName;
//学分
int score;
//学时数
int hours;
//课程类别
string category;
//授课专业
string professional;
public:
//无参构造器
Course();
//有参构造器
Course(string courseName,string category,string professional,int score,int hours);
//声明getter
string getCourseName();
string getCategory();
string getProfessional();
int getScore();
int getHours();
//声明setter
void setCourseName(string str);
void setCategory(string str);
void setProfessional(string str);
void setScore(int a);
void setHours(int a);
//声明 打印所有数据函数
void showInfo();
};
//定义无参构造
Course::Course()
{
cout<<"The no-argument constructor is running"<<endl;
}
//定义有参构造
Course::Course(string courseName_,string category_,string professional_,int score_,int hours_)
{
courseName = courseName_;
category = category_;
professional = professional_;
score = score_;
hours = hours_;
}
//定义 getter
string Course::getCourseName(){return courseName;}
string Course::getCategory(){return category;}
string Course::getProfessional(){return professional;}
int Course::getScore(){return score;}
int Course::getHours(){return hours;}
//定义 setter
void Course::setCourseName(string str){courseName = str;}
void Course::setCategory(string str){category = str;}
void Course::setProfessional(string str){professional = str;}
void Course::setScore(int a){score = a;}
void Course::setHours(int a){hours = a;}
//定义 打印所有数据函数
void Course::showInfo()
{
cout<<"print all the infomation"<<endl;
cout<<"courseName="<<courseName<<endl;
cout<<"category="<<category<<endl;
cout<<"professional="<<professional<<endl;
cout<<"score="<<score<<endl;
cout<<"hours="<<hours<<endl;
}
//主函数测试
int main()
{
Course test("c++程序设计","c++","计算机科学技术",80,60);
test.showInfo();
}
输出结果
print all the infomation
courseName=c++程序设计
category=c++
professional=计算机科学技术
score=80
hours=60