2.1 函数的基本用法 | Basic Function Usage

发布于 2025-09-18  578 次阅读


函数的基本用法 | Basic Function Usage

一、回顾与引入

在前面的章节中,我们学习了许多编程的基本概念:

  • 变量:存储数据的"容器"
  • 循环:重复执行相同的操作
  • 条件语句:根据不同情况执行不同的代码
  • 数组:存储多个相同类型数据的集合

以上属于C语言的简单程序设计,足够实现最基础、最简单的功能。从这一章开始,我们将认识C语言的另一重要内容:函数。

事实上,函数的发明和使用,是使C语言在上世纪广泛兴起的重要推手。强大的函数、函数库(头文件)也是C语言的一大重要特征。

这一小节,我们将删繁就简,从最简单的例子中认识函数的第一个基础功能:在程序中需要重复完成相同的功能时,不需要重复地写一样的代码或代码块,也能轻松完成相同的任务。

我们来看这样一些例子:

例如,在一些程序里,在前后不同的功能之间,可能需要多次打印分割线来提示用户,也就是像下面这三行代码可能在整个源码文件中多次出现:

printf("===================\n");
printf("  这是一条分割线\n");
printf("===================\n");

或者在不同地方都需要计算圆的面积:

// 在程序的多个地方都可能需要这样的计算
float pi = 3.14159;
float radius1 = 5.0;
float area1 = pi * radius1 * radius1;

// 过了几十行代码后,又需要计算另一个圆的面积
float radius2 = 8.0;
float area2 = pi * radius2 * radius2;

这样写代码有什么问题?

  • 代码重复:相同的逻辑写了很多遍
  • 难以维护:如果要修改计算公式,需要在多个地方同时修改
  • 容易出错:复制粘贴时可能忘记修改某些部分
  • 代码冗长:程序变得很长,难以阅读

今天我们要学习函数,它就像是给代码片段起个名字,让我们能够轻松地"调用"它们,从而实现代码的模块化和复用。

二、什么是函数?

在之前的顺序结构里,我们的程序按照下面的方式执行:

语句1 → 语句2 → 语句3 → ...

而对于一些程序,可能有的语句会重复执行很多遍,例如:

   语句1 → 语句A → 语句B → 语句C →  
 → 语句2 → 语句A → 语句B → 语句C → 
 → 语句3 → 语句A → 语句B → 语句C →  
 → ...

这时,如果我们给这些相同的语句或代码块“起个名字”,在需要执行它们的时候,“喊”它们的名字即可,是不是简洁很多?

例如:

称:语句A → 语句B → 语句C 为 MyFunction

那么刚才的执行逻辑就可以变成:

语句1 → MyFunction → 语句2 → MyFunction → 语句3 → MyFunction → ...

事实上,函数(Function)的基本功能,就是一段被命名的代码块。上面例子里,“起名字”这个过程,就是声明函数的过程,这个名字就是函数名。我们可以通过函数名来"调用"函数,让这段代码“插入”到顺序结构中执行。

在编程中:

  • 函数有名字:比如printMenucalculateArea
  • 函数有具体代码:函数体内的语句
  • 重复调用:需要这个功能时就"调用"函数
  • 模块化:将程序分解成一个个小的功能模块

三、函数的基本语法

我们从最简单的void类函数开始学习。void类函数就是"只做事,不问不答"的函数

你可能会疑惑:什么“问”、什么“答”?函数不就是代码块的代称么?事实上,替代代码块是函数的最基本功能。这里的“问”,指的是函数的参数传递;“答”,指的是函数的返回与返回值。这些概念在本章都会讲到。

1. 函数的定义

对于最简单的void类函数,我们通过下面的方法来定义它:

void 函数名() {
    // 函数体:需要执行的代码
}

(PS:对于变量,我们常说声明变量,但这里为什么说定义函数而非声明函数?事实上,定义是一种常见的声明操作,因此定义函数就是在声明函数。这在后面也会讲到)

让我们用一个具体例子来理解:

#include <stdio.h>

// 定义一个打印菜单的函数
void printMenu() {
    printf("===================\n");
    printf("  欢迎使用计算器\n");
    printf("===================\n");
    printf("1. 加法计算\n");
    printf("2. 减法计算\n");
    printf("3. 退出程序\n");
    printf("===================\n");
}

int main() {
    // 主函数要顺序执行的功能
    // ...
    return 0;
}

语法说明:

  • void:最简单的函数类型,“只干事”。严谨地说,表示这个函数不返回任何值(这在后面会讲到)
  • printMenu:函数的名字,我们自己起的
  • ():英文括号。括号内是参数列表,现在为空(后面章节会学习)
  • {}:英文大括号。大括号内是函数体,包含具体要执行的代码

这里,你可能发现了定义函数与声明变量有一些显著不同:位置不同

非常重要的是,函数的定义应当放在主函数main()之外,这是因为:我们曾经提到主函数main()也是一种函数,我们新定义的函数和主函数main()的“地位”是相同的。属于程序的结构级别。

而变量的声明是通过语句来实现的,需要在主函数main()或其他我们定义的函数的英文大括号{}内。

2. 函数的调用

定义了函数之后,我们就可以在程序中"调用"它:

函数名();

比如:

printMenu();  // 调用printMenu函数

3. 完整的程序示例

// Functions_Basic.c
#include <stdio.h>

// 函数定义
void printMenu() {
    printf("===================\n");
    printf("  欢迎使用计算器\n");
    printf("===================\n");
    printf("1. 加法计算\n");
    printf("2. 减法计算\n");
    printf("3. 退出程序\n");
    printf("===================\n");
}

int main() {
    printf("程序启动!\n\n");

    // 第一次调用函数
    printMenu();

    printf("\n用户进行了一些操作...\n\n");

    // 第二次调用函数
    printMenu();

    printf("\n程序结束!\n");
    return 0;
}

在这个例子中,我们调用了函数printMenu。程序执行大致如下:

  1. 程序启动,进入main()函数
  2. 输出"程序启动!"
  3. 遇到printMenu(); → “跳转到”printMenu函数执行
  4. 执行printMenu函数内的7行printf语句
  5. printMenu函数执行完毕 → “返回到”main()函数
  6. 继续执行main()函数中的下一条语句...

运行结果:
最终的输出结果是:

程序启动!

===================
  欢迎使用计算器
===================
1. 加法计算
2. 减法计算
3. 退出程序
===================

用户进行了一些操作...

===================
  欢迎使用计算器
===================
1. 加法计算
2. 减法计算
3. 退出程序
===================

程序结束!

四、使用函数的优势

通过上面的例子,我们可以看到使用函数带来的好处:

1. 代码复用

  • 之前:每次需要打印菜单都要写7行代码
  • 现在:只需要写一次函数定义,之后用printMenu();就可以了

2. 易于维护

  • 之前:修改菜单内容需要在多个地方同时修改
  • 现在:只需要修改函数定义中的内容,所有调用的地方都会自动更新

3. 代码结构清晰

  • 主程序main()变得简洁,容易理解程序的整体流程
  • 每个函数负责一个特定的功能,职责明确

4. 减少错误

  • 避免了复制粘贴代码时可能产生的错误
  • 逻辑集中在一个地方,bug更容易发现和修复

五、更多函数示例

让我们再看几个实用的函数例子:

示例1:打印分割线

void printSeparator() {
    printf("----------------------------------------\n");
}

int main() {
    printf("第一部分内容\n");
    printSeparator();
    printf("第二部分内容\n");
    printSeparator();
    printf("第三部分内容\n");
    return 0;
}

示例2:显示程序信息

void showProgramInfo() {
    printf("程序名称:简单计算器\n");
    printf("版本:1.0\n");
    printf("作者:小明\n");
    printf("功能:进行基本数学运算\n");
}

int main() {
    showProgramInfo();
    // 其他程序逻辑...
    return 0;
}

六、函数定义的位置

在C语言中,函数的定义位置有一个重要规则:函数必须在使用之前定义,或者提前声明

方法1:在main函数之前定义

#include <stdio.h>

// 函数定义在main之前
void sayHello() {
    printf("Hello, World!\n");
}

int main() {
    sayHello();  // 可以正常调用
    return 0;
}

方法2:先声明,后定义

在前面我们提到 声明(Declaration)定义(Definition) 有什么区别。这里我们做出解释:

通俗地讲,声明操作(例如声明一个变量、声明一个函数),是告诉编译器,这样的变量或函数现在存在了。后续的语句中如果要使用这些变量或调用这些函数,用它们的变量名/函数名来使用/调用是可行合法的。

而对于函数,还有定义操作,是指给出一个函数的确切功能。例如我们此前定义void类型函数时,就明确指明了这样一个函数代表什么代码块。

  • 声明:告诉编译器有这样一个函数/变量,但函数的具体功能可能尚不清晰
  • 定义:告诉编译器有这样一个函数的同时,确定它的确切功能

因此,定义函数的同时,也就是在声明它。

我们回到函数定义的位置这个话题上来。和第一种方法不同的是,如果把某函数的定义放在main()函数后面,那么main()函数内部再调用该函数的时候,会认为这个函数“从没见过”,即没有声明。

因此,如果想把定义写在后面,我们也可以先"告诉"编译器函数的存在,再在后面具体定义:

#include <stdio.h>

// 函数声明(就像是"预告")
void sayHello();

int main() {
    sayHello();  // 可以正常调用
    return 0;
}

// 函数定义在main之后
void sayHello() {
    printf("Hello, World!\n");
}

对于初学者,推荐使用方法1,将函数定义放在main函数之前,这样比较直观易懂。

七、练习思考

  1. 模块化思维:想想在你日常生活中,有哪些重复性的工作可以"标准化"成类似函数的步骤?

  2. 代码设计:如果要设计一个学生成绩管理程序,你觉得可以设计哪些函数?(比如:显示学生信息、显示操作菜单等)

  3. 函数命名:给函数起一个好名字很重要。你觉得函数名应该遵循什么原则?

八、本章小结

在这一章中,我们学习了:

  • 函数的概念:被命名的代码块,可以重复调用
  • 函数的目的:实现代码模块化,提高复用性
  • void函数的语法void 函数名() { 函数体 }
  • 函数的调用函数名();
  • 使用函数的优势:代码复用、易于维护、结构清晰、减少错误

下一章预告:我们将学习函数的参数传递,让函数变得更加灵活和强大!


重要提醒:目前我们学习的是最基础的void函数,暂时不涉及:

  • 函数的返回值
  • 函数的参数传递
  • 函数的参数列表
    这些概念我们会在后续章节中逐步学习!

这里是 /* Huajidawang */ 的个人主页