C 函数定义

在 C 语言中,我们编写的程序通常由一个或多个函数组成。每个函数都有其特定的功能。在使用函数之前,我们需要对其进行 “声明” 和 “定义” 。

C 函数定义

在 C 语言中,函数定义是指提供函数的实际代码,包括函数名、参数列表和函数体。函数定义告诉编译器函数要做什么。

从返回值的角度来看,函数可以分为 2 种:一种是 “没有返回值的函数” ,另一种是 “有返回值的函数”。

1. 定义没有返回值的函数

在 C 语言中,没有返回值的函数,指的是函数执行完就算了,不会返回任何值。

语法:

void 函数名(参数1, 参数2, ..., 参数n)
{
    ……
}

说明:

如果一个函数没有返回值,那么我们应该在函数名前面加上 void,以表示这个函数的返回值为空。void 就是 “空” 的意思,它和 int、float 等一样,也是一种数据类型。

在 C 语言中,函数是一个用 “{}” 括起来的、可重复使用的、具有特定功能的语句块。每一个函数,就是独立的语句块(看成一个整体)。用 “{}” 括起来的,我们称之为语句块,像 ifwhiledo...whilefor 等语句中也有。对于语句块来说,我们都是把它当成整体来处理的。

函数的定义由 2 部分组成:函数头和函数体。函数头包括类型名、函数名、函数参数。函数体指的是 “{}” 括起来的那一部分,如下图所示。

C 函数定义语法

函数跟变量是非常相似的,如果想要使用一个变量,我们要先定义它的类型。同样地,函数也要定义类型,对于没有返回值的函数,它的类型就是 void。

在定义函数的时候,函数名不要随便取,尽量取有意义的英文名,让人一看就知道这个函数是干什么的。对于函数的参数,是可以省略 的(即不写),当然也可以是 1 个、2 个或 n 个。如果是多个参数,则参数之间用英文逗号(,)隔开。此外,函数参数的个数,一般取决于你实际开发的需要。

示例 1:定义一个没有返回值的函数

#include <stdio.h>

// 定义函数
void sum(int a, int b)
{
    int result = a + b;
    printf("%d", result);
}

int main(void)
{
    // 调用函数
    sum(10, 20);
    return 0;
}

运行结果如下。

30

分析:

在这个例子中,我们使用 void 定义了一个没有返回值的函数 sum(),该函数用于计算任意两个整数之和。其中函数名是可以随便取的,不过一般取能够表示函数功能的英文名或英文缩写。

void sum(int a, int b){…} 是函数的定义部分,对于函数的定义,我们一般放在 main() 函数的上方。这里的 a 和 b 是函数的参数,也叫做 “形参”。参数的名字也是随便取的。初学的小伙伴就会问了:“怎么判断一个函数需要多少个参数啊?” 其实很简单,上面这个函数用于计算两个整数之和,那肯定就是需要 2 个参数啦!

C 程序是从 main() 函数内部开始执行的,sum(10, 20); 是函数的调用,这里的 1 和 2 也是参数,叫做 “实参”。一般来说:函数定义时的参数叫做 “形参”,而函数调用时的参数叫做 “实参”

实际上,函数调用是和函数定义一一对应的,比如 sum(10, 20) 就刚好对应于 sum(a, b)。其中 10 对应 a,20 对应 b。因此 sum(10, 20); 相当于在函数内部执行了:

int a = 10;
int b = 20;

也就是说,函数调用其实就是把 “实参”(即 10 和 20)传递给 “形参”(即 a 和 b),然后再把函数执行一遍。对于上面这个例子,小伙伴可以改变一下函数调用时的参数,也就是把 “10 和 20” 换成其他试试,然后看看结果又是怎样的。

最后要说明一点,函数如果只有定义部分,却没有调用部分,这是一点意义都没有的。如果函数只定义而不调用,那么 C 语言就会自动忽略这个函数,也就是不会去执行这个函数。原因很简单,C 语言是从 main() 开始执行的,如果 main() 内部没有任何该函数的相关信息(比如函数调用),那么就等于没有用到这个函数。小伙伴们一定要记住:函数只有在被调用的时候,才会被执行

2. 定义有返回值的函数

在 C 语言中,有返回值的函数,指的是函数执行完了之后,会返回一个值,这个返回值可以供我们使用。

语法:

类型符 函数名(参数1 , 参数2 ,..., 参数n)
{
    ……
    return 返回值;
}

说明:

对于有返回值的函数,内部必须使用 return 来返回一个值,并且返回值的类型要和函数名前面的类型符相同。

示例 2:定义一个有返回值的函数

#include <stdio.h>

// 定义函数
int sum(int a, int b)
{
    int result = a + b;
    return result;
}

int main(void)
{
    // 调用函数
    int result = sum(10, 20) + 100;
    printf("%d", result);
    return 0;
}

运行结果如下。

130

分析:

在这个例子中,我们定义了一个有返回值的函数,该函数类型为 int。函数类型和它的返回值类型是相同的,所以它的返回值类型也要是 int。

这里的 sum() 函数和上一个例子的函数功能是一样的,都是用来计算两个整数之和。唯一不同的是,这个 sum() 函数会返回相加的结果。为什么要返回相加的结果呢?这是因为这个相加结果在后面要用到啊!现在小伙伴现在应该知道什么时候该用 return,什么时候不用 return 了吧?

一般情况下,如果后面的程序需要用到函数的计算结果,就要用 return 返回一个值;如果后面的程序不需要用到函数的计算结果,就不用 return 返回值。

当然了,对于上面这个例子,下面 2 种定义函数的方式是等价的。

// 方式 1
int sum(int a, int b)
{
    int result = a + b;
    return result;
}

// 方式 2
int sum(int a, int b)
{
    return a + b;
}

深入了解 C 函数定义

接下来我们给小伙伴们全面讲解一下与 C 函数定义相关的细节,主要包括以下几个方面。

  • 函数定义的位置。
  • 函数返回值的类型。
  • 函数的中断。
  • 函数有多个 return。

1. 函数定义的位置

在 C 语言中,如果想要定义一个函数,一般都是在主函数 main() 之前定义。实际上,我们还可以在 main() 函数 之后定义,只不过这种情况要在 main() 之前或在 main() 之内添加一个声明才可以。

示例 3:函数在 main() 之前定义

#include <stdio.h>

int max(int a, int b)
{
    return a > b ? a : b;
}

int main(void)
{
    printf("%d", max(10, 20));
    return 0;
}

运行结果如下。

20

示例 4:函数在 main() 之后定义

#include <stdio.h>

int max(int a, int b);      // 添加函数声明(必需)
int main(void)
{
    printf("%d", max(10, 20));
    return 0;
}

int max(int a, int b)
{
    return a > b ? a : b;
}

运行结果如下。

20

分析:

如果一个函数放在 main() 函数之外定义,那么它在使用之前必须添加一个函数声明才行。不过这个函数声明的位置,可以在 main() 函数之前,也可以在 main() 函数之内。下面 2 种方式都是可行的,小伙伴们可以自行试一下。

// 方式 1
int max(int a, int b);        // 在 main() 之前添加函数声明
int main(void)
{
    ……
}

// 方式 2
int main(void)
{
    int max(int a, int b);    // 在 main() 之内添加函数声明
    ……
}

在实际开发中,对于函数定义部分放在哪里,我们不能笼统一概而论,而是应该分为以下 2 种情况来选择。

  • 如果整个 C 程序函数的数量不多,那么放在 main() 之前比较好,这样可以省略声明代码。
  • 如果整个 C 程序函数的数量很多,那么放在 main() 之后比较好。如果全部放在 main() 之前,我们还得往下找半天才找到 main() 函数,代码可读性比较差。

总而言之:在 C 语言中,除了主函数 main() 之外,用户定义的函数必须遵循 “先声明,后使用” 的规则。

2. 函数返回值的类型

对于一个函数来说,它返回值的类型是由函数定义时的类型(也就是函数名前面的类型)决定的,而不是由 return 后面的值的类型决定的。

提示: 我们一般说起的 “函数的类型”,一般指的是它返回值的类型。

示例 5: “函数返回值的类型” 与 “函数定义的类型” 不一致

#include <stdio.h>

// 定义函数
int fn(void)
{
    float a = 3.14;
    return a;
}

int main(void)
{
    // 调用函数
    printf("%d", fn());
    return 0;
}

运行结果如下。

3

分析:

对于 fn() 函数来说,函数名前面的类型是 int,而 return 后面值的类型是 float。前后类型不一致,就会以函数名前面的为准。在实际开发中,我们一定要保证前后类型一致,否则可能会导致一些难以发现的 bug。

3. 提前退出函数

对于循环语句来说,如果想要中断循环,我们可以使用 “break 语句” 或 “continue 语句” 来实现。那么如果想要提前退出一个函数,我们又应该怎么实现呢?

示例 6:使用 return; 提前退出函数

#include <stdio.h>

// 定义函数
void fn(void) 
{
    int a = 20;
    int b = 10;
    printf("%d", a + b);
    return;
    printf("%d", a - b);
}
int main(void) 
{
    // 调用函数
    fn();
    return 0;
}

运行结果如下。

30

分析:

在 C 语言中,我们可以使用 “return;” 来中断一个函数,注意 return 后面只有一个分号。在上面的 fn() 函数中,当我们执行第 1 个 printf() 之后,遇到了 “return;”,此时就会直接中断函数(退出函数),后面第 2 个 printf() 就不会被执行了。

4. 函数有多个 return

在一个函数中,可以有多个 return 语句。但是只要有一个 return 语句被执行了,那么就会直接退出函数。

示例 7:函数包含多个 return 语句

#include <stdio.h>

// 定义函数
int fn(void)
{
    int a = 10, b = 20, c = 30;

    if (a < b)
    {
        return b;
    }
    if (b < c)
    {
        return c;
    }
    return 0;
}
int main(void) 
{
    // 调用函数
    printf("%d", fn());
    return 0;
}

运行结果如下。

20

分析:

在 fn() 这个函数中,两个 if 语句的条件都是真,但是执行了第 1 个 if 语句之后,遇到了一个 return 语句,所以就直接退出函数了,而不会执行后面的代码。

对于一个函数来说,它只能有一个返回值。就算有多个 return 语句,执行了第一个 return 语句,就直接退出函数了,这种方式可以很好地保证函数只能有一个返回值。

上一篇: C 函数

下一篇: C 函数调用

给站长反馈

绿叶网正在不断完善中,小伙伴们如果发现任何问题,还望多多给站长反馈,谢谢!

邮箱:lvyenet@vip.qq.com

「绿叶网」服务号
绿叶网服务号放大
关注服务号,微信也能看教程。
绿叶网服务号