第二章 函数
文章目录
第一节 函数的定义与使用
一、函数的定义
1、定义
函数是面向对象程序设计中,对功能的抽象
2、语法
int sum(int a,int b)
{
return int c=a+b;
}
// 返回值类型 函数名(形参列表)
//{
// 函数体;
// return ***; 无返回值就用void
//}
二、函数的调用
1、调用
- 调用前先声明函数:
- 若函数定义在调用点之前,则无需另外声明;
- 若函数定义在调用点之后,则需要在调用函数前按如下形式声明函数原型:
返回值类型 函数名(形参列表);
- 调用形式 : 函数名(实参列表)
- 嵌套调用:在一个函数的函数体中,可以调用另一函数,称为嵌套调用
- 递归调用:函数直接或间接调用自身
2、例子
①x的n次方
#include<iostream>
using namespace std;
int DoublePower (int x,int n);
int main()
{
int x,n,result;
cout<<"please enter two numbers,the front one is x,the next one is n"<<enl;
cin>>x>>n;
result=DoublePower (x,n);
cout<<"the result is"<<result<<endl;
return 0;
}
int DoublePower (int x,int n)
{
int m=1,i=0;
do{
m=m*x;
i++;
}while(i<=n);
return m;
}
②八位二进制化为十进制
#include<iostream>
#include<cmath>
using namespace std;
int conversion(int a, int b, int c, int d, int e, int f, int g, int h);
int main()
{
int a, b, c, d, e, f, g, h, DecimalNum;
cout << "please enter an 8-bit binary number one by one" << endl;
cin >> a >> b >> c >> d >> e >> f >> g >> h;
DecimalNum = conversion(a, b, c, d, e, f, g, h);
cout << "the result is:" << DecimalNum;
return 0;
}
int conversion(int a, int b, int c, int d, int e, int f, int g, int h)
{
int DecimalNum;
int A =pow(2, 7);
int B =pow(2, 6);
int C =pow(2, 5);
int D =pow(2, 4);
int E =pow(2, 3);
int F =pow(2, 2);
int G =pow(2, 1);
int H =pow(2, 0);
return DecimalNum = a * A + b * B + c * C + d * D + e * E + f * F + g * G + h * H;
}
输入八位二进制转化为十进制 老师的方法
#include <iostream>
using namespace std;
double power (double x, int n);//函数声明
int main()
{
int value = 0;
cout << "Enter an 8 bit binary number:";
for (int i = 7; i >= 0; i--) //题目限制了八位二进制数 所以已知循环次数适合用for循环 这个i顺便还可以记录是二进制的哪一位
{
char ch;
cin >> ch;
if (ch == '1')
{
value += static_cast<int>(power(2, i));
//因为power函数算出来的是double类型,还需要强制类型转换
}
}
cout << "Decimal value is " << value << endl;
return 0;
}
//power函数专门用来计算每一位的n次方
double power (double x, int n)
{
double val = 1.0; //变量一定不要忘了给它初始化鸭~
while (n--)
{
val *= x;
}
return val;
}
③求π的值
π的计算公式如下:
π=16arctan(1/5)-4arctan(1/239)
其中arctan用如下形式的级数计算:
arctanx=x-x3/3+x5/5-x7/7+……
直到级数某项绝对值不大于10-15为止;π和x均为double型
下边做错了 (泣)
还找不到错在哪儿 难受
#include<iostream>
using namespace std;
double ArcTan(double n);
double power(int i, int c);
int main()
{
double a = 1 / 5.0;
double b = 1 / 239.0;
double pi;
cout <<"test"<< endl;
pi = 16 * ArcTan(a) - 4 * ArcTan(b);
cout << "π=" << pi << endl;
return 0;
}
double ArcTan(double c)
{
int i = 0;
double A = 0;
do
{
i = 2 * i + 1;
A = A + (power(i,-1)*power(i, c)) / i;
} while ((power(i, c)) / i <= 10e-15);
return A;
}
double power(int i, int c) //计算c的i次方
{
double m = 1;
int j;
for (j = 0; j <= i; j++)
{
m = m * c;
}
return m;
}
计算π 老师的方法
#include <iostream>
using namespace std;
double arctan(double x)
{
double sqr = x * x; //wow~
double e = x;
double r = 0;
int i = 1;
while (e / i > 1e-15)
{
double f = e / i;
//用f表示单独的一项 f负责确认数值
r = (i % 4 == 1) ? r + f : r - f;
//用余数来判断符号 i%4负责确认符号
e = e * sqr;
//利用两项之间的次数差为2 直接用sqr来表示这个次数差 不用i
//这个要放在double f = e / i;的后边 不然第一项就没法表示
i += 2;
}
return r;
}
int main()
{
double a = 16.0 * arctan(1 / 5.0);
double b = 4.0 * arctan(1 / 239.0);
cout << "PI = " << a - b << endl;
return 0;
}
④找回文数
寻找并输出11~999之间的数m,它满足m、m2和m3均为回文数
回文:各位数字左右对称的整数例如:11满足上述条件 112=121,113=1331
分析:
10取余的方法,从最低位开始,依次取出该数的各位数字。按反序重新构成新的数,比较与原数是否相等,若相等,则原数为回文。
#include<iostream>
using namespace std;
int judge(unsigned n);
int main()
{
unsigned a;
for (a=1; a<= 999; a++)
{
unsigned b = a * a;
unsigned c = b * a;
if (judge(a) == 1 && judge(b) == 1 & judge(c) == 1)
{
cout << a << " a^2= " << b << " a^3= " << c << endl;
}
}
cout << "That's all the palindrome number as request between 0 and 999" << endl;
return 0;
}
int judge(unsigned n)
{
int r; //用r来判断是否为回文 r=1 是 r=0 否
unsigned i = n;
unsigned m = 0;
while (i > 0)
{
m = m * 10 + i % 10;
i /= 10;
}
if(m==n)
return r = 1;
else
return r = 0;
}
三、函数的参数传递
1、函数参数的存储
在函数被调用时才分配形参的存储单元。
2、实参相关要求
实参可以是常量、变量或表达式。
实参类型必须与形参相符。
3、传递方向
值传递是传递参数值,即单向传递。
引用传递可以实现双向传递
常引用作参数可以保障实参数据的安全
4、引用传递
1、引用(&)是标识符的别名
例如:
int i, j;
int &ri=i;//建立一个int型的引用ri,并将其初始化为变量i的一个别名
j = 10;
ri = j;//相当于 i = j;
2、声明一个引用时,必须同时对它进行初始化,使它指向一个已存在的对象。
3、一旦一个引用被初始化后,就不能改为指向其它对象。
4、引用可以作为形参
void swap(int &a, int &b) {...}
第二节 内联函数
1、声明时使用关键字inline。
2、编译时在调用处用函数体进行替换,节省了参数传递、控制转移等开销。
3、注意:
内联函数体内不能有循环语句和switch语句。
内联函数的声明必须出现在内联函数第一次被调用之前。
对内联函数不能进行异常接口声明。
4、举例
#include <iostream>
using namespace std;
const double PI = 3.14159265358979;
inline double calArea(double radius)
{
return PI * radius * radius;
}
int main()
{
double r = 3.0;
double area = calArea(r);
cout << area << endl;
return 0;
}
第三节 带默认参数值的函数
1、概念
函数在声明时可以预先给出默认的形参值,调用时如给出实参,则采用实参值,否则采用预先给出的默认参数值。
举例:
int add(int x = 5,int y = 6)
{
return x + y;
}
int main()
{
add(10,20);//10+20
add(10); //10+6
add(); //5+6
}
2、默认参数值的说明次序
有默认参数的形参必须在形参列表的最后,也就是说默认参数值的右面不能有无默认值的参数。因为调用时实参与形参的结合是从左向右的顺序。
例:
int add(int x, int y = 5, int z = 6);//正确
int add(int x = 1, int y = 5, int z);//错误
int add(int x = 1, int y, int z = 6);//错误
3、默认参数值与函数的调用位置
如果一个函数有原型声明,且原型声明在定义之前,则默认参数值必须在函数原型声明中给出;而如果只有函数的定义,或函数定义在前,则默认参数值需在函数定义中给出。
int add(int x = 5,int y = 6);
//原型声明在前
int main()
{
add();
}
int add(int x,int y)
{
//此处不能再指定默认值
return x + y;
}
int add(int x = 5,int y = 6)
{
//只有定义,没有原型声明
return x + y;
}
int main()
{
add();
}
第四节 函数重载
1、概念
C++允许功能相近的函数在相同的作用域内以相同函数名声明,从而形成重载。方便使用,便于记忆。
举例:
int add(int x, int y);
float add(float x, float y);
//形参类型不同
int add(int x, int y);
int add(int x, int y, int z);
//形参个数不同
2、注意
(1)重载函数的形参必须不同:个数不同或类型不同
- 形参不同或者是返回值不同都不算数
(2)编译程序将根据实参和形参的类型及个数的最佳匹配来选择调用哪一个函数
(3)不要将不同功能的函数声明为重载函数,以免出现调用结果的误解、混淆。这样不好:
int add(int x, int y)
{
return x + y;
}
//这两个只是长得差不多 但是功能差太多 一个是+一个是-
float add(float x,float y)
{
return x - y;
}
3、举例
#include <iostream>
using namespace std;
int sumOfSquare(int a, int b)
{
return a * a + b * b;
}
double sumOfSquare(double a, double b)
{
return a * a + b * b;
}
int main()
{
int m, n;
cout << "Enter two integer: ";
cin >> m >> n;
cout << "Their sum of square: " << sumOfSquare(m, n) << endl;
double x, y;
cout << "Enter two real number: ";
cin >> x >> y;
cout << "Their sum of square: " << sumOfSquare(x, y) << endl;
return 0;
}