C++大白话系列-入门基础篇-11-函数详解

函数详解:代码复用的艺术

从重复代码到优雅函数

什么是函数?

又要学数学了吗?

关系可大了!

编程中的函数数学中的函数

  • ✅ 名字一样
  • ❌ 实现不同
  • ❌ 用途不同

但核心思想类似: 输入 → 处理 → 输出


为什么需要函数?

问题:代码重复

场景: 计算某年某月某日是星期几

版本1.0: 计算一个日期

int year = 2025;
int month = 6;
int day = 3;

// 一堆计算代码(假设有10行)
int result = /* 复杂计算 */;

// result = 0 表明星期六
// result = 1 表明星期天
// result = 2-6 表明星期一到星期五

版本2.0: 计算两个日期

// 第一个日期
int year1 = 2025;
int month1 = 6;
int day1 = 3;
int result1 = /* 复杂计算 */; // 重复代码!

// 第二个日期
int year2 = 2024;
int month2 = 12;
int day2 = 25;
int result2 = /* 复杂计算 */; // 又重复了!

问题严重性

如果项目中有100个地方需要这个功能:

  • 写100遍一样代码?
  • 代码量暴增
  • 修改一处,要改100处
  • 容易出错

必须有更好的办法!


函数:代码复用的解决方案

✨ 优雅版本

定义函数:

int GetWeekDay(int year, int month, int day) {
 // 复杂计算逻辑
int result = /* 计算 */;
return result;
}

使用函数:

// 计算第一个日期
int result1 = GetWeekDay(2025, 6, 3);

// 计算第二个日期
int result2 = GetWeekDay(2024, 12, 25);

// 计算第三个、第四个...
int result3 = GetWeekDay(2023, 1, 1);

函数的好处

代码复用
 ↓
减少重复
 ↓
易于维护
 ↓
提高效率

函数的定义

四个部分

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

示例:

int Add(int a, int b) {
int sum = a + b;
return sum;
}

四部分详解

部分

说明

示例

返回类型

函数返回什么类型的值

int

函数名

给函数起的名字

Add

参数列表

函数需要什么输入

int a, int b

函数体

函数的具体实现

{ … }


类比:函数 = 机器

洗衣机的例子

洗衣机 = 函数

┌─────────────────────────┐
│ 洗衣机(函数) │
├─────────────────────────┤
│ │
│ 放入: │
│ ├─ 衣服(参数1) │
│ └─ 洗衣液(参数2) │
│ │
│ 内部处理: │
│ └─ 洗涤、漂洗、脱水 │
│ │
│ 取出: │
│ └─ 干净的衣服(返回值)│
│ │
└─────────────────────────┘

对应到代码

衣服类型 洗衣机(衣服类型 脏衣服, 清洁剂类型 洗衣液) {
 // 内部处理
 衣服类型 干净衣服 = 洗涤过程(脏衣服, 洗衣液);
return 干净衣服;
}

⚠️ 参数类型要匹配

错误示例:

// 洗衣机要求:衣服 + 洗衣液
洗衣机(室友, 点燃的鞭炮); // ❌ 类型不对!

正确示例:

洗衣机(脏衣服, 洗衣液); // ✅ 类型匹配

函数的完整示例

求星期几的函数

#include <stdio.h>

// 函数定义
int GetWeekDay(int year, int month, int day) {
 // 蔡勒公式(简化版)
int result;
if (month < 3) {
month += 12;
year -= 1;
 }
int c = year / 100;
int y = year % 100;
result = (c / 4 - 2 * c + y + y / 4 +
26 * (month + 1) / 10 + day - 1) % 7;
if (result < 0) {
result += 7;
 }
return result;
}

int main() {
int weekday;
 // 函数调用
weekday = GetWeekDay(2025, 6, 3);
printf("2025年6月3日是星期 %d
", weekday);
weekday = GetWeekDay(2024, 12, 25);
printf("2024年12月25日是星期 %d
", weekday);
return 0;
}

函数的调用

调用语法

返回值 = 函数名(参数1, 参数2, ...);

示例

// 定义函数
int Add(int a, int b) {
return a + b;
}

int main() {
int result;
 // 调用函数
result = Add(3, 5);
printf("结果:%d
", result); // 输出:8
return 0;
}

调用过程

1. 程序执行到 Add(3, 5)
 
2. 跳转到 Add 函数
 
3. a = 3, b = 5
 
4. 执行函数体
 
5. return 8
 
6. 回到调用处,result = 8

主函数 main

特殊的函数

int main() {
 // 程序从这里开始
return 0;
}

main 函数特点:

特点

说明

唯一性

每个程序有且只有一个

固定名称

必须叫 main

程序入口

程序从这里开始执行

操作系统调用

不是你调用,是系统调用

为什么叫 main?

main = 主要的、主函数
 ↓
程序的主入口
 ↓
就像房子的大门

参数详解

参数名可以不同

常见疑惑:

“调用时的变量名和参数名必须一样吗?”

答案: 不需要!

int Add(int a, int b) { // 参数名:a, b
return a + b;
}

int main() {
int x = 3;
int y = 5;
int result = Add(x, y); // 变量名:x, y
 // 参数名和变量名不同,没问题!
return 0;
}

参数名随意起

int Add(int num1, int num2) { // 叫 num1, num2
return num1 + num2;
}

int main() {
int apple = 3;
int banana = 5;
int result = Add(apple, banana); // 传水果名也行
return 0;
}

重点:类型匹配

只要类型对上就行:

int Add(int a, int b); // 期望两个 int

// ✅ 正确
Add(10, 20);
Add(x, y);
Add(apple, banana);

// ❌ 错误
Add(3.14, 2.5); // double 类型不匹配

返回值详解

return 关键字

作用:

  1. 结束函数执行
  2. 返回指定的值

单一返回

int GetMax(int a, int b) {
if (a > b) {
return a;
 } else {
return b;
 }
}

多个返回点

int CheckAge(int age) {
if (age < 0) {
return -1; // 错误码
 }
if (age < 18) {
return 0; // 未成年
 }
return 1; // 成年
}

⚠️ return 后的代码不执行

int Test() {
printf("执行这句
");
return 10;
printf("不会执行
"); // 永远不会执行
}

void 函数

不返回值的函数

语法:

void 函数名(参数列表) {
 // 函数体
}

示例

void PrintHello() {
printf("Hello World
");
 // 不需要 return
}

void PrintLine(int n) {
int i;
for (i = 0; i < n; i++) {
printf("-");
 }
printf("
");
}

int main() {
PrintHello(); // 输出:Hello World
PrintLine(10); // 输出:----------
return 0;
}

void 函数的 return

可以用 return 提前退出:

void CheckNumber(int n) {
if (n < 0) {
printf("错误:负数
");
return; // 提前退出
 }
printf("数字是:%d
", n);
}

值传递

重大致念

C语言中,参数传递是值传递(拷贝)

void ChangeValue(int x) {
x = 100; // 只改变副本
}

int main() {
int num = 10;
ChangeValue(num);
printf("%d
", num); // 输出:10(没变)
return 0;
}

传递过程

main中:
num = 10
  调用 ChangeValue(num)
 
函数中:
创建副本 x = 10
 
修改副本 x = 100
 
函数结束,副本销毁
 
main中:
num = 10(原件未变)

类比:银行复印件

你去银行办业务
 ↓
提交身份证复印件(副本)
 ↓
银行对复印件做标记
 ↓
你的原件身份证不受影响

函数内部对参数的修改,不影响原变量!


综合示例

矩形面积函数

#include <stdio.h>

// 计算矩形面积
double GetRectArea(double width, double height) {
double area = width * height;
return area;
}

// 打印矩形信息
void PrintRectInfo(double width, double height) {
double area = GetRectArea(width, height);
printf("宽:%.2lf
", width);
printf("高:%.2lf
", height);
printf("面积:%.2lf
", area);
}

int main() {
double w = 5.0;
double h = 3.0;
 // 方式1:获取面积
double area = GetRectArea(w, h);
printf("面积:%.2lf
", area);
printf("
");
 // 方式2:打印信息
PrintRectInfo(w, h);
return 0;
}

输出:

面积:15.00

宽:5.00
高:3.00
面积:15.00

判断质数函数

#include <stdio.h>

// 判断是否为质数
int IsPrime(int n) {
int i;
if (n < 2) {
return 0; // 不是质数
 }
for (i = 2; i * i <= n; i++) {
if (n % i == 0) {
return 0; // 不是质数
 }
 }
return 1; // 是质数
}

int main() {
int num;
printf("请输入一个数:
");
scanf("%d", &num);
if (IsPrime(num)) {
printf("%d 是质数
", num);
 } else {
printf("%d 不是质数
", num);
 }
return 0;
}

函数的优势

✨ 五大好处

  1. 代码复用
  • 写一次,用多次
  • 减少代码量
  1. 易于维护
  • 修改一处,全部生效
  • 降低出错概率
  1. 逻辑独立
  • 每个函数负责一件事
  • 代码更清晰
  1. 提高可读性
  • 函数名表达意图
  • 代码更易懂
  1. 便于测试
  • 单独测试每个函数
  • 更容易找bug

对比

没有函数:

// 1000行代码全在 main 里
int main() {
 // 计算1
 // 计算2
 // 计算3
 // ...
 // 乱成一团
}

有函数:

int Calculate1() { ... }
int Calculate2() { ... }
int Calculate3() { ... }

int main() {
int r1 = Calculate1();
int r2 = Calculate2();
int r3 = Calculate3();
 // 清晰明了
}

本文要点回顾

  • 函数作用:代码复用、逻辑独立
  • 函数定义:返回类型 + 函数名 + 参数 + 实现
  • 函数调用:函数名(参数)
  • main函数:程序入口,有且只有一个
  • 参数名:可以和调用时的变量名不同
  • return:返回值并结束函数
  • void函数:不返回值
  • 值传递:传递的是副本,不影响原变量

记忆口诀

函数封装一段码,复用方便又可靠。

返回类型名参数,花括号里写实现。

调用传参是副本,原件不变要记牢。


实战练习

练习1:求最大值

任务: 写一个函数,返回两个数中较大的

点击查看答案

cpp #include <stdio.h> int GetMax(int a, int b) { if (a > b) { return a; } else { return b; } } int main() { int x = 10; int y = 20; int max = GetMax(x, y); printf(“最大值:%d
“, max); return 0; }

练习2:求三个数的最大值

任务: 写一个函数,返回三个数中最大的

点击查看答案

cpp #include <stdio.h> int GetMax3(int a, int b, int c) { int max = a; if (b > max) { max = b; } if (c > max) { max = c; } return max; } int main() { int result = GetMax3(10, 25, 15); printf(“最大值:%d
“, result); return 0; }

练习3:打印分隔线

任务: 写一个void函数,打印n个’-‘

点击查看答案

cpp #include <stdio.h> void PrintLine(int n) { int i; for (i = 0; i < n; i++) { printf(“-“); } printf(”
“); } int main() { printf(“标题
“); PrintLine(20); printf(“内容
“); return 0; }

输出:
标题 ——————– 内容

练习4:阶乘函数

任务: 写一个函数计算n的阶乘

点击查看答案

cpp #include <stdio.h> long long Factorial(int n) { long long result = 1; int i; for (i = 1; i <= n; i++) { result *= i; } return result; } int main() { int n; printf(“请输入n:
“); scanf(“%d”, &n); long long result = Factorial(n); printf(“%d! = %lld
“, n, result); return 0; }

练习5:验证值传递

任务: 写一个函数,尝试修改参数,观察原变量是否改变

点击查看答案

cpp #include <stdio.h> void TryChange(int x) { printf(“函数内修改前:x = %d
“, x); x = 999; printf(“函数内修改后:x = %d
“, x); } int main() { int num = 10; printf(“调用前:num = %d
“, num); TryChange(num); printf(“调用后:num = %d
“, num); return 0; }

输出:
调用前:num = 10 函数内修改前:x = 10 函数内修改后:x = 999 调用后:num = 10

结论: 原变量未改变!


互动时间

思考题:

  1. 一个函数可以调用另一个函数吗?
  2. 函数可以调用自己吗?(提示:递归)
  3. 如果要在函数内修改原变量,该怎么办?(提示:指针)

如果本文对你有协助,欢迎:

  • 点赞支持
  • 关注不迷路
  • 评论区分享你的函数设计
  • ⭐ 收藏慢慢看

—-本文为”C++ 大白话”系列第 11 篇

© 版权声明

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
none
暂无评论...