# 函数

C程序的基本组成部分是函数,每个C程序都有一个主函数main(),所有的函数都是由main()开始调用的。函数是一组一起执行一个任务的语句。每个C程序都至少有一个函数,即主函数main(),所有简单的程序都可以定义其他额外的函数。您可以把代码划分到不同的函数中。如何划分代码到不同的函数中是由您来决定的,但在逻辑上,划分通常是根据每个函数执行一个特定的任务来进行的。

从函数定义的角度来看,C程序可分为两大部分:

  • 主函数main():主函数是每个程序必须有的,是程序执行的入口,一般情况下,主函数不嵌套定义其他函数,但可以调用其他函数。

  • 其他函数:除了主函数以外的其他函数,可以嵌套定义在主函数中,也可以定义在主函数外面,但必须在主函数调用之前定义。

# 函数的定义

函数定义包括函数头和函数体两部分。

  • 函数头:由函数名、形式参数列表、返回值类型和函数的返回值组成。

  • 函数体:由一条或多条C语句组成,它们定义了函数的功能。


#include <stdio.h>

//函数声明

int max(int num1, int num2);

int main() {

    //局部变量声明
    int a = 100;
    int b = 200;
    int ret;

    //调用函数来获取最大值
    ret = max(a, b);

    printf("Max value is : %d\n", ret);

    return 0;
}

//函数返回两个数中较大的那个数

int max(int num1, int num2) {

    //局部变量声明
    int result;

    if (num1 > num2)
        result = num1;
    else
        result = num2;

    return result;
}

# 函数的调用

C语言中的函数调用很简单,您只需要声明函数,定义函数以及调用函数即可。当程序调用函数时,程序控制权会转移给被调用的函数。被调用的函数执行已定义的代码,当函数的返回语句被执行时,或到达函数的结束括号时,会把程序控制权交还给主程序。


#include <stdio.h>

//函数声明

void swap(int *x, int *y);

int main() {

    //局部变量定义
    int a = 100;
    int b = 200;

    printf("交换前,a的值:%d\n", a);
    printf("交换前,b的值:%d\n", b);

    //调用函数来交换值
    swap(&a, &b);

    printf("交换后,a的值:%d\n", a);
    printf("交换后,b的值:%d\n", b);

    return 0;
}

//函数定义

void swap(int *x, int *y) {

    int temp;

    temp = *x;    //保存地址x的值
    *x = *y;    //把y赋值给x
    *y = temp;    //把temp赋值给y

    return;
}

# 函数参数

如果函数要使用参数,则必须声明接受参数值的变量。这些变量称为函数的形式参数。形式参数就像函数内的其他局部变量,在进入函数时被创建,退出函数时被销毁。

  • 形式参数:函数定义中的参数,用于接收调用该函数时传递给它的值。形式参数在函数被调用时被赋值,退出函数后被销毁。

  • 实际参数:函数调用时传递给函数的值,被称为实际参数。实际参数是在调用函数时产生的。

  • 形式参数和实际参数的区别:形式参数只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形式参数只有在函数内部有效。函数调用结束返回主调函数后则不能再使用该形式参数变量。实际参数可以是常量、变量、表达式、函数等,无论实际参数是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形式参数。

# 形式参数

形式参数就像函数内的其他局部变量,在进入函数时被创建,退出函数时被销毁。当调用函数时,有两种向函数传递参数的方式:

  • 传值调用:该方法把参数的实际值复制给函数的形式参数。在这种情况下,修改函数内的形式参数对实际参数没有影响。

  • 引用调用:通过指针传递方式,形参为指向实参地址的指针,当形参发生改变时,实参也发生改变。


#include <stdio.h>

//函数声明

void swap(int *x, int *y);

int main() {

    //局部变量定义
    int a = 100;
    int b = 200;

    printf("交换前,a的值:%d\n", a);
    printf("交换前,b的值:%d\n", b);

    //调用函数来交换值
    swap(&a, &b);

    printf("交换后,a的值:%d\n", a);
    printf("交换后,b的值:%d\n", b);

    return 0;
}

//函数定义

void swap(int *x, int *y) {

    int temp;

    temp = *x;    //保存地址x的值
    *x = *y;    //把y赋值给x
    *y = temp;    //把temp赋值给y

    return;
}

# 引用调用

C语言中,引用调用函数的实例,把一个变量的地址传递给函数,那么它就可以在函数中修改这个变量的值。这个例子使用了引用调用来交换两个数。


#include <stdio.h>

//函数声明

void swap(int *x, int *y);

int main() {

    //局部变量定义
    int a = 100;
    int b = 200;

    printf("交换前,a的值:%d\n", a);
    printf("交换前,b的值:%d\n", b);

    //调用函数来交换值
    swap(&a, &b);

    printf("交换后,a的值:%d\n", a);
    printf("交换后,b的值:%d\n", b);

    return 0;
}

//函数定义

void swap(int *x, int *y) {

    int temp;

    temp = *x;    //保存地址x的值
    *x = *y;    //把y赋值给x
    *y = temp;    //把temp赋值给y

    return;
}

# 传值调用

C语言中,传值调用函数的实例,把参数的实际值复制给函数的形式参数。在这种情况下,修改函数内的形式参数对实际参数没有影响。


#include <stdio.h>

//函数声明

void swap(int x, int y);

int main() {

    //局部变量定义
    int a = 100;
    int b = 200;

    printf("交换前,a的值:%d\n", a);
    printf("交换前,b的值:%d\n", b);

    //调用函数来交换值
    swap(a, b);

    printf("交换后,a的值:%d\n", a);
    printf("交换后,b的值:%d\n", b);

    return 0;
}

//函数定义

void swap(int x, int y) {

    int temp;

    temp = x;    //保存地址x的值
    x = y;    //把y赋值给x
    y = temp;    //把temp赋值给y

    return;
}

# 函数的返回值

C语言中,函数的返回值是函数执行完成后返回到主程序的值。C语言中,函数的返回值只能是一个,如果要返回多个值,只能通过指针的方式来实现。

# 返回值类型

函数返回值的类型,可以是任意的数据类型,包括基本类型和结构类型。当函数返回一个值时,它必须使用return语句。


#include <stdio.h>

//函数声明

int max(int num1, int num2);

int main() {

    //局部变量声明
    int a = 100;
    int b = 200;
    int ret;

    //调用函数来获取最大值
    ret = max(a, b);

    printf("Max value is : %d\n", ret);

    return 0;
}

//函数返回两个数中较大的那个数

int max(int num1, int num2) {

    //局部变量声明
    int result;

    if (num1 > num2)
        result = num1;
    else
        result = num2;

    return result;
}

# 返回指针

C语言中,函数的返回值可以是指针类型,但是不能返回一个局部变量的地址,因为局部变量在函数返回后会被释放掉。


#include <stdio.h>

//函数声明

int *getRandom();

int main() {

    //一个指向整数的指针
    int *p;

    p = getRandom();

    for (int i = 0; i < 10; ++i) {
        printf("*(p + %d) : %d\n", i, *(p + i));
    }

    return 0;
}

//函数返回随机数

int *getRandom() {

    static int r[10];

    //设置种子
    srand((unsigned) time(NULL));

    for (int i = 0; i < 10; ++i) {
        r[i] = rand();
        printf("%d\n", r[i]);
    }

    return r;
}

# 函数的递归调用

C语言中,函数的递归调用是指在一个函数的函数体内调用函数自身。函数的递归调用是合法的,但是要注意不要造成死循环。


#include <stdio.h>

//函数声明

int factorial(int i);

int main() {

    int i = 5;
    printf("%d 的阶乘是 %d\n", i, factorial(i));

    return 0;
}

//函数定义

int factorial(int i) {

    if (i <= 1) {
        return 1;
    }

    return i * factorial(i - 1);
}

# 函数的声明

C语言中,函数的声明是指在函数调用之前告诉编译器函数的名称、返回值类型和参数的类型。函数的声明可以在函数的定义之前或之后,如果在函数定义之前,那么函数的定义必须在函数调用之前。

TIP

  • 函数的声明只是告诉编译器函数的名称、返回值类型和参数的类型,函数的定义才是真正实现函数功能的地方。
  • 函数的声明可以在函数的定义之前或之后,如果在函数定义之前,那么函数的定义必须在函数调用之前。
  • 函数的声明可以多次,但是函数的定义只能有一次。
  • 函数的声明和函数的定义必须保持一致,否则会报错。
  • 函数的声明和函数的定义可以分别写在不同的文件中,但是函数的声明和函数的定义必须在同一个文件中。

#include <stdio.h>

//函数声明

int max(int num1, int num2);

int main() {

    //局部变量声明
    int a = 100;
    int b = 200;
    int ret;

    //调用函数来获取最大值
    ret = max(a, b);

    printf("Max value is : %d\n", ret);

    return 0;
}

//函数返回两个数中较大的那个数

int max(int num1, int num2) {

    //局部变量声明
    int result;

    if (num1 > num2)
        result = num1;
    else
        result = num2;

    return result;
}

# main 函数 exit 函数

在main函数中调用exit和return结果是一样的, 在子函数中调用exit和return结果是不一样的。exit函数是在stdlib.h中定义的,它的原型为: void exit(int status); 。exit函数的作用是终止当前正在执行的程序,status是一个整数,用来表示程序的终止状态,一般来说,0表示程序正常终止,非0表示程序的异常终止。exit函数的功能是终止当前正在执行的程序,它可以在任何地方调用,包括main函数中,它的作用是终止当前正在执行的程序,status是一个整数,用来表示程序的终止状态,一般来说,0表示程序正常终止,非0表示程序的异常终止。exit函数的功能是终止当前正在执行的程序,它可以在任何地方调用,包括main函数中,它的作用是终止当前正在执行的程序,status是一个整数,用来表示程序的终止状态,一般来说,0表示程序正常终止,非0表示程序的异常终止。


#include <stdio.h>

//函数声明

void func1();

int main() {

    printf("调用函数 func1 前...\n");

    func1();

    printf("调用函数 func1 后...\n");

    return 0;
}

//函数定义

void func1() {

    printf("进入函数 func1 ...\n");

    printf("调用 exit() 函数...\n");

    exit(0);

    printf("退出函数 func1 ...\n");
}

# 多文件编程

C语言中,多文件编程是指把程序分成多个文件,每个文件都可以单独编译,然后再把它们连接起来生成可执行文件。C语言中,多文件编程的好处是可以把程序分成多个文件,每个文件都可以单独编译,然后再把它们连接起来生成可执行文件。C语言中,多文件编程的好处是可以把程序分成多个文件,每个文件都可以单独编译,然后再把它们连接起来生成可执行文件。

# 头文件

C语言中,头文件是指包含函数声明、宏定义和类型定义的文件,头文件的扩展名是.h。C语言中,头文件是指包含函数声明、宏定义和类型定义的文件,头文件的扩展名是.h。C语言中,头文件是指包含函数声明、宏定义和类型定义的文件,头文件的扩展名是.h。

# 头文件的引用

C语言中,头文件的引用是指在源文件中使用#include指令包含头文件,#include指令的格式为: #include <filename>#include "filename"


#include <stdio.h>

#include "max.h"

int main() {

    //局部变量声明
    int a = 100;
    int b = 200;
    int ret;

    //调用函数来获取最大值
    ret = max(a, b);

    printf("Max value is : %d\n", ret);

    return 0;
}

# 头文件的保护

C语言中,头文件的保护是指在头文件中使用条件编译指令,防止头文件被重复引用


#ifndef MAX_H

#define MAX_H

int max(int num1, int num2);

#endif