C语言函数详解
定义函数
返回类型 函数名称( 参数表 )
{
函数体
}
函数声明
声明
函数声明(函数原型)的目的是告诉编译器这个函数长什么样,函数的实际主体可以单独定义。
函数声明包括以下几个部分:
返回类型 函数名称( 参数表 );
//形式一
int sum(int a, int b);
//形式二
int sum(int, int);
不声明
C的编译器自上而下顺序分析你的代码,如果你把函数定义在main函数之上,那么可以不声明。
调用函数
函数名称( 参数表 )
- ()起到了表示函数调用的重要作用
- 即使没有参数也需要()
- 如果有参数,则需要给出正确的数量和顺序,这些值会被按照顺序依次用来初始化函数中的参数
从函数中返回值
- return停止函数的执行,并送回
一个值,其返回类型为定义函数时的返回类型 - return 表达式;
函数参数
如果函数要使用参数,则必须声明接受参数值的变量。这些变量称为函数的形式参数。
形式参数就像函数内的其他局部变量,在进入函数时被创建,退出函数时被销毁。
当调用函数时,有两种向函数传递参数的方式:
-
传值调用:该方法把参数的实际值复制给函数的形式参数。在这种情况下,修改函数内的形式参数不会影响实际参数。
-
引用调用:通过指针传递方式,形参为指向实参地址的指针,当对形参的指向操作时,就相当于对实参本身进行的操作。
默认情况下,C 使用传值调用来传递参数。一般来说,这意味着函数内的代码不能改变用于调用函数的实际参数。
详细解释:
传值调用:
此时的结果依旧为初始化时的结果,没有变化。
如果利用返回值会如何?
显然改变了b的值
解释:
- 每个函数有自己的变量空间,参数也位于这个独立的空间中,和其他函数没有关系。比如main()中a与swap()中的a没有直接关系,仅仅是因为main()调用swap函数将而自己a的数值传入了swap(),而swap函数中a的改变不会直接影响main函数的a。可以简单理解为参数只在自己所在函数的{}内有效。
- 对于函数参数表中的参数,叫做“形式参数”,调用函数时给的值,叫做“实际参数”
- 拓展:同一个函数的变量空间嵌套另一个变量空间是,局部变量只在局部有效,而全局变量在整个变量空间都有效。这和java是不同的
注意:
- 调用函数时给的值与参数的类型不匹配是C语言传统上最大的漏洞,编译器自动把类型转换好,但答案不一定准确(如下图)
- 后续的语言,C++/Java在这方面很严格