广州大学程序设计基础实验报告二

广州大学学生实验报告

                                        报告日期:  

学院

年级/专业/班

姓名

学号

实验课程名称

程序设计基础(实验课)

成绩

实验项目名称

实验2 函数

指导

老师

一、实验目的及要求

1.掌握函数的定义方法,及函数调用的形式;

2.掌握函数实参与形参的对应关系,“值传递”与“地址传递”的方式与区别;

3.掌握函数的应用方法,熟悉函数的嵌套调用和递归调用的设计方法;

4.了解全局变量、局部变量、动态变量及静态变量的概念和使用方法;

5.综合应用顺序结构选择结构循环结构的设计方法设计函数和程序。

二、实验设备与平台

1. 实验设备:计算机

2. 平台:Windows操作系统,Microsoft Visual C++或其它合适的C++编程环境。

三、实验内容及步骤

编写程序,解下列问题,然后把编写的程序代码和运行结果截图复制到题目后面的空白处。

1、求三角形的面积。已知三角形的三边a、b、c,则三角形的面积为

其中,s=(a+b+c)/2。

(1)三角形的三边的边长由cin输入,需要判断这三边是否构成一个三角形。若是,则计算其面积并输出,否则输出“错误:不能构成三角形!”。

(2)程序中要包含两个函数,一个函数判断是否构成三角形,另一个函数计算三角形的面积。

程序代码:

// 程序设计基础实验2 函数

// 问题描述:

/*1、求三角形的面积。已知三角形的三边a、b、c,则三角形的面积为

     area = sqrt(s*(s-a)*(s-b)*(s-c))

     其中,s = (a + b + c) / 2。

(1)三角形的三边的边长由cin输入,需要判断这三边是否构成一个三角形。

     若是,则计算其面积并输出,

     否则输出“错误:不能构成三角形!”。

(2)程序中要包含两个函数,

     一个函数判断是否构成三角形,

     另一个函数计算三角形的面积。*/

#include<iostream>

using namespace std;

bool IsTriangle(double a, double b, double c);  //判断是否构成三角形

double GetArea(double a, double b, double c);   //获取三角形的面积

int main()

{

    //声明三角形的三条边、三角形的面积变量

    double a, b, c, area;

    cout << "请输入三角形的三条边a、b、c:" << endl;

    cin >> a >> b >> c;

    if (IsTriangle(a, b, c))  //判断输入的三条边是否能构成三角形

    {

        area = GetArea(a, b, c);  //计算三角形面积

        cout << "三角形的面积为:" << area << endl;

    }

    else

    {

        cout << "错误:不能构成三角形!" << endl;

    }

return 0;

}

//判断是否构成三角形

bool IsTriangle(double a, double b, double c)

{

    if (a > 0 && b > 0 && c > 0)  //三条边均需要大于零

    {

        if (a + b > c && a + c > b && b + c > a)  //两边之和大于第三边

        {

            return 1;

        }

        else

            return 0;

    }

    else

        return 0;

}

//获取三角形的面积

double GetArea(double a, double b, double c)

{

    double s = (a + b + c) / 2;

    double area = sqrt(s * (s - a) * (s - b) * (s - c));  //三角形面积计算公式

    return area;

}

运行结果截图:

案例1:(确定构成三角形)

心得与体会:

1、本题是一个很好的题目,它告诉我们,在做一件事或者是求解一样东西时,需要先判断前提条件是否成立,若条件都不成立,那么求解就没有意义了。例如,本题中的求解三角形面积,则先需要判断输入的边是否构成三角形。

2、编程求下式值,其中ni用函数来实现,且设参数n的默认值为2:

 

程序代码:

// 程序设计基础实验2 函数

// 问题描述:

/*2、编程求下式值,其中ni用函数来实现,且设参数n的默认值为2:

   n^1+n^2+n^3+n^4+n^5+n^6+n^7+n^8+n^9+n^10,n = 1,2,3*/

// 分析可得:如上为等比数列求和,公比q = n, 求和项的个数"n" = 10

// 等比数列求和公式:S = a1*(1-q^n)/(1-q),其中a1为首项,q为公比,n为求和项的个数

#include<iostream>

#include <cmath>  //使用函数pow()需要包含该头文件

using namespace std;

int Func(int n = 2);   //获取三角形的面积

int main()

{

    //声明自变量、计算结果

    int n, result1, result3;

    //数据初始化

    result1 = 0;

    result3 = 0;

    n = 1;

    result1 = Func(n);

    cout << "当n为1时,求解的结果为:" << result1 << endl;

    //函数参数为缺省时,n为2

    cout << "当函数缺省时(n默认为2),求解的结果为:" << Func() << endl;

    n = 3;

    result3 = Func(n);

    cout << "当n为3时,求解的结果为:" << result3 << endl;

}

//计算求和结果

int Func(int n)

{

    //int a1 = n ^ 1;  //首项  //此写法错误,原因是:在C++中^为异或运算,不是指数的符号

    int a1 = n;      //首项

    int q = n;       //公比

    int num = 10;    //求和项的个数

    int S = 0;       //等比数列求和结果

    if (q == 1)      //注意需要分类讨论,当q的值为1时

    {

        S = num * a1;  //计算求和结果

    }

    else             //当q的值不为1时

    {

        //S = a1 * (1 - q ^ num) / (1 - q);  //不能直接使用^运算符

        S = a1 * (1 - pow(q, num)) / (1 - q);  //计算求和结果

    }

    return S;

}

运行结果截图:

心得与体会:

  1. 本题中采用了缺省的函数,我在平时写作业中比较少用到函数缺省参数。这次实验很好地让我重拾了函数缺省的写法。
  2. 本题中,我直接运用了高中数学中的等比数列的公式进行计算,提高算法效率。
  3. 在运用高中数学公式中,需要对参数n进行分类讨论。当n为1时,采用一种公式,当n不为1时,采用另外一种公式。
  4. 在编码过程中,我发生了编写错误。原因:之前暑假经常使用matlab进行编程,习惯了指数运算直接使用^,但这在C++中是不允许的。需要使用函数pow()来进行指数运算。

 3、用递归法将一个整数n转换成字符串。如输入1234,应输出字符串“1234”。n的位数不确定,可以是任意位数的整数。

程序代码:

// 程序设计基础实验2 函数

// 问题描述:

/* 3、用递归法将一个整数n转换成字符串。

      如输入1234,应输出字符串“1234”。

      n的位数不确定,可以是任意位数的整数。*/

#include <iostream>

using namespace std;

// 递归函数,将整数n转换为字符串s,同时使用index跟踪字符串的当前位置

void IntToString(int n, char*& s, int& index);

int main()

{

    int num = 0;  //整数num

    char* s = NULL;  //指针s初值置为空

    cout << "请输入一个整数:" << endl;

    cin >> num;

    int digits = num == 0 ? 1 : int(log10(abs(num))) + 1;  //获取输入数据的位数

    //依据整数的正负号,分别划分不同大小的数组

    if (num >= 0)

    {

        s = new char[digits + 1];  //动态创建一个数组

    }

    else

    {

        s = new char[digits + 2];  //动态创建一个数组,比正整数多一位,用于存储负号

    }

    int index = 0; // 用于跟踪字符串位置的索引

    if (s)  //内容申请成功

    {

        IntToString(num, s, index);  //调用函数,将整数转换为字符串

        s[index] = '\0';  //添加串结束符

        cout << "转换后的字符串为:" << endl;

        cout << s << endl;

        delete[] s;  //释放s所指存储空间

        s = NULL;  //对指针变量赋NULL,清除其无意义的地址值

    }

    else  //内存申请失败

    {

        cout << "转换失败:内存分配错误" << endl;

    }

}

//整数转为字符函数

void IntToString(int n, char*& s, int& index)

{

    if (n < 0)

    {

        s[index] = '-';  //存储整数符号

        index++;         //更新索引

        n = abs(n);      //取绝对值

    }

    if (n < 10)  //数据仅为1位时

    {

        s[index] = '0' + n;  //计算出一个字符值,其ASCII码值等于'0'的ASCII码值加上(n % 10)的值

    }

    else  //数据大于1位时

    {

        IntToString(n / 10, s, index);  //递归调用函数,不断缩小整数范围,以处理更高位的数字

        s[index] = '0' + (n % 10);  //逐个将整数的每位字符添加到下标为index的动态字符数组中

    }

    index++;  //更新索引,指向下一个位置

}

运行结果截图:

案例1:(正整数转字符串)、

心得与体会:

  1. 原先我使用的是固定的字符数组进行存储整数转换后的字符串。但这并不符合题目“任意位数的整数”的要求。于是,我采用了动态数组的方法进行存储
  2. 程序中隐含了两种范围的整数:非负数和负数。负数除了要求存储数位外,还要存储符号位:负号。这是容易在编程中遗漏的。

4、编写程序,计算下面公式并输出结果。

(1)编写一个函数计算n!

(2)编写主函数,由键盘输入n和m,调用(1)中的函数完成计算。

(3)输入n和m要给出提示,并检查n和m的合理性,不合理的输入应输出错误信息,并不再进行计算。

(4)运行程序,输出计算

程序代码:

// 程序设计基础实验2 函数

// 问题描述:

/* 4、编写程序,计算下面公式并输出结果。

      (1)编写一个函数计算n!

      (2)编写主函数,由键盘输入n和m,调用(1)中的函数完成计算。

      (3)输入n和m要给出提示,并检查n和m的合理性,不合理的输入应输出错误信息,并不再进行计算。

      (4)运行程序,输出计算:C85,C52,C70 */ 

#include<iostream>

using namespace std;

int getFactorial(int n);  //获取n的阶层

int main()

{

    //声明自变量、计算结果

    int n, m, result;

    //数据初始化

    n = m = result = 0;

    

    cout << "请分别输入排列组合中元素总数n、选择元素的个数m:(要求0=<m<=n)" << endl;

    cin >> n >> m;

    //检查n和m的合理性

    if (n < 0 || m < 0)

    {

        cout << "出错!n和m的取值均应为大于等于零的数" << endl;

        cout << "程序中断,不再进行运算" << endl;

    }

    else if (m > n)

    {

        cout << "出错!m的取值不能大于n" << endl;

        cout << "程序中断,不再进行运算" << endl;

    }

    else  //n和m均合理,进行计算操作

    {

        if (m == 0)  //特别地,当m=0时,排列取值为1

        {

            result = 1;

        }

        else

        {

            result = getFactorial(n) / (getFactorial(n - m) * getFactorial(m));

        }

        cout << "C(" << n << "," << m << ") = " << result << endl;

    }

}

//获取n的阶层

int getFactorial(int n)

{

    if (n == 1)

        return 1;

    else

        return n * getFactorial(n - 1);  //递归调用求阶层的函数

}

运行结果截图:

心得与体会:

  1. 计算阶层过程中用到了递归的思想,递归是求解大问题分解为结构相同的子问题,子问题范围逐渐缩小,最终得到一个结果,然后再逐级返回。

2、在进行排列组合运算时,同样需要对n和m进行范围检测,符合范围的才能进行运算。

  • 32
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值