在c语言中函数的作用是非常大的,他可以减少我们程序的复杂性,使程序具有逻辑,可以避免重复性代码,可以让程序模块化。
下面从几个方面来剖析函数的基础
1.函数的定义
首先我们确定这个函数该如何写,该如何实现,一个函数的结构应该是这样
其中,函数名的命名,要遵循一定的规则,可以由字母、数字、下划线组成,但不可以用数字开头。也不能与c语言的关键字和头文件的库函数重名。命名的时候可以使用驼峰法命名。
注:不写函数类型,系统会默认认定为,int类型。假如不需要函数返回值的话,可使用void缺省类型。
然而,函数的参数可以根据自己编写函数的功能需求,可以没有,可以有很多个。没有的话可以填写void缺省。
我们把一个函数可以比作后厨,他的参数相当于原材料,则返回值则是做出来的一道佳肴。具体做什么菜,则是函数体自己功能的实现了。
如下方提供一个简单的加法例子
可见函数的类型,就是函数运行结果的类型,也就是返回值的类型。如果函数类型和返回值的类型不一样,则最终返回的还是函数定义的类型。如果你的函数定义为int,但是返回值是5.21,则最终返回的是5这个整型数。
变量的作用域
在c语言中,变量会有一定的作用域。
局部变量
如在函数体内部定义的变量一般他的作用域就在这个函数体内部。与其其实就是,局部变量的作用域就是在离定义该变量最近的大括号内部。出了大括号,该变量将不能调用。
全局变量
当我们在函数体外面定义变量,则他的作用域可以作用在整个文件程序中都可以使用。但全局变量也有缺陷,因为在程序非常庞大的时候,可能会遇到重复名的可能,往往会有风险。使整个程序会出现bug甚至崩溃。
而一个文件程序中,全局变量和局部变量重名时,在函数体内部,用的是谁?答案是局部变量,可谓强龙难压地头蛇。在函数执行的过程中,小作用域会将大作用域的变量隐藏了,则大作用域的变量不能访问小作用域里。
变量的生存周期
在一段程序中,在执行到定义这个代码这一行是,会为这个变量开辟一个内存空间,而在执行到这个变量的作用域结束的时候,会回收这个变量。所以不在一个函数内部定义的变量,不能互相调用,而全局变量可以调用,因为他作用于整个程序。
变量的存储类型
存储类型分为四种
1 auto 自动型存储、局部存储(默认类型) ->将变量存放在栈区
执行到变量定义的时候,会为变量开辟空间,超出作用域时候回收空间
2 register 寄存器存储 -> 存放到CPU内部的寄存器中 例如(register int num = 0;)
寄存器不在内存区域(这个区域离CPU近,访问速度快)如果寄存器存满了,还是会存到auto,一般用于硬件开发。
3 externa 外部存储 -> 在另一个文件已经定义了
声明一个外部变量(原来本就存在,只是声明)
4 static 静态存储 -> 将变量存储在静态区
则在数据区,即使不用初始化,他的初值在任何情况下都是0
看下方一段程序
#include <stdio.h>
int main(int argc, const char *argv[])
{
int i = 0;
int c = 0;
for(i = 0; i < 3; i++)
{
int a = 0;
static int b;
a++;
b++;
c++;
printf("a = %d, b = %d, c = %d\n",a,b,c);
}
return 0;
}
运行结果
c很好理解
a 的话每次循环都是开辟与释放。每次进入循环都是0,然后a++为1
b是一个静态变量,他是在程序执行一开始,就会开辟定义,程序结束的时候才会离开作用域
2.函数的调用
调用函数就像我们用printf()这个函数一样,下面是调用函数的类型
函数名(实参1,实参2,......);
如果有返回值的函数,可以用有一个变量去接他
形参与实参区别
假如你去街上买衣服,形参就好比穿着衣服的模特,实参就相当于你。
实参会把值给到形参,然后在函数内部对形参进行一系列的操作。
函数在调用时,实参与形参要一一对应,实参多少,形参就得对少。
程序执行到函数的调用那一行,会跳转到函数在向下执行,函数执行完后,会回到原函数中继续向下执行,则函数也可以反复调用嵌套,调用时候跳转,执行完回到原函数。
3.函数的声明
如果被调用的函数在主函数上面,可以不去声明,否则的话需要声明
4.函数的传参
1.实参将值拷贝给形参,但是实参和形参不是一个东西
2.实参可以将自己的地址传递给形参,用于函数体内部想改变函数体外部的值