*学习书籍为Essential C++*
如何编写函数
从起初的hello world开始,我们就一直在学习程序的编写和算法的实现,函数的编写自然少不了它的规范和要求,本文章以斐波那契数列为例探索如何编写函数以及编写函数时的注意事项
函数的组成
1.返回类型
返回值的类型就是函数的返回类型,如:return 4;返回值为int类型,那么函数类型为int;如果函数没有返回值,那么返回类型为void,如:在终端打印Fibonacci数列
2.函数名
函数名应该简短并且经可能准确的描述这个函数的作用,如:fibon_elem(),这样代码的可读性就增强了
3.参数列表
函数参数扮演(placeholder)的角色,用户在每次调用函数时.将要传入的值放在其中,以便函数使用,如果函数的目的是打印菜单或者显示文字,那么就不太需要参数
4.函数体
操作本身的工作逻辑的实现内容,用{}括起
函数必须先被声明,才能被调用.声明时编译器会检查函数的参数是否正确,声明的时候不需要提供函数体
//函数声明
int fibon_elem(int pos);
/*
Fibonacci的前两个数值为1
elem:持有返回的值
n_1,n_2:持有前两个元素的值
pos:数列中的元素位置(由用户指定)
*/
int elem = 1;
int n_1 = 1,n_2 = 1;
for(int ix = 3;ix<=pos;ix++)
{
elem = n_1 + n_2;
n_2 = n_1;n_1 = elem;
}
用户要求获取第一个和第二个元素是,for循环不会被执行,直接返回elem,若要求获取第三个及后面的元素,for循环执行,位于pos的元素的值会被elem持有
return elem;
如果用户输入了错误的位置信息,我们可以直接终止程序
if(pos<=0)
exit(-1);
exit(n)函数是由操作系统提供的,当n=0时:正常运行程序,退出程序;当n!=0时:非正常运行倒置退出程序
但是这种当时过于极端,因此,改便返回值,使其可以表示fibon_elem是否能计算出用户想要的值才是合理的修改方向
//重新修改函数
bool fibon_elem(int pos,int &elem);//bool,返回值为false/true
返回该元素的实际值,我们加入了第二个参数,这里不多做说明,在下一节会详细介绍pos和elem之间的区别(想提前了解的小伙伴可以去查找"引用")
如果用户要求计算5000位置上的元素,会发生什么呢
element 5000 is -1846256875
这是不正确的,因为每个值的类型只能表达其值域里的值,int是个有符号(signed)类型,显然运算已经超出了int的最大范围,我们将elem类型环卫unsigned int
element 5000 is 2448710421
因为Fibonacci数列是无终止的,所以我们需要为代码设置一个足够大的值(int能胜任),如1024
bool fibon_elem(int pos,int &elem)
{
//检查位置是否合理
if(pos<=0||pos>1024)
{
elem = 0;
return false;
}
int elem = 1;
int n_1 = 1,n_2 = 1;
for(int ix = 3;ix<=pos;ix++)
{
elem = n_1 + n_2;
n_2 = n_1;n_1 = elem;
}
return true;
}
下面来简单实现一下这个程序
#include<iostream>
using namespace std;
//Fibon函数的声明
bool fibon_elem(int ,int&);//函数名称只有在函数内使用参数是才是必要的
int main()
{
int pos;
cout << "Please inter a position:";
cin >> pos;
int elem = 0;
if (fibon_elem(pos, elem))
cout << "element " << pos
<< " is " << elem << endl;
else
cout << "Sorry .Could not calculate element " << pos << endl;
}
编译程序,结果如图
如果函数的返回值不为void,那么它必须在每个可能的退出点将值返回,函数中的每条return语句都被用来明确表示该处就是函数的退出点.如果最后一条语句不是return,那么最后一条语句之后便是该函数的隐式退出点
下面的函数错误,因为其隐式退出点没有返回任何数值
bool print_sequence(int pos)
{
if (pos <= 0 || pos > 1024)
{
cerr << "invailed position: " << pos
<< "cannot handle request!" << endl;
return false;
}
switch (pos)
{
default:
case 2:
cout << "1 ";
case 1:
cout << "1 ";
break;
}
int elem = 1;
int n_2 = 1, n_1 = 1;
for (int ix = 3; ix <= pos; ix++)
{
elem = n_1 + n_2;
n_2 = n_1; n_1 = elem;
cout << elem << (!(ix % 10) ? "\n" : " ");
}
cout << endl;
}
编译器(vs2019)会进行报错,print_sequence()函数不会产生结果上的错误,但是例如上面的fibon_elem会产生奇怪的错误,在编写程序时,要检查是否正确返回了数值(非void类型)
当返回值为void时,return不返回任何数值,只用于提前结束函数
void print_mag(ostream &os,const string &msg)
{
if(msg.empty())
//不打印任何值,结束函数
return;
...
//无需在加return语句,隐式退出点已经足够
}
作者仍在学习中,如有不足或错误,请大佬指正
让我们一起痛苦并快乐的学习吧!😇