C语言函数调用的5种方法(附带实例)

36587 📅 2025-07-29 14:19:55 👤 admin 👁️ 8468 ❤️ 437
C语言函数调用的5种方法(附带实例)

在生活中,为了能完成某项特殊的工作,可能需要使用具有特定功能的工具。在使用工具之前需要先制作这个工具,工具制作完成后,才可以使用。

C语言中的函数就像要实现某项功能的工具,而使用函数的过程就是函数的调用。

C语言函数的调用方式

一种工具可能不止有一种使用方式,就像雨伞一样,它既可以遮雨也可以遮阳光,函数的调用也是如此。

函数的调用方式有 5 种,包括函数语句调用、函数表达式调用、函数参数调用、函数嵌套调用和函数递归调用。

1) 函数语句调用

把函数调用作为一条语句就称为函数语句调用。函数语句调用是常使用的调用函数的方式。

定义一个函数,使用函数语句调用方式,通过调用函数实现输出一条信息的功能,进而观察函数语句调用的使用方式。

具体代码如下:

#include /* 包含头文件 */

void Display() /* 定义函数 */

{

/* 输出一条信息的功能 */

printf("三人行,必有我师焉,择其善者而从之,其不善者而改之 \n");

}

int main() /* 主函数 main() */

{

Display(); /* 调用函数输出语句 */

return 0; /* 程序结束 */

}

在介绍定义与声明函数时曾说明过,如果在使用函数之前定义函数,那么此时的函数定义包含函数声明。

运行程序,结果为:

三人行,必有我师焉,择其善者而从之,其不善者而改之

2) 函数表达式调用

函数出现在一个表达式中,这时会要求函数必须返回一个确定的值,这个值则作为参加表达式运算的一部分。

定义一个函数,其功能是利用欧姆定律(R=U/I)计算电阻值,并在表达式中调用该函数,使得函数的返回值参加运算得到新的结果。

具体代码如下:

#include /* 包含头文件 */

/* 声明函数,进行计算 */

void TwoNum(float iNum1, float iNum2);

int main()

{

TwoNum(5, 10); /* 调用函数计算表达式的值 */

return 0;

}

void TwoNum(float iNum1, float iNum2) /* 定义函数 */

{

float iTempResult; /* 定义整型变量 */

/* 进行计算,并将结果赋给 iTempResult */

iTempResult = iNum1 / iNum2;

printf("电阻值是 %f\n", iTempResult); /* 输出电阻值 */

}

运行程序,结果为:

电阻值是 0.500000

3) 函数参数调用

将函数作为另一个函数的实参调用,这样将函数返回值作为实参传递到函数中使用。函数出现在一个表达式中,这时要求函数返回一个确定的值,这个值会参加表达式的运算。

编写 getTemperature() 函数返回体温,将返回的结果传递给 judgeTemperature() 函数。把函数作为参数使用,在程序中定义 getTemperature() 函数,又定义 judgeTemperature() 函数,而 judgeTemperature() 的参数是 getTemperature()。

具体代码如下:

#define _CRT_SECURE_NO_WARNINGS /* 解除 vs 安全性检测问题 */

#include /* 包含头文件 */

void judgeTemperature(int temperature); /* 声明函数 */

int getTemperature(); /* 声明函数 */

int main() /* 主函数 main() */

{

judgeTemperature(getTemperature()); /* 调用函数 */

return 0; /* 程序结束 */

}

int getTemperature() /* 定义体温函数 */

{

int temperature;

printf("please input a temperature:\n"); /* 输出提示信息 */

scanf("%d", &temperature); /* 输入体温 */

printf("当前体温是: %d\n", temperature); /* 输出当前体温 */

return temperature; /* 返回体温 */

}

void judgeTemperature(int temperature) /* 自定义体温正常函数 */

{

if (temperature <= 312.3f && temperature >= 36) /* 判断体温是否正常 */

printf("体温正常 \n");

else

printf("体温不正常 \n");

}

运行程序,结果为:

please input a temperature:

35

当前体温是: 35

体温不正常

4) 函数嵌套调用

在 C语言中,函数的定义都是互相平行、独立的,也就是说在定义函数时,一个函数体内不能包含定义的另一个函数。

例如,下面的代码是错误的:

int main()

{

void Display() /*错误!!!不能在函数内定义函数*/

{

printf("I want to show the Nesting function");

}

return 0;

}

从上面的代码可以看到,在主函数 main() 中定义了一个 Display() 函数,目的是输出一句提示信息。但 C语言是不允许进行嵌套定义的,因此编译时就会出现下面的错误提示:

[Error] a function-definition is not allowed here before '{' token

虽然 C语言不允许进行嵌套定义,但是可以嵌套调用函数,也就是说,在一个函数体内可以调用另外一个函数。例如,使用下面的代码进行函数的嵌套调用:

void ShowMessage() /*定义函数*/

{

printf("The ShowMessage function");

}

void Display()

{

ShowMessage(); /*正确,在函数体内进行函数的嵌套调用*/

}

嵌套过程如下:

从主函数 main() 入口进入程序,执行 main() 函数开头部分;

执行到调用 Display() 函数时,程序转向执行 Display() 函数;

执行 Display() 函数,从 Display() 函数头开始执行,执行到调用 ShowMessage() 函数,程序转向执行 ShowMessage() 函数;

执行 ShowMessage() 函数,从函数头开始执行,如果没有其他嵌套函数,则完成 ShowMessage() 函数的全部操作;

转向执行 Display() 函数中尚未执行的部分,直到 Display() 函数执行结束;

返回 main() 函数中调用 Display() 函数的调用处;

继续执行 main() 函数剩余部分,直到 main() 函数执行结束。

可用一个例子来理解嵌套过程,某公司的 CEO 决定该公司要完成一个方向的目标,但是要完成这个目标就需要将其讲给公司的经理,公司中的经理需将要做的内容再传递给下级的副经理,副经理再讲给下属职员,职员按照上级的指示进行工作,最终完成目标。其过程如下图所示。

图 1 嵌套过程

在嵌套调用函数时,一定要在使用前进行原型声明。

利用嵌套函数模拟上述比喻中描述的过程,将每一个位置的人要做的事情封装成一个函数,通过调用函数完成最终目标。具体代码如下:

#include

void CEO(); /*声明函数*/

void Manager();

void AssistantManager();

void Clerk();

int main()

{

CEO(); /*调用CEO的作用函数*/

return 0;

}

void CEO()

{

/*输出信息,表示调用CEO()函数进行相应的操作*/

printf("CEO下达命令给经理\n");

Manager(); /*调用经理的作用函数*/

}

void Manager()

{

/*输出信息,表示调用Manager()函数进行相应的操作*/

printf("经理下达命令给副经理\n");

AssistantManager(); /*调用副经理的作用函数*/

}

void AssistantManager()

{

/*输出信息,表示调用AssistantManager()函数进行相应的操作*/

printf("副经理下达命令给职员\n");

Clerk(); /*调用职员的作用函数*/

}

void Clerk()

{

/*输出信息,表示调用Clerk()函数进行相应的操作*/

printf("职员执行命令\n");

}

运行程序,结果为:

CEO下达命令给经理

经理下达命令给副经理

副经理下达命令给职员

职员执行命令

5) 函数递归调用

在调用函数的过程中又直接或间接地调用其本身,称为函数的递归调用。递归调用分为直接递归调用和间接递归调用两种。

直接递归调用过程如下图所示:

图 2 直接递归调用过程

间接递归调用,是指在递归函数调用的下层函数中再调用原函数。间接递归调用过程如下图所示。

图 3 间接递归调用过程

从图 2 和图 3 可以看出,这两种递归调用都是无止境地调用自身。程序不应该出现这样无止境的循环,应该有结束条件。通常可在函数内部加一个条件判断语句,在满足条件时停止递归调用,然后逐层返回。

这种机制是目前大多数程序设计语言实现子程序结构的基础,这也使得递归成为可能。假定某个调用函数调用了一个被调用函数,再假定被调用函数又反过来调用了调用函数,那么第二个调用就称为调用函数的递归,它发生在调用函数的当前执行过程结束之前。

而且,因为原先的调用函数、现在的被调用函数在栈中较低的位置有独立的一组参数和自变量,原先的参数和变量将不受任何影响,所以递归能正常进行。

例如,有 5 个人坐在一起,猜第 5 个人的年龄。戊说比丁大 2 岁,问丁的岁数;丁说比丙大 2 岁,问丙的岁数;丙说比乙大 2 岁,问乙的岁数;乙说比甲大 2 岁,问甲的岁数;甲说他 10 岁。下图所示是岁数的示意图,一层调用一层。

图 4 递归调用示意图

用递归的方式求上述例子中戊的年龄。具体代码如下:

#include

int getage(int n); //声明函数

int main()

{

int age; //定义整型变量,存储年龄

age = getage(5); //调用函数计算年龄

printf("戊的年龄是:%d岁\n", age); //输出戊的年龄

return 0; //程序结束

}

int getage(int n) //自定义函数

{

if (n==1) //如果是甲

{

return 10; //返回10岁

}

return 2 + getage(n - 1); //递归调用,调用getage()函数本身,同时加2

}

运行程序,结果为:

戊的年龄是:18岁

相关养生推荐

寞字五行属性是什么,寞字起名字的含义
365买球怎么玩

寞字五行属性是什么,寞字起名字的含义

📅 07-09 👁️ 2821
崩坏3次元攻略大全 次元边界突破使用心得
365bet现金

崩坏3次元攻略大全 次元边界突破使用心得

📅 07-25 👁️ 3340
1800ml酒是多少斤,如何换算1800ml酒的重量?
365买球怎么玩

1800ml酒是多少斤,如何换算1800ml酒的重量?

📅 07-10 👁️ 6500
怪物怪物的英语怎么说
365买球怎么玩

怪物怪物的英语怎么说

📅 07-16 👁️ 5218
二、什么是DNS服务器?
36587

二、什么是DNS服务器?

📅 07-06 👁️ 4707