当前位置: 首页 > news >正文

C 语言中的函数到底是什么?从“重复劳动”到“代码积木”的入门课

C 语言中的函数到底是什么?从“重复劳动”到“代码积木”的入门课

适合读者:已经学过变量、iffor、数组等基础内容,准备开始理解函数的 C 语言新手。
阅读目标:读完这篇文章,你应该能明白函数是什么,分清函数声明、函数定义、函数调用,理解参数、返回值、void和作用域的基本用法。

想象你每天都要做一杯奶茶。流程大概是:

烧水 -> 放茶包 -> 加牛奶 -> 加糖 -> 搅拌

你当然可以每天重新写一遍这些步骤。问题是,写多了人会烦,代码也会烦。更好的办法是:把这套流程整理好,起个名字叫makeMilkTea。以后想喝奶茶时,直接调用这个流程。

函数就是这么来的。

函数就是把一段可以重复使用的代码打包起来,起一个名字,需要时调用它。

目录

  • 一、为什么 C 语言需要函数
  • 二、函数到底是什么
  • 三、函数的基本结构
  • 四、声明、定义、调用分别是什么
  • 五、参数和返回值有什么用
  • 六、形参和实参:名字像亲戚,其实很好分
  • 七、void 是什么意思
  • 八、变量作用域和函数
  • 九、函数如何让代码更清晰、更容易复用
  • 十、完整示例:用函数计算两个数的最大值
  • 十一、初学者常见错误
  • 十二、总结与 5 个要点

一、为什么 C 语言需要函数

学函数之前,先看一个朴素的问题:重复代码。

假设你要输出接水步骤,两次都要写:

printf("打开水龙头\n");printf("接水\n");printf("关水龙头\n");printf("打开水龙头\n");printf("接水\n");printf("关水龙头\n");

这段代码能运行,但它有三个问题:

  1. 重复。同样三行写了两遍。
  2. 难改。如果要把“接水”改成“接一杯水”,每个地方都要改。
  3. 不清晰。代码一多,读者会被重复细节淹没。

如果用函数,可以这样写:

voidgetWater(void){printf("打开水龙头\n");printf("接水\n");printf("关水龙头\n");}

需要接水时调用它:

getWater();getWater();

这样代码就清爽很多。函数的作用不是让程序看起来高级,而是把重复劳动收纳起来。程序员喜欢偷懒,但这种偷懒叫“抽象”,听起来立刻正经了不少。

二、函数到底是什么

函数可以理解成一个“代码积木”。

你把一段代码打包成一个小模块,给它起名字。以后哪里需要,就把这块积木拿出来用。

函数通常解决三类问题:

问题函数怎么帮忙
重复代码太多把重复逻辑打包
程序太长不好读把大任务拆成小任务
同一功能多处使用写一次,多次调用

比如计算两个数的和:

intadd(inta,intb){returna+b;}

这个函数的意思是:给我两个整数,我返回它们的和。

像不像一个小工具?你把材料递进去,它把结果递回来。

三、函数的基本结构

一个函数通常长这样:

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

add来看:

intadd(inta,intb){returna+b;}

拆开解释:

部分示例含义
返回值类型int函数最后会返回一个整数
函数名add调用这个函数时使用的名字
参数列表int a, int b调用函数时需要提供两个整数
函数体{ ... }函数真正执行的代码
returnreturn a + b;把结果返回给调用者

也可以画成一个小盒子:

输入参数 a, b ↓ [ add 函数 ] ↓ 返回 a + b

函数像一个小加工厂:参数是原材料,函数体是加工流程,返回值是成品。

四、声明、定义、调用分别是什么

这三个词特别容易把新手绕晕。用“开店”来理解会轻松一点。

概念小白理解代码例子
函数声明先贴个招牌:我这里有这个函数int add(int a, int b);
函数定义真正把店开起来,写清楚怎么干活int add(int a, int b) { return a + b; }
函数调用顾客来点单,让函数执行add(3, 5);

1. 函数声明

intadd(inta,intb);

声明告诉编译器:后面会有一个叫add的函数,它接收两个int,返回一个int

2. 函数定义

intadd(inta,intb){returna+b;}

定义才是真正写函数内容的地方。

3. 函数调用

intresult=add(3,5);

调用就是让函数真正执行。这里add(3, 5)会得到结果8,再赋值给result

完整示例:

#include<stdio.h>intadd(inta,intb);// 函数声明intmain(void){intresult=add(3,5);// 函数调用printf("%d\n",result);return0;}intadd(inta,intb){// 函数定义returna+b;}

为什么要声明?因为 C 语言编译时通常从上往下看。main先用到了add,编译器需要提前知道:这个函数确实存在,而且应该怎么用。

五、参数和返回值有什么用

函数如果完全不接收数据,也不返回结果,就像一个只会喊口号的工具。能用,但用途有限。

参数和返回值让函数真正灵活起来。

1. 参数:把数据传进去

intadd(inta,intb){returna+b;}

这里的ab是参数。调用时可以传不同的值:

add(1,2);add(10,20);add(100,200);

同一个函数,因为参数不同,可以处理不同数据。

2. 返回值:把结果带回来

intsum=add(3,5);

add(3, 5)算出8,这个8就是返回值。调用者可以把它保存起来、打印出来,或者继续参与计算。

调用者给函数:3 和 5 函数内部计算:3 + 5 函数返回结果:8

做奶茶也是一样。参数可以是“甜度、杯数、是否加冰”,返回值就是做好的奶茶。只不过 C 语言不会真的给你递奶茶,最多给你一个结果。

六、形参和实参:名字像亲戚,其实很好分

形参和实参是函数里很常见的一对词。

名称出现位置含义
形参函数定义里占位用的变量
实参函数调用时真正传进去的值

看代码:

intadd(inta,intb){returna+b;}intresult=add(3,5);

这里:

  • ab是形参;
  • 35是实参。

你可以把形参理解成点单表上的空格,实参就是你真正填进去的内容。

形参:甜度、杯数 实参:七分糖、2 杯

函数被调用时,实参的值会传给形参。函数内部用形参做计算。

七、void 是什么意思

void在函数里常见,有两个主要意思。

1. 没有返回值

voidsayHello(void){printf("Hello!\n");}

函数名前面的void表示:这个函数不返回结果。它只是做一件事,比如输出一句话。

调用时这样写:

sayHello();

不能这样写:

intx=sayHello();// 错误:sayHello 没有返回值

2. 没有参数

voidsayHello(void)

括号里的void表示:这个函数不需要你传任何参数。

所以void sayHello(void)可以理解成:

不需要输入,也不返回结果,只负责打招呼。

如果函数既不需要输入,也不需要输出,void就会出现两次。看着有点重复,其实很诚实。

八、变量作用域和函数

函数会形成自己的小房间。你在函数里定义的变量,通常只能在这个函数里使用。

voidtest(void){intx=10;printf("%d\n",x);}intmain(void){printf("%d\n",x);// 错误:main 里看不到 test 里的 xreturn0;}

xtest函数里的局部变量。它住在test的房间里,main不能隔墙直接拿。

这叫作用域。先记住一句话:

变量在哪里定义,通常就只能在哪里附近使用。

函数之间如果要传数据,不能靠“偷看别人房间”,而要通过参数和返回值。

intsquare(intx){returnx*x;}

这里main可以把一个数传给squaresquare算完后通过return把结果带回来。这才是函数之间沟通的正规路线。

九、函数如何让代码更清晰、更容易复用

函数最大的价值,不只是“少写几行代码”。它还会让程序结构更清楚。

比如一个成绩程序可以拆成:

输入成绩 -> 计算平均分 -> 判断是否及格 -> 输出结果

写成函数后可以变成:

inputScores();average=calculateAverage();printResult(average);

这三行不一定能直接运行,因为它们只是示意:把不同任务拆成不同函数。哪怕你还不知道函数内部怎么写,也能大概看懂程序在做什么。

这就是函数的好处:

好处说明
减少重复同一段逻辑写一次,多次调用
结构清晰大任务拆成小任务
方便修改改函数内部,调用处不用全改
容易测试可以单独测试某个函数
更像人类思考每个函数负责一件事

好的函数不一定很长。很多时候,一个函数如果能清楚表达一件事,就已经很有价值。

十、完整示例:用函数计算两个数的最大值

下面写一个完整、可运行的小程序:输入两个整数,输出较大的那个。

#include<stdio.h>intgetMax(inta,intb);intmain(void){intx;inty;intmax;printf("请输入两个整数:");scanf("%d %d",&x,&y);max=getMax(x,y);printf("较大的数是:%d\n",max);return0;}intgetMax(inta,intb){if(a>b){returna;}else{returnb;}}

拆开看:

intgetMax(inta,intb);

这是函数声明,提前告诉编译器:后面会有一个getMax函数。

max=getMax(x,y);

这是函数调用。xy是实参,真正传给函数的数据。

intgetMax(inta,intb){if(a>b){returna;}else{returnb;}}

这是函数定义。ab是形参,函数内部用它们比较大小,并通过return返回结果。

这个程序虽然简单,但函数的几个关键点都出现了:声明、定义、调用、参数、返回值。

真实项目里通常还会检查scanf是否读取成功。为了让入门示例更清楚,这里先保留最简单写法。

十一、初学者常见错误

错误类型示例问题原因正确理解
忘记函数声明main前调用了后面才定义的函数编译器提前不知道函数信息在前面写函数声明
返回值类型不匹配int f() { return 3.14; }会发生类型转换,可能丢失信息返回类型要和结果匹配
void函数还拿来赋值int x = sayHello();sayHello不返回结果void函数只执行动作
参数个数不对add(1);函数需要两个参数,只给了一个调用时参数数量要匹配
混淆形参和实参ab当成调用时的固定值形参只是占位变量实参才是真正传入的值
局部变量跨函数使用main使用别的函数里的变量超出作用域用参数和返回值传递数据
忘记写 returnint f() { }声明返回int却没返回void函数应返回对应值

函数错误多数不是因为“函数很难”,而是因为调用、返回、作用域这些边界没分清。

十二、总结与 5 个要点

函数就是把一段代码打包成一个有名字的小模块。它让我们可以把重复逻辑收起来,把复杂任务拆开,把代码写得更清楚。

如果说变量是一个小盒子,数组是一排小盒子,那么函数就是一块代码积木。你可以把它拼进程序里,也可以在不同地方反复使用。

读完这篇文章,记住下面五点:

  1. 函数用来打包可复用代码。同一段逻辑写一次,需要时调用。
  2. 函数有结构。返回值类型、函数名、参数列表、函数体、return都各有作用。
  3. 声明、定义、调用不是一回事。声明是提前打招呼,定义是写具体实现,调用是让函数执行。
  4. 参数负责把数据传进去,返回值负责把结果带回来。
  5. 函数有作用域边界。函数里的局部变量,外面的函数不能直接使用。

先别急着学递归和函数指针。把普通函数写熟,理解参数、返回值和作用域,后面的复杂内容才不会像从天上掉下来。

C 语言中的函数到底是什么?从“重复劳动”到“代码积木”的入门课

适合读者:已经学过变量、iffor、数组等基础内容,准备开始理解函数的 C 语言新手。
阅读目标:读完这篇文章,你应该能明白函数是什么,分清函数声明、函数定义、函数调用,理解参数、返回值、void和作用域的基本用法。

想象你每天都要做一杯奶茶。流程大概是:

烧水 -> 放茶包 -> 加牛奶 -> 加糖 -> 搅拌

你当然可以每天重新写一遍这些步骤。问题是,写多了人会烦,代码也会烦。更好的办法是:把这套流程整理好,起个名字叫makeMilkTea。以后想喝奶茶时,直接调用这个流程。

函数就是这么来的。

函数就是把一段可以重复使用的代码打包起来,起一个名字,需要时调用它。

目录

  • 一、为什么 C 语言需要函数
  • 二、函数到底是什么
  • 三、函数的基本结构
  • 四、声明、定义、调用分别是什么
  • 五、参数和返回值有什么用
  • 六、形参和实参:名字像亲戚,其实很好分
  • 七、void 是什么意思
  • 八、变量作用域和函数
  • 九、函数如何让代码更清晰、更容易复用
  • 十、完整示例:用函数计算两个数的最大值
  • 十一、初学者常见错误
  • 十二、总结与 5 个要点

一、为什么 C 语言需要函数

学函数之前,先看一个朴素的问题:重复代码。

假设你要输出接水步骤,两次都要写:

printf("打开水龙头\n");printf("接水\n");printf("关水龙头\n");printf("打开水龙头\n");printf("接水\n");printf("关水龙头\n");

这段代码能运行,但它有三个问题:

  1. 重复。同样三行写了两遍。
  2. 难改。如果要把“接水”改成“接一杯水”,每个地方都要改。
  3. 不清晰。代码一多,读者会被重复细节淹没。

如果用函数,可以这样写:

voidgetWater(void){printf("打开水龙头\n");printf("接水\n");printf("关水龙头\n");}

需要接水时调用它:

getWater();getWater();

这样代码就清爽很多。函数的作用不是让程序看起来高级,而是把重复劳动收纳起来。程序员喜欢偷懒,但这种偷懒叫“抽象”,听起来立刻正经了不少。

二、函数到底是什么

函数可以理解成一个“代码积木”。

你把一段代码打包成一个小模块,给它起名字。以后哪里需要,就把这块积木拿出来用。

函数通常解决三类问题:

问题函数怎么帮忙
重复代码太多把重复逻辑打包
程序太长不好读把大任务拆成小任务
同一功能多处使用写一次,多次调用

比如计算两个数的和:

intadd(inta,intb){returna+b;}

这个函数的意思是:给我两个整数,我返回它们的和。

像不像一个小工具?你把材料递进去,它把结果递回来。

三、函数的基本结构

一个函数通常长这样:

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

add来看:

intadd(inta,intb){returna+b;}

拆开解释:

部分示例含义
返回值类型int函数最后会返回一个整数
函数名add调用这个函数时使用的名字
参数列表int a, int b调用函数时需要提供两个整数
函数体{ ... }函数真正执行的代码
returnreturn a + b;把结果返回给调用者

也可以画成一个小盒子:

输入参数 a, b ↓ [ add 函数 ] ↓ 返回 a + b

函数像一个小加工厂:参数是原材料,函数体是加工流程,返回值是成品。

四、声明、定义、调用分别是什么

这三个词特别容易把新手绕晕。用“开店”来理解会轻松一点。

概念小白理解代码例子
函数声明先贴个招牌:我这里有这个函数int add(int a, int b);
函数定义真正把店开起来,写清楚怎么干活int add(int a, int b) { return a + b; }
函数调用顾客来点单,让函数执行add(3, 5);

1. 函数声明

intadd(inta,intb);

声明告诉编译器:后面会有一个叫add的函数,它接收两个int,返回一个int

2. 函数定义

intadd(inta,intb){returna+b;}

定义才是真正写函数内容的地方。

3. 函数调用

intresult=add(3,5);

调用就是让函数真正执行。这里add(3, 5)会得到结果8,再赋值给result

完整示例:

#include<stdio.h>intadd(inta,intb);// 函数声明intmain(void){intresult=add(3,5);// 函数调用printf("%d\n",result);return0;}intadd(inta,intb){// 函数定义returna+b;}

为什么要声明?因为 C 语言编译时通常从上往下看。main先用到了add,编译器需要提前知道:这个函数确实存在,而且应该怎么用。

五、参数和返回值有什么用

函数如果完全不接收数据,也不返回结果,就像一个只会喊口号的工具。能用,但用途有限。

参数和返回值让函数真正灵活起来。

1. 参数:把数据传进去

intadd(inta,intb){returna+b;}

这里的ab是参数。调用时可以传不同的值:

add(1,2);add(10,20);add(100,200);

同一个函数,因为参数不同,可以处理不同数据。

2. 返回值:把结果带回来

intsum=add(3,5);

add(3, 5)算出8,这个8就是返回值。调用者可以把它保存起来、打印出来,或者继续参与计算。

调用者给函数:3 和 5 函数内部计算:3 + 5 函数返回结果:8

做奶茶也是一样。参数可以是“甜度、杯数、是否加冰”,返回值就是做好的奶茶。只不过 C 语言不会真的给你递奶茶,最多给你一个结果。

六、形参和实参:名字像亲戚,其实很好分

形参和实参是函数里很常见的一对词。

名称出现位置含义
形参函数定义里占位用的变量
实参函数调用时真正传进去的值

看代码:

intadd(inta,intb){returna+b;}intresult=add(3,5);

这里:

  • ab是形参;
  • 35是实参。

你可以把形参理解成点单表上的空格,实参就是你真正填进去的内容。

形参:甜度、杯数 实参:七分糖、2 杯

函数被调用时,实参的值会传给形参。函数内部用形参做计算。

七、void 是什么意思

void在函数里常见,有两个主要意思。

1. 没有返回值

voidsayHello(void){printf("Hello!\n");}

函数名前面的void表示:这个函数不返回结果。它只是做一件事,比如输出一句话。

调用时这样写:

sayHello();

不能这样写:

intx=sayHello();// 错误:sayHello 没有返回值

2. 没有参数

voidsayHello(void)

括号里的void表示:这个函数不需要你传任何参数。

所以void sayHello(void)可以理解成:

不需要输入,也不返回结果,只负责打招呼。

如果函数既不需要输入,也不需要输出,void就会出现两次。看着有点重复,其实很诚实。

八、变量作用域和函数

函数会形成自己的小房间。你在函数里定义的变量,通常只能在这个函数里使用。

voidtest(void){intx=10;printf("%d\n",x);}intmain(void){printf("%d\n",x);// 错误:main 里看不到 test 里的 xreturn0;}

xtest函数里的局部变量。它住在test的房间里,main不能隔墙直接拿。

这叫作用域。先记住一句话:

变量在哪里定义,通常就只能在哪里附近使用。

函数之间如果要传数据,不能靠“偷看别人房间”,而要通过参数和返回值。

intsquare(intx){returnx*x;}

这里main可以把一个数传给squaresquare算完后通过return把结果带回来。这才是函数之间沟通的正规路线。

九、函数如何让代码更清晰、更容易复用

函数最大的价值,不只是“少写几行代码”。它还会让程序结构更清楚。

比如一个成绩程序可以拆成:

输入成绩 -> 计算平均分 -> 判断是否及格 -> 输出结果

写成函数后可以变成:

inputScores();average=calculateAverage();printResult(average);

这三行不一定能直接运行,因为它们只是示意:把不同任务拆成不同函数。哪怕你还不知道函数内部怎么写,也能大概看懂程序在做什么。

这就是函数的好处:

好处说明
减少重复同一段逻辑写一次,多次调用
结构清晰大任务拆成小任务
方便修改改函数内部,调用处不用全改
容易测试可以单独测试某个函数
更像人类思考每个函数负责一件事

好的函数不一定很长。很多时候,一个函数如果能清楚表达一件事,就已经很有价值。

十、完整示例:用函数计算两个数的最大值

下面写一个完整、可运行的小程序:输入两个整数,输出较大的那个。

#include<stdio.h>intgetMax(inta,intb);intmain(void){intx;inty;intmax;printf("请输入两个整数:");scanf("%d %d",&x,&y);max=getMax(x,y);printf("较大的数是:%d\n",max);return0;}intgetMax(inta,intb){if(a>b){returna;}else{returnb;}}

拆开看:

intgetMax(inta,intb);

这是函数声明,提前告诉编译器:后面会有一个getMax函数。

max=getMax(x,y);

这是函数调用。xy是实参,真正传给函数的数据。

intgetMax(inta,intb){if(a>b){returna;}else{returnb;}}

这是函数定义。ab是形参,函数内部用它们比较大小,并通过return返回结果。

这个程序虽然简单,但函数的几个关键点都出现了:声明、定义、调用、参数、返回值。

真实项目里通常还会检查scanf是否读取成功。为了让入门示例更清楚,这里先保留最简单写法。

十一、初学者常见错误

错误类型示例问题原因正确理解
忘记函数声明main前调用了后面才定义的函数编译器提前不知道函数信息在前面写函数声明
返回值类型不匹配int f() { return 3.14; }会发生类型转换,可能丢失信息返回类型要和结果匹配
void函数还拿来赋值int x = sayHello();sayHello不返回结果void函数只执行动作
参数个数不对add(1);函数需要两个参数,只给了一个调用时参数数量要匹配
混淆形参和实参ab当成调用时的固定值形参只是占位变量实参才是真正传入的值
局部变量跨函数使用main使用别的函数里的变量超出作用域用参数和返回值传递数据
忘记写 returnint f() { }声明返回int却没返回void函数应返回对应值

函数错误多数不是因为“函数很难”,而是因为调用、返回、作用域这些边界没分清。

十二、总结与 5 个要点

函数就是把一段代码打包成一个有名字的小模块。它让我们可以把重复逻辑收起来,把复杂任务拆开,把代码写得更清楚。

如果说变量是一个小盒子,数组是一排小盒子,那么函数就是一块代码积木。你可以把它拼进程序里,也可以在不同地方反复使用。

读完这篇文章,记住下面五点:

  1. 函数用来打包可复用代码。同一段逻辑写一次,需要时调用。
  2. 函数有结构。返回值类型、函数名、参数列表、函数体、return都各有作用。
  3. 声明、定义、调用不是一回事。声明是提前打招呼,定义是写具体实现,调用是让函数执行。
  4. 参数负责把数据传进去,返回值负责把结果带回来。
  5. 函数有作用域边界。函数里的局部变量,外面的函数不能直接使用。

先别急着学递归和函数指针。把普通函数写熟,理解参数、返回值和作用域,后面的复杂内容才不会像从天上掉下来。

http://www.jsqmd.com/news/957940/

相关文章:

  • Anthropic:当 AI 开始构建自身
  • AI工具如何重构排序逻辑:7个被90%团队忽略的智能排序性能拐点
  • 吴恩达深度学习笔记第三周:手把手推导单隐层神经网络的前向与反向传播
  • 2026年南京汽车维修服务TOP10榜:小保养/换机油/补胎换胎/底盘异响/发动机维修/钣金喷漆/24小时拖车救援专业精选 - 品牌企业推荐师(官方)
  • Python之stringsim包语法、参数和实际应用案例
  • 如何快速掌握Figma中文界面:设计师的终极解决方案指南
  • 不用下载直接改!主流网盘在线编辑功能深度实测 - 品牌测评鉴赏家
  • 2026亲测10款降AIGC软件红黑榜!优缺点无保留曝光,达标率直接对标行业天花板
  • 家用台式洗碗机实力品牌推荐榜单:GORGENOX歌嘉诺凭精工高性价比领跑,台式洗碗机、免安装洗碗机、超窄洗碗机、嵌入式美妆冰箱、台下嵌入式冰箱高口碑全解析 - 变量人生001
  • 实战指南:基于快马平台构建企业级oh my opencode开源生态平台
  • 北京家中闲置字画出手怎么选?本地六大上门回收商家实力排名 - 品牌排行榜单
  • A股指数不上涨不赚钱的原因
  • 实在Agent有没有针对开发者的个人终身免费版?2026开发者政策与企业级AI智能体演进深度评测
  • 2026 湖州防水补漏哪家好?住建实地测评权威榜单 TOP5|卫生间免砸砖 / 阳台屋顶 / 厨卫漏水维修(6 月湖州专项调研) - 苏易修缮
  • 如何用快马平台将markdown文档秒变可运行网站原型
  • 快速构建前端工具库原型:用快马一键生成小宇工具库完整项目框架
  • TIA Portal避坑指南:Get_Alarm指令读取ProDiag报警的5个常见错误与调试技巧
  • DataX从入门到精通 第2课 ETL之DataX 安装datax-web
  • 主流网盘在线追剧播放体验深度实测对比
  • DVWA-File Upload
  • DataX从入门到精通 第1课 ETL之DataX 安装DataX
  • 2026连云港防水补漏哪家好?住建实地测评权威榜单TOP5|卫生间免砸砖/阳台屋顶/厨卫漏水维修(6月连云港专项调研) - 苏易修缮
  • opencv识别抖音的评论区其实很简单
  • 告别锐捷客户端:WinSCP+抓包工具,给Padavan路由器‘植入’校园网认证的完整指南
  • 三步突破:重新定义Dell G15散热控制的轻量革命
  • 八目蛛网络(免费工具网站导航)
  • 有没有免费或低成本的工单系统推荐?
  • 如何在3分钟内实现WPS与Zotero的无缝对接:跨平台文献管理终极指南
  • 用Matlab GUI做个指纹锁原型:从图像处理到特征匹配的完整实战(附源码)
  • 新手福音:用快马平台生成burpsuite安装交互教程,三步完成安全工具部署