一、結構化程序設計
結構化程序設計方法,也稱為面向過程的設計方法。它強調(diào)數(shù)據(jù)類型和程序結構,注重程序的易讀性、可靠性和可維護性。
在結構化程序設計中,采用 自頂向下、逐步求精及模塊化的思想。
程序設計的過程基本上就是編寫函數(shù)的過程。
程序基本上都含有順序、選擇和循環(huán)3種基本控制結構。
程序化結構設計主要強調(diào)的就是程序的易讀性。
基本思想:數(shù)據(jù)結構+算法=程序。
二、面向?qū)ο蟪绦蛟O計的概念和特點
是20世紀90年代以來軟件開發(fā)方法的主流。
所謂面向?qū)ο蟮某绦蛟O計方法,就是使分析、設計和實現(xiàn)一個系統(tǒng)的方法盡可能地接近人們認識一個系統(tǒng)的方法。通常包括:面向?qū)ο蟮姆治?/code>、面向?qū)ο蟮脑O計和面向?qū)ο蟮某绦蛟O計。
對象具有兩個特性:
1.狀態(tài):是指對象本身的信息,也稱為屬性。
2.行為:是對對象的操作。
類是面向?qū)ο蟪绦蛟O計方法中的程序主體。
面向?qū)ο蟮某绦蛟O計有:抽象、封裝、繼承和多態(tài)4個基本特點。
在面向?qū)ο蟪绦蛟O計中,將一組數(shù)據(jù)和這組數(shù)據(jù)有關的操作集合組裝在一起形成對象,叫做抽象。
對象的特點:屬性和操作。
把對象的屬性和操作結合成一個獨立的系統(tǒng)單位,并盡可能隱蔽對象的內(nèi)部細節(jié)叫做封裝。
C++語言通過建立用戶定義的類來支持數(shù)據(jù)封裝和信息隱藏。
繼承是面向?qū)ο蟪绦蛟O計的一個重要特性,是軟件復用的一種形式,它允許在原有類的集成上創(chuàng)建新的類。
多態(tài)是指不同種類的對象都具有名稱相同的行為,而具體行為的實現(xiàn)方式卻有所不同。
三、類的初步認識
在C++中,向int或double這樣的類型是系統(tǒng)預定義的,稱為基本數(shù)據(jù)類型。
類以數(shù)據(jù)為中心,把相關的一批函數(shù)組成為一體。
定義類以稱為說明類。
在C++中,類定義的一般格式
class 類名
{
訪問范圍說明符:
成員變量1
成員變量2
...
成員函數(shù)聲明1
成員函數(shù)聲明2
...
訪問范圍說明符:
更多成員變量
更多成員函數(shù)聲明
...
};
類以關鍵字class開始,后面是類名。類名的定義遵循一般的標識符命名規(guī)則,即字母、下劃線和數(shù)字的組合,大小寫敏感,但不能以數(shù)字開頭,也不能和系統(tǒng)中使用的關鍵字完全相同。
類是具有唯一標識符的實體,類名不能重復。
訪問范圍說明符一共有public(公有)、private(私有)和protected(保護)3種。
成員變量是類中的一類成員,個數(shù)不限,也稱為數(shù)據(jù)成員。代表對象的屬性。聲明方式與普通變量的聲明相同。
在C++98標準下,類中聲明的任何成員不能使用auto、extern和register關鍵字進行修飾。
如果成員函數(shù)定義在類體外,則類體內(nèi)必須要有函數(shù)原型,類體外函數(shù)定義的前面必須用“類名::"來限定
返回值類型 類名::成員函數(shù)名(參數(shù)列表)
{
成員函數(shù)的函數(shù)體
}
在一般情況下,將類的成員變量聲明為私有的,以便隱藏數(shù)據(jù)。
程序2-1定義一個表示日期的類myDate。3個基本屬性:年、月、日,用year、month和day表示。
程序2-1 定義日期類myDate
#include <iostream>
using namespace std;
class myDate
{
public:
myDate(); //構造函數(shù)
myDate(int,int,int); //構造函數(shù)
void setDate(int,int,int); //設置日期
void setDate(myDate); //設置日期
myDate getDate(); //獲取日期
void setYear(int); //設置年
int getMonth();//獲取月
void printDate() const; //打印日期
private:
int year,month,day; //成員變量,表示年、月、日
};
//在類體外定義成員函數(shù)
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; //生日
};
//在類體外定義成員函數(shù)
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(); //調(diào)用類myDate的成員函數(shù)
cout<<endl;
}
四、類的示例程序剖析
(一)、程序結構
一個完整的C++程序包括以下兒部分。
●一個主函數(shù),可以調(diào)用其他函數(shù),但不能被調(diào)用,也稱為主程序。
●用戶定義的任意多個的類及全局函數(shù)。
●全局說明。在所有函數(shù)和類定義之外的變量說明及函數(shù)原型。
●注釋。
●頭文件。
從邏輯關系上看,典型的C++程序的結構包括類的定義、類中成員函數(shù)的實現(xiàn)和主函數(shù)main。
成員變量一般均定義為私有訪問權限,僅能在本類內(nèi)訪問。如果要從類外訪問,則需要為成員變量定義相應的訪問函數(shù),然后通過訪問函數(shù)來訪問私有的成員變量。
實現(xiàn)成員函數(shù)時要指明類的名稱,
返回值類型 類名::函數(shù)成員名(參數(shù)表)
{
函數(shù)體
}
定義一個普通對象,即類變量的基本方法有兩種。
(1)
類名 對象名;
或是
類名 對象名(參數(shù));
或是
類名 對象名 = 類名(參數(shù));
(2)
類名 *對象指針名 = new 類名;
或是
類名 *對象指針名 = new 類名();
或是
類名 *對象指針名 = new 類名(參數(shù));
用new創(chuàng)建對象時返回的是一個對象指針,這個指針指向本類剛創(chuàng)建的這個對象。
C++分配給指針的僅僅是存儲指針值的空間,而對象所占用的空間分配在堆上。
聲明對象引用即變量別名的基本格式
類名 &對象引用名 = 對象;
聲明對象指針,即指向?qū)ο蟮闹羔樀幕靖袷?類名 對象指針名 = 對象的地址;
聲明對象數(shù)組的格式
類名 對象數(shù)組名[數(shù)組大小];
同類型的對象之間可以相互賦值。例如,定義了類C后,
C a1,b1; //定義了C類的對象a1和b1
C *p = &a1; //定義了指向?qū)ο骯1的C類類型的指針p
C &R = b1; //定義了C類類型對象b1的引用R
C A[3]; //定義了C類類型對象的數(shù)組A,含3個元素
程序運行中,創(chuàng)建對象就是為對象分配內(nèi)存。
五、訪問對象的成員
使用對象訪問成員變量與調(diào)用成員函數(shù)
通過對象訪問成員變量的一般格式:
對象名.成員變量名
調(diào)用成員函數(shù)的格式
對象名.成員函數(shù)名(參數(shù)表)
例如,可以寫一個驅(qū)動程序。
程序2-3 驗證類功能的驅(qū)動程序
#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 使用指針方式的驅(qū)動程序
#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 使用引用方式的驅(qū)動程序
#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的含義是私有的,使用它修飾的類的成員僅能在本類內(nèi)被訪問。
protected的含義是保護的,它的作用介于public和private之間,使用它修飾的類的成員能在本類內(nèi)及子類中被訪問。
如果某個成員前面沒有訪問范圍說明符,則默認該成員為私有成員。
例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;
};
//類體外定義成員函數(shù)
double Box::getWidth()
{
return width;
}
void Box::setWidth(double wid)
{
width = wid;
}
int main()
{
Box box; //聲明一個對象
//不使用成員函數(shù)設置長度
box.length = 10.0; //正確,因為length是公有的
cout<<"Length of box:"<< box.length<<endl; //輸出Length of box:10
//不使用成員函數(shù)設置寬度
// box.width = 10.0; //錯誤,因為width是私有的
box.setWidth(10.0); //必須使用成員函數(shù)設置寬度
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"); //需要通過公有成員函數(shù)訪問
//eT.salary = 5000; //編譯錯誤,不能直接訪問私有成員
eT.setSalary(5000);
cout<<eT.getName()<<endl;
eY.setName("Yong7654321"); //需要通過公有成員函數(shù)訪問
eY.setSalary(3500);
cout<<eY.getName()<<endl;
cout<<"aver="<<eT.averageSalary(eY)<<endl;
return 0;
}
輸出結果:
Tom1234567
Yong7654321
aver=4250
隱藏的作用
設置私有成員的機制叫做“隱藏”。目的是強制對私有成員變量的訪問一定要通過公有成員函數(shù)進行。
假設需要修改程序2-7,例如,在系統(tǒng)內(nèi)部對姓名統(tǒng)一加一個前綴“E-”,但不對外展示這個前綴,只需要修改函數(shù)setName()和getName()
void CEmployee::setName(string name)
{
szName = "E-" + name;
cout<<"name="<<szName<<endl;
}
string CEmployee::getName()
{
return szName.substr(2);
}
七、標識符的作用域與可見性
標識符的作用域是指標識符的有效范圍,即它在程序中的存在區(qū)域。
標識符的可見性是指在程序的哪個區(qū)域里可以使用。
C++中標識符的作用域有函數(shù)原型作用域、局部作用域(塊作用域)、類作用域和命名空間作用域。
函數(shù)原型作用域
是C++程序中最小的作用域。在聲明函數(shù)原型時形參的作用范圍就是函數(shù)原型作用域。例如
double ares(double radius);
局部作用域
程序中使用相匹配的一對大括號括起來的一段程序稱為塊。作用域局限在塊內(nèi)的稱為局部作用域。
具有局部作用域的變量也稱為局部變量。
類作用域
命名空間作用域
具有命名空間作用域的變量也稱為全局變量。
對于在不同的作用域聲明的標識符,可見性的一般原則如下:
●標識符要聲明在前,引用在后。
●在同一個作用域中,不能聲明同名的標識符。在沒有互相包含關系的不同作用域中聲明的同名標識符,互不影響。
●如果存在兩個或多個具有包含關系的作用域,外層聲明了一個標識符,而內(nèi)層沒有再次聲明同名標識符,那么外層標識符在內(nèi)層仍然可見。如果在內(nèi)層聲明了同名標識符,則外層標識符在內(nèi)層不可見,這時稱內(nèi)層標識符隱藏了外層同名標識符,這種機制稱為隱藏規(guī)則。
程序2-8 作用域隱藏規(guī)則
#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
* 需求:設計并實現(xiàn)一個類Course.它代表學校中的一門課程.....
*/
//標準流
#include<iostream>
//標準字符
#include<string>
using namespace std;
class Course{
private:
//課程名
string courseName;
//學分
int score;
//學時數(shù)
int hours;
//課程類別
string category;
//授課專業(yè)
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);
//聲明 打印所有數(shù)據(jù)函數(shù)
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;}
//定義 打印所有數(shù)據(jù)函數(shù)
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;
}
//主函數(shù)測試
int main()
{
Course test("c++程序設計","c++","計算機科學技術",80,60);
test.showInfo();
}
輸出結果
print all the infomation
courseName=c++程序設計
category=c++
professional=計算機科學技術
score=80
hours=60