第七章——函数 第一节——函数定义和返回值

第七章——函数 第一节——函数定义和返回值

亓翎_Re-Tikara Lv5

一、函数定义:你的专属工具说明书

函数定义就像写一份工具说明书。比如你发明了一个“自动榨果汁机”(函数),说明书需要写清楚:

  • 功能:能榨什么水果(参数类型,比如苹果、橙子)
  • 步骤:怎么操作(函数体里的代码)
  • 结果:最后产出什么(返回值类型,比如果汁)

代码例子

1
2
3
4
5
// 函数定义:榨汁机说明书
int juice_maker(int apples, int oranges) { // 苹果和橙子的数量是参数
int total = apples * 10 + oranges * 15; // 榨汁过程(函数体)
return total; // 返回值:果汁毫升数
}

类比:就像你告诉朋友:“用2个苹果+3个橙子榨汁,能得到210+315=65ml果汁”,这个公式就是你的“函数”。


一般格式

1
2
3
4
5
6
函数类型 函数名(形参类型说明表)
// 函数名必须合法,既不可以使用系统关键字
{
说明部分
语句部分
}

有参函数(现代写法)

1
2
3
4
5
6
7
8
int max(int a, int b)
// 两个形参必须分开指明类型,int max(int a, b)是错误的
{
int z;
z=a>b?a:b;

return z;
}

无参函数

写法一

1
2
3
4
void print_menu()
{
printf("1. 菜单\n");
}

写法二

1
2
3
4
void print_menu(void)
{
printf("1. 菜单\n");
}

空函数

1
2
3
4
5
6
7
void nothing()
{
// 是空的哦~什么也不用写
// 如果确定是个空函数的话
// 虽然加上也不会报错
// 但是加了是一个多余的写法,亓翎不推荐
}

古早的传统写法

1
2
3
4
5
6
函数类型 函数名(形参表)
形参类型说明
{
说明部分
语句部分
}

示例-有参函数

1
2
3
4
5
6
7
int max(a , b)
int a, int b;
{
int z;
z=a>b?a:b;
return z;
}

二、返回值:任务完成后的“结果反馈”

返回值就像快递员送完包裹后给你的签收单。比如:

  • 有返回值:快递员说“已送达,签收了!”(比如返回果汁毫升数)
  • 无返回值(void):快递员放下包裹就走,不说话(比如一个打印菜单的函数)

返回语句形式

1
2
3
4
return(表达式);
return 表达式;
return;
// 这三种写法全是对的,但是我个人喜欢第二种

代码例子

1
2
3
4
5
6
7
// 有返回值函数:计算两个数的最大值
int max(int a, int b) {
if (a > b)
return a; // 如果a大,返回a
else
return b; // 否则返回b
}

类比:相当于老师批改考试,最后给你打分(返回值)告诉你考得怎么样。


功能

  功能:使程序控制从被调用函数返回到调用函数中,同时把返值带给调用函数。


函数返回值类型

  定义在函数开头的函数类型,一般有如下几种:

  • int:返回整数(比如计算结果)
  • void:无返回值(比如打印菜单)
  • char:返回字符(比如输入的字母)
  • double:返回小数(比如计算结果)

几点说明

  • 函数中可有多个return语句
  • 若无return语句,遇}时,自动返回调用函数
  • 若函数类型与return语句中表达式值的类型不一致,按前者为准,自动转换——函数调用转换
  • 要注意void型函数

关于在void型函数中使用return

  在C语言中,void 类型的函数可以使用 return 语句,但有一些注意事项和潜在问题需要了解。

1. void 函数中的 return 是合法的

  void 类型的函数表示该函数不返回任何值。在这种情况下,return 可以用于提前终止函数的执行,而不需要返回值。例如:

1
2
3
4
5
6
7
8
9
10
void print_message(int flag)
{
if (flag == 0) {
return;
// 直接结束函数,后面的输出也不会输出哦
// 无论是几层嵌套的,都会直接截断,后面的直接不执行
// 呀注意它和break不一样的
}
printf("Flag is not zero.\n");
}

  在这个例子中,如果 flag 的值为 0,函数会在 return 处直接退出,不会执行后续的代码。


2. return 后不能跟随表达式

  在 void 函数中,return 语句后面不能跟随任何表达式或值,否则会导致编译错误。例如:

1
2
3
4
void example_function(void)
{
return 42; // 错误!void 函数不能返回值
}

  上述代码会导致编译器报错,因为 void 类型的函数不允许返回任何值。


3. 潜在问题

  虽然在 void 函数中使用 return 是合法的,但在某些情况下可能会引发问题或误解:

a. 过度使用 return 导致代码难以维护

  如果在一个函数中频繁使用 return,可能会使代码逻辑变得复杂且难以阅读。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
void complex_function(int value)
{
if (value < 0) {
return;
}
if (value == 0) {
return;
}
if (value > 100) {
return;
}
printf("Value is valid: %d\n", value);
}

  这种写法虽然功能上没有问题,但由于存在多个 return 语句,可能会使代码逻辑变得分散,难以追踪程序的执行路径。

b. 遗漏必要的清理操作

  如果函数中有资源分配(如动态内存分配、文件打开等),过早使用 return 可能会导致资源泄漏。例如:

1
2
3
4
5
6
7
8
9
void resource_leak_example(void)
{
FILE *file = fopen("example.txt", "r");
if (file == NULL) {
return; // 直接返回,未关闭文件
}
// 正常处理文件
fclose(file);
}

  在这个例子中,如果 fopen 返回 NULL,函数会直接通过 return 退出,导致文件指针未被正确关闭,从而可能引发资源泄漏。


三、常见误区:没有return会怎样?

  特别提醒:如果函数没有return语句,遇到}时会自动返回,但返回值不确定。这就像:

做实验没写结论,老师直接合上实验本——结果可能被误判为0分,也可能随机给个值(取决于编译器)。

错误示范

1
2
3
4
int add(int a, int b) {
int result = a + b; // 计算结果存在变量里
// 没有return语句!
}

  这会导致调用者拿到一个“未知的结果”,就像你问AI问题,它突然说:“嗯……忘了告诉你答案”。


四、类型不匹配怎么办?系统自动“翻译”

如果函数声明返回整数(int),但实际返回小数(比如return 3.14;),系统会自动转换成整数(3)。就像:

  • 用美元付款,但找零给的是人民币——系统帮你“汇率转换”,但可能损失精度。

五、为什么函数定义和返回值重要?

函数定义和返回值对应的知识点是编程的“骨架”:

  1. 模块化思维:把复杂问题拆成小工具(函数),比如把做蛋糕拆成“打蛋器”、“烤箱”等函数
  2. 数据流动:参数是输入,返回值是输出,构成完整的“数据生产线”
  3. 调试基础:理解返回值机制才能排查“为什么函数没返回预期结果”的问题

现实案例:某银行系统有个利息计算器函数,因忘记写return,导致所有储户利息显示为0,引发客诉——这就是函数定义和返回值知识点踩坑的典型反例。


总结:函数就像“魔法盒子”

  • 定义函数:写说明书(参数+过程+结果)
  • 返回值:给使用者一个明确的反馈
  • 注意事项:别让盒子空手回来,类型要匹配,否则系统会“好心帮倒忙”

  掌握函数定义和返回值,就像学会搭积木的第一块基石,后面才能堆出更复杂的程序高楼!


考点总结

C语言函数定义的一般形式

1
2
3
4
5
存储类型说明符 函数返回值类型 函数名(类型名 形参1,类型名 形参2,类型名 形参n)
{
说明部分
执行部分
}

存储类型说明符

  在C语言中,存储类型说明符(Storage Class Specifier)用于定义变量或函数的存储方式、作用域(scope)和生命周期(lifetime)。当提到“说明该函数是内部函数还是外部函数”时,主要涉及两个关键字:staticextern


1. 内部函数(Internal Function)

  • 使用 static 关键字修饰的函数被称为内部函数
  • 内部函数的作用域被限制在定义它的源文件中,其他文件无法访问该函数。
  • 这种方式可以避免函数名冲突,尤其是在大型项目中。
示例:
1
2
3
4
5
6
7
8
// 文件1: file1.c
static void internal_function(void) {
printf("This is an internal function.\n");
}

void call_internal_function(void) {
internal_function(); // 可以调用,因为它们在同一个文件中
}
1
2
3
4
5
6
7
// 文件2: file2.c
extern void call_internal_function(void); // 声明外部函数

void try_to_call_internal_function(void) {
// internal_function(); // 错误!无法访问 file1.c 中的内部函数
call_internal_function(); // 正确!可以通过暴露的接口调用
}

在这个例子中:

  • internal_function 是一个内部函数,只能在 file1.c 中使用。
  • 其他文件(如 file2.c)无法直接调用 internal_function

2. 外部函数(External Function)

  • 默认情况下,函数是外部函数,即可以在其他文件中通过 extern 关键字引用。
  • 外部函数的作用域跨越多个源文件,允许不同文件之间的函数调用。
示例:
1
2
3
4
// 文件1: file1.c
void external_function(void) {
printf("This is an external function.\n");
}
1
2
3
4
5
6
// 文件2: file2.c
extern void external_function(void); // 声明外部函数

void call_external_function(void) {
external_function(); // 正确!可以调用 file1.c 中的外部函数
}

在这个例子中:

  • external_function 是一个外部函数,默认情况下可以在其他文件中通过 extern 引用并调用。

3. 总结对比

特性 内部函数 (static) 外部函数 (默认或 extern)
作用域 仅限于定义它的源文件 跨越多个源文件
声明方式 使用 static 关键字修饰 不需要额外修饰(默认为外部函数)
用途 避免函数名冲突,封装实现细节 在多个文件之间共享函数功能
是否需要 extern 不需要 在其他文件中需要 extern 声明

4. 实际应用建议

  • 如果某个函数只在当前源文件中使用,建议将其声明为 static,以减少全局命名空间污染,提高代码的可维护性。
  • 如果某个函数需要在多个文件中共享,则不需要使用 static,而是通过头文件(.h 文件)声明并导出该函数。

其余几点说明

  • 函数返回值的类型是用来说明该函数返回值的类型,如果没有返回值,则其类型说明符应该为void。
  • 函数名和形式参数都是由用户命名的标识符。在同一程序中,函数名必须唯一,形参名只要在同一函数中唯一即可,可以与其它函数中的变量重名。
  • 若省略了函数返回值的类型默认为int型。
  • 形参可以省略,称为无参函数。在调用时不用参数。
  • 函数体中,除形参外,用到的其它变量必须在说明部分进行定义,且可以和其它函数中的变量重名。

函数的返回值

return 语句一般形式

1
2
3
4
5

return(表达式);
return 表达式;
return;

  • return语句中表达式的值就是所求的函数值,且其类型必须与函数首部所说明的类型一致,若类型不一致,则由系统自动转换为函数值的类型。
  • 在程序执行到return语句时,流程就返回到调用该函数处,并带回函数值。在同一个函数体内,可以在多处return语句。
  • return语句也可以不含表达式。此时,它只是使流程返回到调用函数,并没有确定的函数值。
  • 函数体内也可以没有reture语句,程序就一直执行到函数末尾,然后返回到调用函数,此时也没有确定的函数值带回。
  • 标题: 第七章——函数 第一节——函数定义和返回值
  • 作者: 亓翎_Re-Tikara
  • 创建于 : 2026-02-07 02:21:28
  • 更新于 : 2026-02-10 02:48:46
  • 链接: https://re-tikara.fun/Blog/posts/4049614e/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。