![2fd682838d12d24000de87ad9a3017f0.png](https://i-blog.csdnimg.cn/blog_migrate/79cee6391d1d459867e11f9e5cc1b85f.png)
文 | Edward
![6fb0a404a7ef639558533210f781c3f7.png](https://i-blog.csdnimg.cn/blog_migrate/fce253532b85dd678562965cc788a939.png)
4.3 函数的参数和返回值
函数定义和声明好之后,整个函数也就定义好了,上一小节我们说到,声明函数原型的目的,就是将函数的信息传递给编译器“登记”下来,以便后续调用时进行参数的检查和返回值的传递。在C语言中,描述一个函数的信息主要由三个维度的信息:
(1) 函数名。函数名是我们在定义和声明完成函数之后,最为直接的信息,在C语言中,不允许函数名重复,这个是ISO C语言完全不允许的。但是在GNUC语言中,GCC编译器允许使用“__weak“属性来声明和定义一个”弱函数“,这个弱函数的意思类似于C#和JAVA等高级语言中的抽象函数。除此以外,C语言不支持类似于高级语言那样的重载函数。但是如果放眼一个C语言工程,里面有很多的.c文件,在两个.c文件中定义函数名,返回值,参数类型,参数数量一样的函数是允许的,只不过函数需要用关键词”static“来修饰,这个我们后面再详细讨论。
(2) 返回值(函数类型)。在C语言中,只允许一个函数最多只有一个返回值,函数的返回值可以是我们之前所学习的基本数据类型。而这里有读者要问了,如果我有多个返回值需要函数返回时该怎么办?这里我们可以返回指针类型,关于指针类型,后面有一大篇的内容,这里先不讨论。当然,如果函数不返回任何值时,可以使用关键词“void“替代其返回类型,那此时这个函数就是无返回值函数。
(3) 参数类型和参数数量。C语言函数后面括号里面跟随的变量又被称为“传递参数“,显然这些参数是在函数被调用时,从调用端传进来的。这些参数可以是我们之前学过的一些基本数据类型,也可以是后面将会学习的数组,指针等。如果定义的函数不需要传递参数时,可以用关键词”void“表示,如”int main(void)“。当然main函数的内容远远不止我们目前使用的那么简单,后面也会详细讨论。有一点需要注意,C语言的传递参数只能从调用处传入函数里面,反方向传递是不被允许的。我们可以看图4-3-1的程序代码。图4-3-1中,定义了一个函数,这个函数的本意是将传入的两个变量进行交换。但是当我们完成这个函数之后,将结果打印出来,发现和我们想象的完全不一样,这就是C 语言函数传递参数的一个很重要特点,单向性,即只能从调用处传入函数,但是函数里面的变量是无法传到调用处的。后面会讲到如何利用指针参数变量来使得函数修改指针的指向值,这种方式是可以改变传递参数的值的,但指针原理和这里不一样,因此先不做讨论。
![2ce006f529c3065aef168941ca79184e.png](https://i-blog.csdnimg.cn/blog_migrate/17d3f7b19d6cb2757ad706fcdccc8fed.png)
图4-3-1 传递参数交换
以上就是C语言中函数定义的全部需要注意的内容,其实C语言中的函数更多的趋向于“黑盒“设计,这一点无论是硬件设计,软件设计的基本思想都类似,即将每个细小的模块分割出来,将其独立去实现,然后统一好各自的接口。在做大系统的时候,将这些小模块一个个根据其接口统一拼接起来。用这样方法方便系统调试,同时也提高了开发效率和开发协作。而我们在编写函数时,也要注意这个原则,即将特定的功能模块,用函数封装好,留出接口,并且要确保各个函数的独立性,总结一下程序各个模块间的关系”高内聚,低耦合“。
![672c61c65427db8ea7e4c3d0461483c7.gif](https://i-blog.csdnimg.cn/blog_migrate/d17f58deada3ce239076d46dfc2f84ac.gif)
![445d5fa863969484b5781a4353463a4d.png](https://i-blog.csdnimg.cn/blog_migrate/844c2a581d7abfbdcec90061cf2247cd.png)