首页 > 编程笔记 > C语言笔记 阅读:2

C语言函数的定义和调用(图文并茂,非常详细)

函数是 C语言中非常重要的一部分,因为它们可以让你编写更加模块化、易于维护的代码。

C语言函数的定义

在编程语言中,函数就像一个工具箱,具有以下三个特性:
举例来说,我们如果想要计算 a 和 b 两个数的和,则可以写一个函数来实现它:
下面是一个名为 add() 的函数的定义,其中的代码实现了上述功能:
int add(int a, int b)
{
    return a + b;
}

因此,可以总结出函数的书写格式:
函数返回值类型 函数名(函数输入参数)
{
    做一些事情
    return 函数返回值;
}
上述格式中,用花括号括起来的部分被称为函数体,函数体必须用花括号明确地界定。由函数名、函数输入参数及函数返回值类型组成的部分被称为函数头,如下图所示:


图 1 函数头与函数体

下图对 add() 函数进行了详细的解析:


图 2 add()函数的解析

该函数的输入参数为 int a 和 int b,并通过 return 语句返回了它们的和。

需要注意的是,每个输入参数都必须指明其变量类型,不能省略变量类型。例如:
int add(int a, int b)  //  正确
int add(int a, b)      //  错误
自定义函数的函数名可以按照个人喜好来选择,甚至可以使用 aaaaa 这样的名字。但是,为了使函数名具有语义化,便于人们阅读和理解代码,通常建议使用有意义的英文来命名函数。

C语言函数的调用

函数定义完成后,需要在另一个函数中进行调用才能执行。

例如,使用 main() 函数来调用 add() 函数:
#include <stdio.h>

int add(int a, int b)
{
    return a + b;
}

int main()
{
    int result;
    result = add(2, 3);  // 调用 add 函数
    printf("%d", result);
    return 0;
}
在上述代码中,main() 函数被称为主调函数,而 add() 函数被称为被调函数。

在 main() 函数中,我们将 2 和 3 两个参数传递给 add() 函数,并调用它。在 add() 函数头中,定义了函数的返回值类型为 int,这表明该函数被调用后将返回一个 int 类型的结果。因此,我们使用一个 int 类型的变量 result 来存储 add() 函数的返回值。

整个调用过程的具体解析如下图所示:


图 3 add() 函数的调用过程解析

使用函数的意义

为什么需要将代码封装为函数呢?如果程序需要多次完成某项任务,你可以选择两个方案:
下面演示如何使用代码求解三角形的面积,并探讨将其封装为函数的优点。

假设在平面内有一个三角形,其三条边的长度分别为 a、b、c,三角形的面积 S 可以通过下图中的海伦公式计算得出:


图 4 海伦公式

此外,三角形中任意两边的长度之和必须大于第三边,否则无法构成三角形。也就是说,三角形的三条边必须满足以下不等式:

a + b > c
a + c > b
b + c > a

例如,当 a = 1,b = 1,c = 1 时,可以构成一个三角形;但当 a = 1,b = 1,c = 3 时,无法构成三角形。

接下来,我们将使用代码计算三角形的面积。首先,我们需要判断三条边是否能够构成一个合法的三角形。为了实现这一点,我们可以使用下面的代码来判断:
if (a + b > c && a + c > b && b + c > a)
{
    printf("It's a triangle\n");
}
else
{
    printf("Not a triangle\n");
}

接下来,我们可以使用海伦公式来计算三角形的面积 s。其中,a、b、c 分别表示三角形的三条边长度,p 为三角形半周长。我们可以写出如下代码:
p = (a + b + c) / 2;
s = sqrt(p * (p - a) * (p - b) * (p - c));
sqrt() 是平方根函数,使用它需要包含头文件 <math.h>

完整的代码如下:
#include <stdio.h>
#include <math.h>  // 需要包含头文件 math.h

int main()
{
    // 输入 a、b、c
    double a, b, c, p, s;
    scanf("%lf %lf %lf", &a, &b, &c);

    // 是否能构成三角形
    if (a + b > c && a + c > b && b + c > a)
    {
        printf("It's a triangle\n");
    }
    else
    {
        // 无法构成三角形,程序结束
        printf("Not a triangle\n");
        // 这里 return 0 表示 main 函数结束
        return 0;
    }

    // 求三角形的面积
    p = (a + b + c) / 2;
    s = sqrt(p * (p - a) * (p - b) * (p - c));  // 修正了公式,添加了 (p-c)
    // 输出结果
    printf("s=%f", s);
    return 0;
}
需要注意的是,上述代码中的 scanf() 函数用于获取从键盘中输入的三个 double 类型的变量。我们可以在程序运行时依次输入三个数字,并用空格或 Enter 键将它们分隔开。此外,我们使用 printf() 函数输出结果。

运行上述代码,输入三条边的长度,例如 3、4、5,执行结果如下:

3 4 5
It's a triangle
s=6.000000

复用代码

在计算三角形面积的程序中,可以将其分解为两个可复用的部分:
有时候我们只需要知道给定的三条边能否构成三角形,而不需要计算其面积。因此,我们可以将这部分代码提取为一个独立的函数,以提高代码的可复用性。具体代码如下:
int isTriangle(double a, double b, double c)
{
    //  是否能构成三角形
    if (a + b > c && a + c > b && b + c > a)
    {
       return 1;
    }
    return 0;
}
函数 isTriangle() 接收三个参数:三角形的三条边长 a、b、c。该函数的返回值为一个整型,其中 1 表示可以构成三角形,0 表示不能构成三角形。

接下来,我们将计算三角形面积的代码也提取为一个函数,具体代码如下:
double areaOfTriangle(double a, double b, double c)
{
    double p, s;
    p = (a + b + c) / 2;
    s = sqrt(p * (p - a) * (p - b) * (p - c));
    return s;
}
函数 areaOfTriangle() 同样接收三个参数:三角形的三条边长 a、b、c。该函数的返回值为三角形的面积。使用者无须关心函数内部的实现细节,只需正确地传入参数即可获得计算结果。

最后,我们把之前的程序改写为使用函数的形式,具体的代码为:
#include <stdio.h>
#include <math.h>  // 需要包含 math.h

// 求三角形的面积
double areaOfTriangle(double a, double b, double c)
{
    double p, s;
    // 求三角形的面积
    p = (a + b + c) / 2;
    s = sqrt(p * (p - a) * (p - b) * (p - c));
    return s;
}

// 是否能构成三角形
int isTriangle(double a, double b, double c)
{
    // 是否能构成三角形
    if (a + b > c && a + c > b && b + c > a)
    {
        return 1;
    }
    return 0;
}

int main()
{
    // 输入 a、b、c
    double a, b, c;
    scanf("%lf %lf %lf", &a, &b, &c);

    // 是否能构成三角形
    if (isTriangle(a, b, c) == 0)
    {
        printf("Not a triangle\n");
        return 0;
    }

    // 求三角形的面积
    double s;
    s = areaOfTriangle(a, b, c);
    printf("area of triangle is %f", s);
    return 0;
}

相关文章