【cpluscplus教程翻译】函数(Functions)

发布时间 2023-05-28 18:06:43作者: xiaoweing

使用函数,可以独立完成代码任务
在c++中,函数是指有名字的语句组,可以被程序的其他点调用
最常见的定义函数语法为(也可以使用lambda表达式和重载调用操作符)
type name ( parameter1, parameter2, ...) { statements }
type是返回值类型,name是函数名,parameter是参数,statements是函数体

// function example
#include <iostream>
using namespace std;

int addition (int a, int b)
{
  int r;
  r=a+b;
  return r;
}

int main ()
{
  int z;
  z = addition (5,3);
  cout << "The result is " << z;
}

这里定义了两个函数,无论定义的顺序如何,C++程序一定先调用main函数,事实上,main函数是唯一被自动调用的函数,其他函数当且仅当被main函数调用后才会执行
上面这个例子声明一个变量后,调用函数。
调用函数后会返回调用点(现场保护和参数入栈)

// function example
#include <iostream>
using namespace std;

int subtraction (int a, int b)
{
  int r;
  r=a-b;
  return r;
}

int main ()
{
  int x=5, y=3, z;
  z = subtraction (7,2);
  cout << "The first result is " << z << '\n';
  cout << "The second result is " << subtraction (7,2) << '\n';
  cout << "The third result is " << subtraction (x,y) << '\n';
  z= 4 + subtraction (x,y);
  cout << "The fourth result is " << z << '\n';
}

函数没有返回值

函数用void表示没有返回值

// void function example
#include <iostream>
using namespace std;

void printmessage ()
{
  cout << "I'm a function!";
}

int main ()
{
  printmessage ();
}

也可以用void表示没有参数

main函数返回值

main函数如果没有返回值,编译器会隐式返回0,其他函数不会这么做
返回0通常表示程序正常运行,注意被shell调用时是否会判断返回值

传值和传引用

函数传值会用实参赋值形参,注意类的构造函数调用
传引用会影响外部变量

// passing parameters by reference
#include <iostream>
using namespace std;

void duplicate (int& a, int& b, int& c)
{
  a*=2;
  b*=2;
  c*=2;
}

int main ()
{
  int x=1, y=3, z=7;
  duplicate (x, y, z);
  cout << "x=" << x << ", y=" << y << ", z=" << z;
  return 0;
}

函数效率及常引用

一般的原则:除了基础类型,其他类型的参数尽量传引用,可以提高程序效率

string concatenate (const string& a, const string& b)
{
  return a+b;
}

内联函数

调用函数通常会有开销,比如现场保护,跳转,因此对于非常短的函数,可能把对应的指令赋值过去性能更好
inline会提醒编译器是否内联,本质上是在编译的时候进行替换,不一定编译器会采纳这个建议

inline string concatenate (const string& a, const string& b)
{
  return a+b;
}

函数默认参数

C++支持函数有默认值,请注意参数匹配的顺序,默认参数和非默认参数不能顺序乱写

// default values in functions
#include <iostream>
using namespace std;

int divide (int a, int b=2)
{
  int r;
  r=a/b;
  return (r);
}

int main ()
{
  cout << divide (12) << '\n';
  cout << divide (20,4) << '\n';
  return 0;
}

声明函数

变量需要先声明再使用,函数也是如此。变量可以声明的时候初始话,函数也可以声明的时候提供函数体,只是声明的话,可以不用加变量名,只要变量类型即可

// declaring functions prototypes
#include <iostream>
using namespace std;

void odd (int x);
void even (int x);

int main()
{
  int i;
  do {
    cout << "Please, enter number (0 to exit): ";
    cin >> i;
    odd (i);
  } while (i!=0);
  return 0;
}

void odd (int x)
{
  if ((x%2)!=0) cout << "It is odd.\n";
  else even (x);
}

void even (int x)
{
  if ((x%2)==0) cout << "It is even.\n";
  else odd (x);
}

尤其是互相调用的话,这种前向声明就更加重要了

递归

函数可以自己调用自己,对于某些情况,这种实现非常有效,本质上递归可以看成dfs搜索或者最短路径

// factorial calculator
#include <iostream>
using namespace std;

long factorial (long a)
{
  if (a > 1)
   return (a * factorial (a-1));
  else
   return 1;
}

int main ()
{
  long number = 9;
  cout << number << "! = " << factorial (number);
  return 0;
}

总结

函数本质上也是封装和抽象的体现