函数分类
函数大致分为自定义函数和库函数。
库函数是比较常用的,被规定标准的、可以直接调用的函数。不同的集成开发环境通过不同的方式实现库函数相同的功能和符号。
这使得程序员在不同的编译器之间转换写代码并不困难。
常见的库函数有printf()等,使用printf函数需要include <stdio.h>的头文件。
库函数的学习可以通过以下两个网址:
C/C++官方的链接:http://zh.cppreference.com/w/c/header
cplusplus.com: https://legacy.cplusplus.com/reference/clibrary
自定义函数
定义函数的方式。
(返回类型)函数名(参数)
{
}
函数的定义是一种特殊的声明,所以定义函数以后,在下面就可以直接调用了。
调用函数只需要写函数名(参数)就好。
定义函数的优点有很多:1.可以使整个程序的主函数部分代码不那么长,逻辑清晰。
2.可以分离程序,比如把函数的定义放在另一个源文件作为全局变量。那么只需要在本文件声明一下就可以。分离程序方便隐藏程序。
定义函数的目的,主要是需要实现一个功能。如果直接写在主函数的程序里写的内容过长,括号太多,逻辑不那么清晰。如果把这一段作为一个函数,内容移到主函数外进行封装就会简单很多,也容易查错。一个定义函数,代表一个功能的实现。需要使用的时候在主函数中直接调用就好。
//假设我要输入一个包含4个元素的一维数组并打印出来
int main()
{
int i=0;
int arr[4]={0};
test( arr[4]);/*我想要test()这个函数帮我实现输入并打印的功能。
于是先加上函数名和参数*/
return 0;
}
void test (int arr[]) /*arr[]是形参,一般来说改变形参不会导致实参的改变,
但是数组是个例外。改变数组的形参,实参也会改变。参数这里,int 表示数组是个
整型数组。void表示不需要返回值。test是函数名。*/
{
int i=0;
for(i=0;i<4;i++)
{
scanf("%d",&arr[i]);
printf("%d ",arr[i]); //输入一个数就打印一个数
}
}
int main()
{
int i=0;
int arr[4]={0};
test(arr); /*这个参数是数组,调用时的参数是实参。传到封装的函数那。
注意,数组传参格式要正确。参数只需要写数组名就好,不需要加[4]。*/
return 0;
}
数组传参的格式要正确,否则导致程序不能按照预想的运行。实参中的数组只需要数组名就好,不需要加上[ ],形参中接收的数组需要加类型,比如这个例子是整型就是int, 再加上数组名和[ ]。
这里还是要谈一下库函数。如果没有库函数,我们要实现打印的功能就要自己去定义函数去实现打印这个功能。每次一个文件只要写需要打印功能的程序,都需要在文件中自定义一个具有打印功能的函数。这导致程序员做大量重复的工作。库函数的出现,使程序员免于自己写代码去实现常用功能的函数,直接调用标准库里的函数,加上头文件就好。这给程序员带来了巨大的便捷。
另外一种是需要返回值的自定义函数,也写个例子。
int add (int x, int y) /*第一个int 表示返回类型。我需要返回的数是个整型
而x是整型,y也是整型,所以接收到参数时需要加int
同时,也相当于对x和y的声明,下面不用再次声明了。*/
{
return x+y; //return后面的是整个函数返回的值,它将会替代下面的add(x,y)
}
int main( )
{
int x=0,y=0;
scanf("%d %d",&x,&y);
int a=add(x,y); //我需要用add函数计算求和,x和y是我传过去的参数
printf("%d",a);
return 0;
}
如果不需要返回值,那么把int 改成void就好,如果不需要传参,那么()的形参也可以写个void表示不用接收参数了。而实参部分,()就不用写参数了。由于不需要返回值,所以在函数定义时不需要写return。
如果需要返回特定值,而函数定义中又包含了if函数,那么需要考虑if的每个分支都需要有返回值。
一旦某个return被执行,函数提前返回,函数定义中该return后面的代码都是未执行的。