写在开头

函数

本讲内容教基础,主要讲解:

  • 概念引入
  • 函数分类
  • 函数定义(返回值、函数名、参数)
  • 函数实现
  • 函数调用
  • 实参与形参
  • 嵌套
  • 递归
  • 局部变量与全局变量

概念引入

前一讲我们讲到了数组,在输出数组时,每次都要重写一个for循环,然后开始遍历,很麻烦。今天,我们将使用函数,来对输出数组进行优化。

函数:有具体功能的代码块

函数有以下几个好处:

  • 将程序模块化(封装)
  • 实现代码复用
  • 使代码易于维护

函数分类

根据角度不同,函数可以分为很多种类,一般分为:

  • 系统函数
  • 自定义函数

系统函数

由C系统提供,用户无须定义,也不必在程序中作类型说明,只需在程序前包含有该函数原型的头文件即可在程序中直接调用。

之前用到的属于stdio.h头文件的,printfscanf函数。以及属于string.hstrlenstrcpy函数。

自定义函数

按需要,自己写的函数。

函数定义

函数定义:

返回值类型 函数名(参数列表) {

    函数体
}

我们可以来看看经常用到的main函数:

int main(int argc, const char * argv[]) {

    // 因为返回值为int,所以需要return一个整型。
    return 0;
}

表示:函数名为main,返回值为int,参数有两个int argc, const char * argv[]

无参数无返回值的定义:

void test() {

    // 因为没有返回值,所以可以不用写return xxxx;
    // 如果一定要提前结束函数,也可以直接
    return; // 不用接具体的值
}

注意:

  • 不允许把一个函数定义在另一个函数内
  • 不同函数定义放置位置没有关系

函数调用

如果函数的定义写在调用函数以后,那么需要进行声明。如果定义在调用函数以前,则不需要声明(告诉编译器有这个函数)。

先来看下面这个完整的例子:

// test2函数的声明,与函数定义一样,只是将{}改成了;
void test2();

// 在main函数中调用了test1,因为test1定义在main函数以前,所以不用声明
void test1() {


}

int main(int argc, const char * argv[]) {

    test1();
    test2();

    return 0;
}

// test2定义在调用它的main函数之后,所以如果在main函数要调用,必须将函数声明写在main函数之前
void test2() {


}

练习

写一个函数,传两个参数a, b,返回他们之中,较大的那一个。

通过这道题,将讲解有参数的函数怎么定义、实现与调用。

int getMax(int number1, int number2) {

    return number1 > number2 ? number1 : number2;
}

int main(int argc, const char * argv[]) {

    int max = getMax(4, 9);
    printf("max = %d", max);
}

形参与实参

练习

尝试交换两个数的位置

选择排序

直接插入排序

输出一个数组

嵌套调用

在函数中调用函数。

递归

递归是算法中的一种,实现方式为函数自己调用自己。

练习

求n!

变量作用域

  • 局部变量
  • 全局变量