C语言总结五:函数详细总结

本文详细介绍了C语言中的函数,包括函数的定义、分类、参数、返回值、调用方式和递归等内容。文章通过实例解析库函数的使用,自定义函数的定义与注意事项,并探讨了函数的参数传递方式。此外,重点讨论了函数递归,包括递归的必要条件和递归函数的编写实践,以及递归和迭代的比较。文章最后还提供了多个经典递归问题的练习,帮助读者深入理解递归在实际编程中的应用。
摘要由CSDN通过智能技术生成

        函数是C语言中非常重要的概念,在结构化程序设计中,函数是将任务进行模块划分的基本单位。通过函数,可以把一个复杂任务分解成为若干个易于解决的小任务。充分体现结构化程序设计由粗到精,逐步细化的设计思想。一个大的程序一般应分为若干个程序模块,每个模块实现一个特定的功能,这些模块称为子程序,在C语言中子程序用函数实现。函数的设计一般具有高内聚低耦合的特点,方便进行维护和使用。

      本篇博客详细总结函数的全部内容,达到学会使用函数和设计函数的目的!

目录

一、函数是什么?

二、C语言中函数的分类

2.1 库函数

2.1.1 如何使用库函数

2.2 自定义函数

2.2.1  C语言无参函数的定义

2.2.2  C语言有参函数的定义

2.2.3  函数不能嵌套定义

2.3  函数设计注意事项

2.4 练习

2.4.1写一个函数可以找出两个整数中的最大值

2.4.2 写一个函数求一组数中的最大数

2.4.3 利用函数实现从键盘输入一个数,输出它是几位数

三、函数参数(重点)

3.1 实际参数(实参)

3.2 形式参数(形参)

3.3 形参和实参的区别和联系(重点理解)

3.4 封装函数实现两个数的交换

四、函数返回值(return关键字)精讲

五、函数调用(重点)

5.1 传值调用

5.2 传址调用

5.3 练习

5.3.1  写一个函数可以判断一个数是不是素数。

5.3.2. 写一个函数判断一年是不是闰年。

5.3.3. 写一个函数,每调用一次这个函数,就会将 num 的值增加1。

六、函数的嵌套调用和链式访问

6.1 嵌套调用

6.2 链式访问

七、函数的声明和定义

6.1 函数声明

6.2 函数定义

6.3 多文件编程 

八、函数递归 (重点!!!)

8.1 什么是递归?

8.2 递归的两个必要条件

8.2.1 练习1 :接受一个整型值(无符号),按照顺序打印它的每一位。

8.2.2 练习2:编写函数不允许创建临时变量,求字符串的长度。

8.3 递归和迭代

8.3.1 练习3

8.3.4 练习4

8.4 总结

九、经典题目(笔试重点)

9.1 反转字符串(递归实现)

9.2 计算一个数的每位之和(递归实现)

9.3 利用递归实现求一个数n的k次方(递归实现)

9.4  二分查找(递归实现)

9.5  青蛙跳台阶问题

9.6 汉诺塔问题


一、函数是什么?

       数学中我们常见到函数的概念。但是你了解C语言中的函数吗? 维基百科中对函数的定义:子程序

      在计算机科学中,子程序(英语:Subroutine, procedure, function, routine, method, subprogram, callable unit),是一个大型程序中的某部分代码, 由一个或多个语句块组 成。它负责完成某项特定任务,而且相较于其他代码,具备相对的独立性。 一般会有输入参数并有返回值,提供对过程的封装和细节的隐藏。这些代码通常被集成为软件库。

二、C语言中函数的分类

    C语言的函数分为两大类:库函数和自定义函数;C语言自带的函数称为库函数库是编程中的一个基本概念,可以简单的认为它是一系列函数的集合,在磁盘上往往是一个文件夹。C语言自带的库称为标准库,其他公司或者个人开发的库称为第三方库。程序员自己编写的函数称为自定义函数

 

2.1 库函数

      为什么会有库函数?

  1. 在我们学习C语言编程的时候,总是在一个代码编写完成之后迫不及待的想知道结果,想把这个结果打印到我们的屏幕上看看。这个时候我们会频繁的使用一个功能:将信息按照一定的格式打印到屏幕上(printf)。
  2. 在编程的过程中我们会频繁的做一些字符串的拷贝工作(strcpy)。
  3. 在编程时我们总是会计算n的k次方这样的运算(pow)。

     像上面我们描述的基础功能,它们不是业务性的代码。我们在开发的过程中每个程序员都可能用的到, 为了支持可移植性和提高程序的效率,所以C语言的基础库中提供了一系列类似的库函数,方便程序员进行软件开发。

2.1.1 如何使用库函数

       那怎么学习库函数呢? 这里我们简单的看看:www.cplusplus.com

       简单的总结,C语言常用的库函数都有: IO函数、字符串操作函数、 字符操作函数 、内存操作函数、 时间/日期函数、 数学函数 、其他库函数

注意事项:

  1. 了解库函数或者自定义函数主要从3个方面:函数返回值类型、函数的作用、函数的参数,了解这三个便知道如何使用函数!
  2. 使用函数必须使用#include预处理命令包含对应的头文件,库函数使用一对尖括号,而自定义函数使用一对双引号!

        需要全部记住吗?No 需要学会查询工具的使用:

  1. MSDN(Microsoft Developer Network)
  2. www.cplusplus.com
  3. http://en.cppreference.com(英文版)
  4. http://zh.cppreference.com(中文版)

英文很重要。最起码得看懂文献。 

2.2 自定义函数

      如果库函数能干所有的事情,那还要程序员干什么? 所有更加重要的是自定义函数。 自定义函数和库函数一样,有函数名,返回值类型和函数参数。 但是不一样的是这些都是我们自己来设计。这给程序员一个很大的发挥空间。

  1. 返回值:既然函数可以处理数据,那就有必要将处理结果告诉我们,所以很多函数都有返回值,所谓返回值就是函数的执行结果,并且函数返回值有固定的基本数据类型,调用函数处必须要用相同类型的变量接收返回值!有的函数不需要返回值,或者返回值类型不确定,那么可以用void来表示,void是C语言中的一个关键字,表示“空类型”或者“无类型”,绝大部分情况下也就意味着没有return 语句。
  2. 函数名:函数名的命名做到见名知意,命名规则与标识符相同,且从内存角度理解:函数名是函数的入口地址!!!这与后面学的函数指针有重要关系!
  3. 函数参数:函数是一段可以重复使用的代码,用来独立完成某个功能,它可以接收用户传递的数据,也可以不接收,接收用户数据的函数在定义时要指明参数,不接收用户数据的函数不需要指明。根据这一点可以将函数分为有参函数和无参函数!

2.2.1  C语言无参函数的定义

       如果函数不接受用户传递的数据,那么定义的时候可以不带参数,语法如下所示:

返回值类型   函数名()   

{

                   函数体;

}

注意事项:

   1、返回值类型为C语言任意数据类型,如int 、float、char、甚至是指针类型char *、void *

   2、函数名于标识符命名规则相同,做到见名知意,函数名后面括号不能少;

   3、函数体是函数需要执行的代码,是函数主体部分,即使只有一条语句,函数体也要用花括号包围;

   4、如果有返回值,在函数体使用return 语句返回,且return出来的数据的类型要和返回值类型一致。

            return 是C语言中的一个关键字,只能用在函数中,用来返回处理结果!

//定义一个函数计算从1加到100
int sum()
{
    int i=0,sum=0;
    for(i=1;i<=100;i++)
    {
        sum+=i;
    }
    return sum;
}

int main()
{
   int res=sum();
   printf("1-100的和为:%d\n",res);
   return 0;
}

2.2.2  C语言有参函数的定义

     如果函数需要接收用户传递的数据,那么定义时就要带上参数,语法如下所示:

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

{

                      函数体;

}

注意事项:

  1. 函数可以只有一个参数,也可以有多个,多个参数之间由逗号分隔,参数本质上也是变量,因此定义时要指明类型和名称。与无参函数的定义相比,有参函数的定义仅仅是多了一个参数列表。
  2. 参数列表中给出的参数可以在函数体内部使用,使用方式同普通变量。
  3. 数据通过参数传递到函数的内部进行处理,处理完成后再通过返回值将处理结果告知函数外部。
//计算从 m 加到 n 的结果
#include <stdio.h>
int sum(int m, int n)
{
    int i, sum=0;
    for(i=m; i<=n; i++)
    {
        sum+=i;
    }
    return sum;
}

int main()
{
    int begin = 5, end = 86;
    int result = sum(begin, end);
    printf("%d加到%d的和为: %d\n", begin, end, result);
    return 0;
}

 调用函数时,参数有三种传递方式,但不管哪一种传递方式,必须是确定的值

  1. 可以直接传递整数,如:int result = sum(1, 100);  //1传递给m,100传递给n
  2. 也可以传递变量,如:int begin = 4;   int end = 86; int result = sum(begin, end);  //begin传递给m,end传递给n
  3. 也可以整数和变量一起传递,如int num = 33;int result = sum(num, 80);  //num传递给m,80传递给n

2.2.3  函数不能嵌套定义

      强调一点,C语言不允许函数嵌套定义;也就是说,不能在一个函数中定义另外一个函数,必须在所有函数之外定义另外一个函数。main() 也是一个函数定义,也不能在 main() 函数内部定义新函数。

       注意:main 是函数定义,不是函数调用。当可执行文件加载到内存后,系统从 main 函数开始执行,也就是说,系统会自动的调用我们定义的 main 函数。

2.3  函数设计注意事项

        函数主要实现功能封装,不允许出现printf输出结果信息,但是可以有提示信息,也不允许出现scanf输入信息,输入信息可以通过参数传递的方式传递到被调函数的内部,这是为了保证函数的功能的单一性,而在主函数中方便直接调用,主函数main()主要对函数进行功能测试。

2.4 练习

2.4.1写一个函数可以找出两个整数中的最大值

#include <stdio.h>
//get_max函数的设计
int get_max(int x, int y)
{
 return (x>y)?(x):(y);
}

int main()
{
 int num1 = 10;
 int num2 = 20;
 int max = get_max(num1, num2);
 printf("max = %d\n", max);
 return 0;
}

底层内存开辟如下图所示

 

2.4.2 写一个函数求一组数中的最大数

#include <stdio.h>
int get_max(int* arr, int len)
{
	int max = arr[0];         //假定第一个数是最大数,逐个进行比较
	for (int i = 0; i < len; i++)
	{
		if (max < arr[i])
		{
			max = arr[i];
		}
	}
	return max;
}
int main()
{
	int arr[] = {2,5,42,12,51,46,23,54,12,89,65,25,45,142,252,321,521};
	int len = sizeof(arr) / sizeof(arr[0]);
	int max = get_max(arr, len);
	printf("这组数的最大数为:%d\n", max);
	return 0;
}

2.4.3 利用函数实现从键盘输入一个数,输出它是几位数

#include <stdio.h>
int getbit(int num)
{
	int bit = 0;
	while (num != 0)
    {
		num /= 10;
		bit++;
	}
	return bit;
}

int main()
{
	int num=0;
	printf("请输入一个数据:\n");
	scanf("%d", &num);
	int bit = getbit(num);
	printf("%d是%d位数", num, bit);
	return 0;
}

三、函数参数(重点)

       如果把函数比喻成一台机器,那么参数就是原材料,返回值就是最终产品从一定程度上讲,函数的作用就是根据不同的参数产生不同的返回值。这一节我们先来讲解C语言函数的参数,下一节再讲解C语言函数的返回值。

  • 25
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

未来可期,静待花开~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值