Accelerated C++学习笔记5―(组织程序和数据)(三)

2014-11-24 13:11:03 · 作者: · 浏览: 16
"median of an empty vector"); sort(vec.begin(), vec.end()); vec_sz mid = size/2; return size % 2 == 0 (vec[mid] + vec[mid - 1]) / 2 : vec[mid]; }
程序说明:我们需要把median函数放如一个名为median.cpp,或者median.C或者median.c文件中。
2)让median函数对其他用户也可用 标准库把其定义的名称放进头文件中,与之类似,我们可以编写自己的头文件,这样用户就可以使用我们定义的名称了
//使用median函数的一种较好的方法
#include "median.h"
#include 
        
          int main {……}
        

程序说明:如果我们在#include指令中使用了一个双引号而不是尖括号来把头文件名称括起来,那么就表示,为了替代#include指令,我们要求编译器把与此名称对应的头文件中所有内容都复制到我们的程序中。
3)写出头文件的声明
#ifndef GUARD_median_h
#define GUARD_median_h

#include 
        
          double median(vector
         
          ); #endif
         
        

程序说明 1)记住我们的median.h头不能单单包含这个声明,我们还需要把声明本身所用到的所有名称包含进去,所有必需加上vector 2)我们这里不适用using声明,因为我们的代码用户可能不想使用一个using std::vector的声明 2)我们需要注意一个细节,加上预处理程序,#ifndef指令检查GUARD_median_h是否被定义。
4、把计算成绩的程序分块 1)把Student_info结构与相关的函数组装起来 头文件:
#ifndef GUARD_Student_info
#define GUARD_Student_info

//Student_info.h 头文件

#include 
        
          #include 
         
           #include 
          
            struct Student_info { std::string name; double midterm, final; std::vector
           
             homework; }; bool compare(const Student_info&, const Student_info&); std::istream& read(std::istream&, Student_info&); std::istream& read_hw(std::istream&, std::vector
            
             &); #endif 
            
           
          
         
        

程序说明:注意这里我们在限定标准库的名称的时候所使用的是std::而不是using声明。
源文件:
#include "Student_info.h"

using std::istream;
using std::vector;

bool compare(const Student_info& x, const Student_info& y)
{
	return x.name < y.name;
}

istream& read(istream& is, Student_info& s)
{
	//读和储存学生的名字,期中和期末考试成绩
	is >> s.name >> s.midterm >> s.final;

	read_hw(is, s.homework); //读和储存家庭作业成绩
	return is;
}

//读一个家庭作业分数,储存在一个'vector
        
         '向量中 istream& read_hw(istream& in, vector
         
          & hw) { if(in) { //清除先前的内容 hw.clear(); //读家庭作业分数 double x; while (in >> x) hw.push_back(x); //清除the stream 保证可以工作到下一个学生 in.clear(); } return in; }
         
        

程序说明:源文件中使用using声明并没有问题,不像头文件,源文件对使用这些函数的程序没有影响。因此在源文件中使用using声明只不过是一个局部的决策罢了,不会影响到全局。
2)编写头文件来声明不同的grade重载函数 头文件:
#ifndef GUARD_grade_h
#define GUARD_grade_h

#include 
        
          #include "Student_info.h" double grade(double, double, double); double grade(double, double, const std::vector
         
          &); double grade(const Student_info&); double grade(const Student_info&); #endif
         
        

源文件:
#include 
        
          #include 
         
           #include "grade.h" #include "median.h" #include "Student_info.h" using std::domain_error; using std::vector; //计算一个vector
          
           类型的对象的中值 double median(vector
           
             vec) { typedef vector
            
             ::size_type vec_sz; vec_sz size = vec.size(); if(size == 0) throw domain_error("median of an empty vector"); sort(vec.begin(), vec.end()); vec_sz mid = size/2; return size % 2 == 0   (vec[mid] + vec[mid - 1]) / 2 : vec[mid]; } //根据期中、期末考试成绩和保存家庭作业的向量来计算学生的总成绩 double grade(double midterm, double final, const vector
             
              & hw) { if (hw.size() == 0) throw domain_error("student has done no homework"); return grade(midterm, final, median(hw)); } //需要读学生的姓名以及考试成绩 istream& read(istream& is, Student_info& s) { is >> s.name >> s.midterm >> s.final; read_hw(is, s.homework);//读入并储存学生的所有家庭作业成绩 return is; }
             
            
           
          
         
        

5、修正后的计算成绩的程序
// lesson4.2.cpp : 定义控制台应用程序的入口点。
//功能:修正后的计算成绩的程序
//时间:2014.5.12

#include "stdafx.h"
#include 
        
          #include 
         
           #include 
          
            #include 
           
             #include 
            
              #include "grade.h" #include "Student_info.h" using namespace std; int _tmain(int argc, _TCHAR* argv[]) { vector
             
               students; Student_info record; string::size_type maxlen = 0; //最长的姓名的长度 //读入并存储所有学生的数据 //不变式 // students 包含了所有的学生的记录 // max包含了students中最长的姓名 while (read(cin, record)) //找出最长的姓名的长度 {