目录
1.函数是什么?
维基百科中对函数的定义:子程序
- 在计算机科学中,子程序(Subroutine,procedure,function,routine,method,subprogram,callable unit),是一个大型程序中的某部分代码,由一个或多个语句块组成。它负责完成某项特定任务,而且相较于其他代码,具备相对的独立性。
- 一般会有输入参数并有返回值,提供对过程的封装和隐藏。这些代码通常被集成为软件库。
2.C语言中的函数分类
2.1库函数
早期的C语言没有库函数,以printf函数为例,假如三个人都要打印某个东西,那他们都需要自己写一个函数来实现打印功能,这样就造成了代码冗余,开发效率低,且没有统一的标准,为了支持可移植性和提高程序的效率,所以C语言的基础库提供了一系列类似的库函数,方便程序员进行软件开发。
查询函数如何使用:cplusplus.com - The C++ Resources Network
C语言中常用的库函数有
- IO函数
- 字符串操作函数
- 字符操作函数
- 内存操作函数
- 时间/日期操作函数
- 数学函数
- 其他库函数
以下通过strcpy函数和memset函数介绍如何通过cplusplus.com - The C++ Resources Network来查询函数的基本使用。
strcpy函数:把一个含有‘\0’结束符的字符串的内容复制到另一个地址空间中,返回值的类型为char*。strcpy(arr1,arr2)的意思是把arr2中的内容复制到arr1中。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
int main()
{
char arr[] = "abcdefgh";
char arr1[] = { 0 };
strcpy(arr1, arr);
printf("%s\n", arr1);//输出为:abcdefgh
printf("%s\n", arr);//输出为:abcdefgh
return 0;
}
memset函数:初始化函数,作用是把一个块内存块中的内容全部设置为指定的值,通常为新新申请的内存做初始化工作。meset(arr,‘a’,5)的意思是把arr数组中的前5个字符改为a。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
int main()
{
char arr[] = "abcdefgh";
memset(arr, 'm', 4);
printf("%s\n", arr);//输出为:mmmmefgh
return 0;
}
2.2自定义函数
库函数并不能解决所有问题,因此,自定义函数更加重要。自定义函数和库函数一样,有函数名,返回值类型和函数参数。
例:写一个函数找出两个整数中的较大值
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int get_max(int x, int y)
{
if (x > y)
{
return x;
}
else
{
return y;
}
}
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b);
int ret = get_max(a, b);
printf("%d\n", ret);
return 0;
}
3.函数的参数
介绍函数的参数之前,我们先写一个函数交换两个整形变量的内容
按照常规写法,我们发现程序并没有达到交换a和b的值得目的。我们引进实参和形参的概念,x,y是形式参数,a,b是实际参数,当实参传给形参的的时候,形参是实参的一份临时拷贝,对形参的的修改不影响实参
3.1实际参数(实参)
真实传给函数的参数叫实参
实参可以是:常量,变量,表达式,函数等。
无论实参是哪种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参
3.2形式参数(形参)
形式参数是指函数名后括号中的变量,因为形式参数只有在函数被调用的过程中才会实例化(分配内存单元),所以叫做形式参数。形式参数当函数调用完后就自动销毁,因此形式参数只在函数中有效。
所以如何通过函数交换两个整形变量的内容呢?
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
void swap(int* x, int* y)
{
int tmp = *x;
*x = *y;
*y = tmp;
}
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b);//4 8
swap(&a, &b);
printf("a=%d b=%d\n", a,b);//a=8 b=4
return 0;
}
通过以上代码可以实现交换。我们看到,swap函数的参数是指针变量x,指针变量y,在主函数里,函数调用时,传到函数里的参数是&a,&b,即a和b的地址。所以在swap函数中,访问的就是a,b的地址,通过对x,y解引用操作,得到a,b的值再进行交换。
4.函数的调用
4.1传值调用
函数的形参和实参分别占有不同的内存块,对形参的改变不会影响实参
例:写一个函数找出两个整数中的较大值
4.2地址调用
- 传址调用是把函数外部创建变量的内存地址传递给函数的参数的一种调用函数的方式
- 这种传参方式可以让函数和函数外边的变量建立起真正的联系,也就是函数内部可以直接操作函数外的变量
5.函数的嵌套调用和链式访问
- 函数不能嵌套定义,但是可以嵌套调用
- 嵌套定义:把一个函数定义在另一个函数的内部
链式访问:把一个函数的返回值作为另一个函数的参数
例一:
例二:
注:printf函数的返回值是打印在屏幕上字符的个数