☰
第 6 章 · 函数
2026/10/5 7:00:16 网站建设 项目流程

函数是编程里最重要的概念之一:把一段代码封装起来,起个名字,需要时调用。它让代码可复用、可读、好维护。本章讲如何定义函数、传参数、返回值。

6.1 为什么需要函数

假设要算很多次"两个数的平方和"a² + b²,每次都写:

intr1=3*3+4*4;intr2=5*5+6*6;intr3=7*7+8*8;

又啰嗦又容易错。用函数封装:

intsquareSum(inta,intb){// 定义函数returna*a+b*b;}intr1=squareSum(3,4);// 调用:返回 25intr2=squareSum(5,6);// 61

清爽多了。函数 = 一段有名字、可重复调用的代码。

6.2 定义函数

函数的完整结构:

返回类型 函数名(参数列表){// 函数体return返回值;}

逐部分解释:

  • 返回类型:函数算出来的结果是什么类型(int、double、void…)
  • 函数名:调用时用的名字
  • 参数列表:调用时传入的"输入"(可以有多个,用逗号分隔;也可以没有)
  • 函数体:{ }里要执行的代码
  • return:返回结果,并结束函数

举例:

// 无参数、无返回值的函数voidgreet(){std::cout<<"你好!"<<std::endl;}// 有参数、有返回值intadd(intx,inty){returnx+y;}// 有参数、无返回值voidprintTwice(intn){std::cout<<n<<" "<<n<<std::endl;}
  • void表示"没有返回值",这样的函数不需要写return(或写return;)。
  • 参数就是"输入",返回值就是"输出"。

6.3 调用函数

定义好函数后,用函数名(实际参数)调用:

#include<iostream>intadd(intx,inty){returnx+y;}intmain(){intresult=add(3,5);// 调用 add,3 和 5 是"实参"std::cout<<result<<std::endl;// 8return0;}

调用过程:

  1. 程序执行到add(3, 5)
  2. 跳进add函数,x=3、y=5
  3. 执行return x + y;,算出 8
  4. 带着 8 跳回调用处,result = 8

术语:定义时写的是形参(x、y),调用时传的是实参(3、5)。实参的值复制给形参。

6.4 参数的值传递

C++ 默认是值传递:调用函数时,把实参的值复制一份给形参。所以函数内修改形参,不影响外部的实参:

#include<iostream>voidchange(intx){x=100;// 改的是副本}intmain(){inta=5;change(a);std::cout<<a<<std::endl;// 还是 5,没被改}

想真正修改外部的变量,要用引用(第 8 章讲)。

6.5 函数声明与定义分离

C++ 要求"先声明、后使用"。如果函数定义在main之后,main里就调用不到。解决方法是先声明:

#include<iostream>intadd(intx,inty);// 函数声明(也叫原型):只写签名,不写函数体intmain(){std::cout<<add(3,5)<<std::endl;// 现在可以调用了return0;}intadd(intx,inty){// 函数定义:在下面补全函数体returnx+y;}

声明只告诉编译器"有这么个函数,长这样",定义才给出具体实现。真实项目里,声明通常放头文件(.h),定义放源文件(.cpp),后面会看到。

6.6 返回值 vs 打印:别搞混

新手常混淆"返回"和"打印":

intgetFive(){std::cout<<"5"<<std::endl;// 这是"打印",不是"返回"return5;// 这才是"返回"}
  • 打印(std::cout)是给人看的,结果显示在屏幕。
  • 返回(return)是把值交给调用者,用于后续计算。

很多函数既要返回也要打印,但要清楚两者是两回事。

6.7 递归:函数调用自己

函数可以调用自己,这叫递归。经典例子是阶乘n! = n × (n-1) × ... × 1:

intfactorial(intn){if(n<=1)return1;// 基准情况:递归的出口returnn*factorial(n-1);// 递归调用自己}// factorial(5) = 5 * factorial(4) = 5 * 4 * factorial(3) = ... = 120

递归必须有一个基准情况(停止条件),否则会无限调用导致崩溃。

递归虽然优雅,但初学不必强求。理解"函数能调用自己"即可。

6.8 完整示例

#include<iostream>// 判断一个数是否为质数boolisPrime(intn){if(n<2)returnfalse;// 小于 2 的不是质数for(inti=2;i*i<=n;i++){// 只需试除到 sqrt(n)if(n%i==0)returnfalse;// 能整除,不是质数}returntrue;}intmain(){std::cout<<"100 以内的质数:"<<std::endl;for(inti=1;i<=100;i++){if(isPrime(i)){std::cout<<i<<" ";}}std::cout<<std::endl;return0;}

这个例子把"判断质数"封装成isPrime函数,主函数里就能干净地复用。

实际输出:

100 以内的质数: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97

6.9 小结

  • 函数 = 有名字、可复用的代码块。
  • 定义:返回类型 函数名(参数) { 函数体 }。
  • return返回结果;void表示无返回值。
  • 默认值传递:函数内改参数不影响外部。
  • 先声明、后使用;声明和定义可以分离。
  • 递归是函数调用自己,必须有停止条件。

下一章,学习数组与字符串——存储一组数据和文字。


练习题

  1. 写函数max(a, b)返回两个数中较大的一个。
  2. 写函数isEven(n)判断偶数,返回 bool。
  3. 写函数计算1+2+...+n的和。
  4. 写递归函数求斐波那契数列第 n 项。
  5. 写函数abs(x)返回绝对值,比较值传递的效果。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询