c++精解和程序设计第六章

                                    第六章 模块化程序设计

6.1值和引用参数

6.1.1值调用参数与引用

值调用:一种把实参的值存储在被调函数的数据区的参数传递机制。
引用调用:一种把实参的地址存储在被调函数的数据区中的参数传递机制。

在形参列表中设置"&"(对引用参数),而不在实参列表中设置。此外,还必须在函数原型中插入符号"&",以指示第3个和第4个形参是引用函数,也为输出函数。
例子:void compute(float,float,float&,float&);

1).例子:计算和与平均值的函数

//计算和与平均值的函数
using namespace std;
//功能原型
void computeSumAve(float,float,float&,float&);
int main()
{
    float x,  //输入第一数
          y,  //输入第二数
          sum, //输出他们的和
          mean;  //输出他们的平均值
    cout<<"Enter 2 numbers: ";
    cin>>x>>y;
    //计算x和y的和和平均值
    computeSumAve(x,y,sum,mean);
    //显示结果
    cout<<"Sum is "<<sum<<endl;
    cout<<"Average is "<<mean<<endl;
    return 0;
}
//计算数字一和数字二的和和平均值
//首先:数字一和数字二被分配值
//发布:计算数字一和数字二的和和平均值,并且返回作为功能输出
void computeSumAve
(
        float num1,   //输入计算的值
        float num2,   //输入计算的值
        float& sum,    //输出数字一和数字二的和
        float& average)  //输出数字一和数字二的平均值
{
        sum=num1+num2;
        average=sum/2.0;
}//结束computeSumAve

排序:重新排列数据值,使它们成为有序序列。
2).例子:对3个数据进行排序的函数

//读三个数并排序为升序

6.1.2void类型的函数能够返回结果

void函数不能通过return语句的执行返回一个值,但可以允许函数通过输出参数返回结果。

6.1.3使用引用参数或值参数的时机

输入参数:用来从主调函数接收数据值的参数。
输出参数:用来把结果返回给2主调函数的参数。
输入/输出参数:一个从主调函数接收数据值并把一个值返回给主调函数的参数。

6.1.4程序风格——书写形参列表

先列出输入参数,其次是输入/输出参数,最后是输出参数。

6.1.5值参数和引用参数的比较

6.1.6值参数提供的保护

引用参数比值参数更易变化,因为不仅函数的执行会改变他们的值,而且在计算中也会使用它们。

6.1.7实参/形参列表对应关系回顾

实参/形参列表对应关系
1)参数个数相等。
2)每一个参数一一对应。
3)每个参数的类型不变。
4)可以用表达式(或者变量或者常量)作为相应值参的实参,但不能作为引用参数的实参。

6.2具有输入和输出参数的函数

例子:1)测试getFrac函数

//测试getFrac函数
#include<iostream>
using namespace std;
void getFrac(int&,int&);
int main()
{
    int num,    //输入-分数分子
        denom;  //输入-分数分母
    cout<<"Enter a common fraction"<<"as 2 integers separated by a slash: ";
    getFrac(num,denom);
    cout<<"Fraction is "<<num<<"/"<<denom<<endl;
    return 0;
}
//读一个分数
//pre:无
//post:返回分数分子通过分子
//     返回分数分母通过分母
void getFrac(int& numerator,  //输出
             int& denominator)   //输出
{
    char slash; //斜杠的临时存储
    cin>>numerator>>slash>>denominator;
}

2)对3个数据进行排序的函数

//对3个数据进行排序的函数
#include<iostream>
using namespace std;
//排序一组数据
void order(float&,float&); //输入输出-排序数字
int main()
{
    float num1,num2,num3; //输入-排序数字
    //读入3个数字
    cout<<"Enter 3 numbers to sort: ";
    cin>>num1>>num2>>num3;
    //排序他们
    order(num1,num2); //对数字一和数字二排序
    order(num1,num3);  //对数字一和数字三排序
    order(num2,num3);  //对数字二和数字三排序
    //显示结果
    cout<<"The three numbers in order are:"<<endl;
    cout<<num1<<" "<<num2<<" "<<num3<<endl;
    return 0;
}
//排序x和y
//pre:x和y是分配值
//post:x是最小的或者y是最大的
void order(float& x,float& y)  //输入输出-排序数字
{
    float temp;  //x的存储值
    //比较x和y,如果没有排序交换值
    if(x>y)
    {
        temp=x;
        x=y;
        y=temp;
    }
}//结束排序

6.3使用函数进行逐步设计

例子:1)用于一般求和与求平均值问题的main函数

//用于一般求和与求平均值问题的main函数
//File:computeSumAve.cpp
#include<iostream>
using namespace std;
//计算数据的和
float computeSum(int ); //输入-数字
//计算数据的平均值
float computeAve
      (int ,       //输入-数字
       float );    //输入-数字的和
//输出数字的项目,和和平均值
void printSumAve
     (int ,   //输入-数字
      float ,  //输入-数字的和
      float );   //输入-数字的平均值
int main()
{
    int numItems;  //输入-要添加的项目数
    float sum;  //输出-累加的数据总和
    float average;  //输出-被处理的数据的平均值
    //读入被处理的数据.
    cout<<"Enter the number of items to process: ";
    cin >> numItems;
    //计算数据的和.
    sum = computeSum(numItems);
    //计算数据的平均值.
    average = computeAve(numItems, sum);
    //输出数据的和和平均值.
    printSumAve(numItems, sum, average);

    return 0;
}
float computeSum(int numItems)
{
    float item; //输入:包含当前的数据项
    float sum; //输出:读入累加的数据项
    //读入每一个数据和累加数据
    sum=0.0;
    for(int count=0;count<numItems;count++)
    {
        cout<<"Enter a number to be added: ";
        cin>>item;
        sum+=item;
    }//结束
    return sum;
}//结束计算求和
float computeAve(int numItems,float sum)
{
    //计算数据的平均值
    if(numItems<1)  //测试无效输入
    {
        cout<<"Invalid value for numItems= "<<numItems<<endl;
        cout<<"Average not computed."<<endl;
        return 0.0; //返回无效输入
    }//结束if
    return sum/numItems;
}//结束computeAve
void printSumAve(int numItems,float sum,float average)
{
    //如果数据有效显示结果
    if(numItems>0)
    {
        cout<<"The number of items is "<<numItems<<endl;
        cout<<"The sum of the data is "<<sum<<endl;
        cout<<"The average of the data is "<<average<<endl;
    }
    else
    {
    cout<<"Invalid number of items= "<<numItems<<endl;
    cout<<"Sum and average are not defined."<<endl;
    cout<<"No printing done.Execution terminated."<<endl;
    }//结束if
}//结束printSumAve

6.3.1程序中标识符的多次声明

6.3.2程序风格——使用函数实现相对简单的算法步骤

main函数应当主要由一系列函数调用组成。

6.3.3程序风格——内聚函数

功能内聚性函数:只执行一个操作的函数。

6.4在函数中使用对象

c++的两种用函数修改对象的方法:
1)使用圆点表示法将一个成员函数应用于一个对象(也称为"向对象发送信息")。成员函数可以修改其所应用对象的一个或多个数据属性。
2)将对象作为参数传递给一个函数

例子:测试函数moneyToNumberstring

//测试函数moneyToNumberstring
#include<string>
#include<iostream>
using namespace std;

//功能原型
void moneyToNumberString(string&);
int main()
{
    string mString; //输入-一个"money"的字符
    cout<<"Enter a dollar amount with $ and commas: ";
    cin>>mString;
    moneyToNumberString(mString);
    cout<<"The dollar amount as a number is "<< mString<<endl;
    return 0;
}
//移动$和逗号到一个money字符串中.
//pre:moneyString被定义和可能包含逗号和以$开头.
//post:$和全部逗号被移动到moneyString.
void moneyToNumberString(string& moneyString) //输入输出-$和逗号的字符串
{
    //局部变量
    int posComma; //下一个逗点的位置
    //移动$到moneyString
    if(moneyString.at(0)=='$') //以$开始
      moneyString.erase(0, 1); //移动$
    else if(moneyString.find("-$")==0) //以-$开始
     moneyString.erase(1, 1);  //移动-$
     //移动全部的逗号
     posComma=moneyString.find(",");  //发现第一个
     while(posComma>=0&&posComma<moneyString.length()) //Is posComma valid
    {
        moneyString.erase(posComma,1); //移动,
        posComma=moneyString.find(",");  //发现下一个,
    }
}//结束 moneyToNumberString

6.5程序系统的调试和测试

6.5.1自顶向下测试和桩模块

自顶向下测试:测试main函数和它的子函数间的控制流。
桩模块:在测试控制流时使用的具有一个函数头和一个最小函数体的函数。
例子:computeSum函数的桩模块

float computeSum(int numItems) //输入-数据项
{
 cout<<"Function computeSum entered"<<endl;
 return 100.0;
}//结束computeSum stub

6.5.2自底向上测试和驱动器

单元测试:单个函数的测试。
自底向上测试:分别测试一个程序系统中的各个函数的过程。
系统集成测试:用已经预先测试过的函数取代系统的所有桩模块后对系统进行的测试。
例子:测试computeSum函数的驱动器函数

int main()
{
 int n;
 //保持调用computeSum和显示结果。
 do{
   cout<<"Enter number of items or 0 to quit: ";
   cin>>n;
   cout<<"The sum is "<<computeSum(n)<<endl;
  }while(n!=0);
  return 0;
}//结束驱动程序

6.5.3程序系统的调试提示

当调试一个程序系统时,下列建议是有益的
1)编写代码时,要使用注释仔细记载每个函数的参数与局部变量并描述其功能。
2)进入函数时,通过显示函数名,创建执行跟踪过程。
3)进入一个函数时,要跟踪或显示所有输入和输入/输出参数的值,并确认这些值是有意义的。
4)从一个函数返回后,跟踪或显示所有函数输出的值。通过手工计算,验证这些值是正确的。确保所声明的所有输入/输出参数和输出参数是引用参数(使用"&"符号)。
5)确保函数的桩模块为每个输出参数赋值。

6.5.4标识符的作用域和观察窗口变量

6.5.5黑盒测试与白盒测试

黑盒测试(或基于规范的测试):假设测试人员对代码一无所知的测试过程,测试人员必须将一个函数或系统的性能与它的规范进行比较。
白盒测试(玻璃盒测试):假定测试人员知道系统内部是如何编码的并且要求检查所有可能的执行路径的测试过程。

6.6递归函数

c++允许函数调用它自己,调用自身的函数是递归函数

递归函数的模板
(1)if达到停止事件
  (1.1)返回停止事件的值
  else
   (1.2)返回再次用不同的参数值调用该函数计算所得的值。

停止事件:一个递归函数中不再调用其他递归的可选任务。

伪代码:

(1)if n是0或1
   (1.1)返回1
   else
      (1.2)返回n*(n-1)!

递归回溯:从每次递归调用返回一个值的过程。
例子:1)递归函数factorial

//pre:n is >=0
//Returns:The product 1*2*3*...*n for n>1;
// otherwise 1.
int factorial(int n)
{
 if(n<=1)
   return 1;
  else
    return n*factorial(n-1);
}

2)迭代的factorial函数

//pre:n is >=0
//Returns: The product 1*2*3*....*n for n>1;
// otherwise 1.
int factorial(int n)
{
  int productSoFar;  //输出:累加的值
  //初始化累加值
  productSoFar=1;
  //显示递归对于i>1.
  productSoFar=productSoFar*i;
  return productSoFar;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
《C语言100例》是一本经典且实用的编程教材,共收录了100个C语言的编程示例,适合初学者与进阶者学习参考。这本书中的每个例子都涵盖了程序设计的基础知识,如变量、循环、条件判断等。同时,这些例子也展示了C语言的灵活性和强大的功能。 这本教材的编排方式很有趣味性,每个例子都有一个贴切的标题,让读者能够快速了解程序的主要功能和实现目标。在例子的解析部分,作者会对程序的每一部分进行详细的解释和分析,包括变量的定义、函数的调用、流程控制等内容。这样的解析有助于读者理解程序的逻辑和实现方式。 通过学习这本书,读者可以提高他们的编程能力,培养解决问题和设计程序的能力。同时,这本书还提供了一些扩展思考的题目,读者可以根据自己的兴趣和能力水平修改和优化程序。 《C语言100例》还有一个非常实用的特点,就是每个例子的程序代码都非常简洁明了,结构清晰。这不仅有助于初学者理解和掌握C语言的语法规则,也方便更有经验的程序员进行代码优化和重构。 总的来说,《C语言100例》是一本经典、实用且有趣的C语言编程教材。它通过100个例子向读者展示了C语言的基础知识和编程技巧,帮助读者提高编程能力和培养解决问题的能力。无论是初学者还是有经验的程序员,都能够从这本书中受益匪浅。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值