函数的基本概念
什么是函数?
函数是 C 程序的基本模块,用于完成特定的任务。就像一台机器,接收输入(参数),经过处理,产生输出(返回值)。
函数的四个分类
类型 1:无参数 无返回值
定义格式
void func(void)
调用方式
func();
示例:打印问候语、清屏等
类型 2:有参数 无返回值
定义格式
void func(int x)
调用方式
func(5);
示例:打印 n 次星号、设置参数等
类型 3:无参数 有返回值
定义格式
int func(void)
调用方式
int x = func();
示例:获取用户输入、生成随机数等
类型 4:有参数 有返回值
定义格式
int func(int x, int y)
调用方式
int z = func(3, 4);
示例:数学计算、数据转换等
函数的一般形式
返回值类型 函数名(参数列表)
{
// 函数体(声明 + 语句)
return 表达式; // 如果返回值类型不是 void
}
注意:谭浩强《C 程序设计》第 7 章强调,函数是 C 程序的基本单位,一个 C 程序由一个或多个函数组成,必须有且仅有一个 main 函数。
类型 1:无参数 无返回值
函数定义格式
void printHello(void)
{
printf("Hello, World!\n");
}
调用方式
int main()
{
printHello(); // 直接调用,不使用返回值
return 0;
}
执行流程
1
程序执行到
printHello() 调用语句↓
2
程序跳转到
printHello 函数定义处↓
3
执行函数体内的
printf 语句↓
4
函数执行完毕,返回到调用点继续执行
互动演示
🖥️ 运行效果演示
> 等待执行...
完整示例代码
/* 无参数无返回值函数示例 */
#include <stdio.h>
void printMenu(void)
{
printf("======== 菜单 ========\n");
printf("1. 开始游戏\n");
printf("2. 加载存档\n");
printf("3. 退出\n");
printf("======================\n");
}
int main()
{
printMenu(); // 调用函数
return 0;
}
关键点:这种函数不接收外部数据,也不返回结果,通常用于执行固定的操作,如打印菜单、清屏、初始化等。
类型 2:有参数 无返回值
函数定义格式
void printStars(int n)
{
for (int i = 0; i < n; i++)
{
printf("★");
}
printf("\n");
}
调用方式
printStars(5); // 输出:★★★★★
printStars(10); // 输出:★★★★★★★★★★
参数传递过程
调用时的内存状态
main 函数
int num = 5;
↓ 传递值
printStars 函数
n = 5 (副本)
互动演示
⭐ 打印星号演示
> 等待执行...
📊 多个参数示例
> 等待执行...
完整示例代码
/* 有参数无返回值函数示例 */
#include <stdio.h>
/* 打印 n 个星号 */
void printStars(int n)
{
for (int i = 0; i < n; i++)
{
printf("★");
}
printf("\n");
}
/* 打印两个数的和 */
void printSum(int a, int b)
{
int sum = a + b;
printf("%d + %d = %d\n", a, b, sum);
}
/* 打印 n×m 的矩形 */
void printRectangle(int n, int m)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
printf("■ ");
}
printf("\n");
}
}
int main()
{
printf("1. 打印星号:");
printStars(5);
printf("2. 打印加法结果:");
printSum(10, 20);
printf("3. 打印矩形:\n");
printRectangle(3, 5);
return 0;
}
关键点:参数是"值传递",函数内修改参数不会影响原变量。适合执行需要外部输入但不需返回结果的操作。
类型 3:无参数 有返回值
函数定义格式
int getRandomNumber(void)
{
return rand() % 100 + 1; // 返回 1-100 的随机数
}
调用方式
int num = getRandomNumber();
printf("随机数:%d\n", num);
// 或者直接在表达式中使用
if (getRandomNumber() > 50)
{
printf("大于 50!\n");
}
返回值传递过程
返回值的传递
函数执行
return 42;
↓ 返回值
调用点接收
int x = 42;
互动演示
🎲 生成随机数演示
> 等待执行...
📝 获取用户输入示例
> 等待执行...
完整示例代码
/* 无参数有返回值函数示例 */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/* 生成 1-100 的随机数 */
int getRandomNumber(void)
{
return rand() % 100 + 1;
}
/* 模拟获取用户输入 */
int getUserInput(void)
{
int value;
printf("请输入一个整数:");
scanf("%d", &value);
return value;
}
/* 获取当前年份 */
int getCurrentYear(void)
{
return 2024; // 简化示例
}
int main()
{
srand(time(0)); // 初始化随机种子
printf("1. 随机数:%d\n", getRandomNumber());
printf("2. 随机数:%d\n", getRandomNumber());
printf("3. 当前年份:%d\n", getCurrentYear());
int num = getUserInput();
printf("你输入的是:%d\n", num);
return 0;
}
关键点:这种函数从内部或外部获取数据(如用户输入、传感器读数、随机数生成),然后返回给调用者使用。
类型 4:有参数 有返回值
函数定义格式
int add(int a, int b)
{
int result = a + b;
return result; // 或直接 return a + b;
}
调用方式
int sum = add(3, 4); // sum = 7
int product = multiply(5, 6); // product = 30
// 可以嵌套调用
int result = add(multiply(2, 3), 4); // result = 10
数据流向图
完整的数据流
调用点
add(5, 3)
↓ 传入参数
函数接收
a=5, b=3
函数处理
result = 8
↑ 返回结果
调用点接收
sum = 8
互动演示
➕ 加法计算器
> 等待执行...
🧮 多功能计算器
> 等待执行...
完整示例代码
/* 有参数有返回值函数示例 */
#include <stdio.h>
/* 计算两数之和 */
int add(int a, int b)
{
return a + b;
}
/* 计算两数之差 */
int subtract(int a, int b)
{
return a - b;
}
/* 计算两数之积 */
int multiply(int a, int b)
{
return a * b;
}
/* 计算两数之商 */
float divide(float a, float b)
{
if (b == 0)
{
printf("错误:除数不能为 0!\n");
return 0;
}
return a / b;
}
/* 判断是否为素数 */
int isPrime(int n)
{
if (n < 2) return 0;
for (int i = 2; i * i <= n; i++)
{
if (n % i == 0)
return 0;
}
return 1;
}
int main()
{
int a = 10, b = 5;
printf("%d + %d = %d\n", a, b, add(a, b));
printf("%d - %d = %d\n", a, b, subtract(a, b));
printf("%d × %d = %d\n", a, b, multiply(a, b));
printf("%d ÷ %d = %.2f\n", a, b, divide(a, b));
int num = 17;
if (isPrime(num))
printf("%d 是素数\n", num);
else
printf("%d 不是素数\n", num);
return 0;
}
关键点:这是最常用的函数类型,实现完整的"输入→处理→输出"流程。适合各种计算、转换、判断等操作。
四种函数类型对比总结
| 函数类型 | 定义格式 | 调用方式 | 应用场景 | 示例 |
|---|---|---|---|---|
| 无参无返回值 | void func(void) |
func(); |
固定操作 打印菜单 初始化 |
printMenu()clearScreen() |
| 有参无返回值 | void func(int n) |
func(5); |
需要输入 不需返回 副作用操作 |
printStars(10)setSize(w, h) |
| 无参有返回值 | int func(void) |
int x = func(); |
获取数据 生成值 查询状态 |
getRandom()getUserInput() |
| 有参有返回值 | int func(int a, int b) |
int z = func(3, 4); |
计算转换 数据处理 判断逻辑 |
add(x, y)isPrime(n) |
选择指南
?
问 1:函数需要外部输入数据吗?
- 是 → 需要参数
- 否 → 不需要参数
↓
?
问 2:函数需要返回结果给调用者吗?
- 是 → 需要有返回值
- 否 → 不需要返回值 (void)
↓
✓
根据两个问题的答案确定函数类型
- 无参数 + 无返回值 → 类型 1
- 有参数 + 无返回值 → 类型 2
- 无参数 + 有返回值 → 类型 3
- 有参数 + 有返回值 → 类型 4
关键概念回顾
形式参数 vs 实际参数
形参
定义时的参数
实参
调用时传入的值
实参的值传递给形参(值传递)
return 语句
有返回值函数
必须 return
void 函数
可省略 return
return 结束函数并返回值
函数声明
// 函数原型声明
int add(int, int);
int main()
{
add(1, 2);
}
// 函数定义
int add(int a, int b)
{
return a + b;
}
互动测试
第 1 题:以下哪个函数定义是"有参数无返回值"的类型?
第 2 题:以下函数调用哪个是正确的?
第 3 题:关于参数传递,以下说法正确的是?
第 4 题:编写一个函数,判断一个数是否为偶数,应该使用哪种类型?
第 5 题:以下代码的输出是什么?
void modify(int x)
{
x = 100;
}
int main()
{
int num = 50;
modify(num);
printf("%d", num);
return 0;
}