一个C程序可以由一个主函数以及若干个其他的函数组成。
C语言中程序的函数有两种:库函数和自定义函数。
库函数:C语言编译系统提供的一些常用的函数,放在指定的库文件中,用户 使用时需要引用即可。
自定义函数:用户自己编写的函数,使得函数完成用户指定的任务。
函数定义和函数调用:
函数定义也就是别写函数,使它完成特定的任务。
函数必须先定义才能再使用,没有定义过的函数不能使用。
类型标识符用来定义函数类型,也就是指定函数的返回值类型。如果定义函数时省略类型标识符,那么系统会默认这个函数的返回值为int型。
程序中除了main函数外其他函数可以任意取名,但是也必须是符合标识符命名规则的。
形参也称为形参变量,由用户取名。函数可以有形参,也可以没有形参。
需要从函数外部传入到函数内的参数为形参。
Return语句
Return函数一般放在函数体内,当执行return语句后,就结束当前函数的执行,返回到主调函数的调用处。
Return的一般形式:
- return;
- return 表达式; 或者return (表达式);
return语句的作用是结束函数的执行,返回到主调函数的调用处。如果是带有表达式的return语句,则同时将表达式的值带回到主调函数的调用处。
定义函数时,如果函数为非空类型,也就是说该函数具有返回值,那么该函数体中必须要有return 表达式 语句。
在程序中使用已经定义的函数,称为函数调用。
有参函数的调用:
函数名(实参,实参,…)
无参函数的调用:
函数名()
其中,实参可以是常量、变量、表达式。有参函数的调用中,实参和形参的个数必须相等,类型应该要一致。
函数调用方式:1,表达式方式;2,语句方式;3,参数方式,这种方式中函数必须要有返回值,这个返回值作为另一个函数调用的实参。
函数声明:若要调用某个已经定义的函数,一般应在主调函数中对被调函数进行声明。作用是告知编译系统,有关被调函数的属性,便于在进行函数调用时,检查调用是否正确。
类型标识符 函数名(类型 形参名;类型 形参名,…);
或者:
类型标识符 函数名(类型,类型,…)
在函数未被调用时,函数的形参是不分配存储单元的,也没有实际值。只有当函数被调用时,系统才为形参分配存储单元,并完成实参与形参之间的数据传递。
函数调用的执行过程:
- 创建形参变量,为每个形参变量建立相应的存储空间。
- 值传递,即将实参的值复制到对应的形参变量中。
- 执行函数体,即执行函数体中的语句。
- 返回(返回函数值、返回到调用处、释放形参所占的内存空间)
函数用参数传递数据的方式有2中:传值方式和传址方式。
函数的嵌套调用和递归调用
函数可以嵌套调用但是不能嵌套定义。也就是说,C语言的各个函数应当是分别独立定义的函数,互不从属。也就是说在函数定义时,该函数体内不能再定义另外的函数,但是可以调用已经定义的函数。
当一个函数直接或者间接的调用他本身时,就被称为函数的递归调用。前者称为直接递归,后者称为间接递归。
局部变量和全局变量:
在函数内部定义的变量是局部变量,也称之为内部变量,其作用域为本函数,即他们只在本函数的范围内有效,也就是说,只有在本函数内才能使用他们,在本函数意外是不能使用这些变量的。
- 形参也是属于局部变量;
- 不同函数中可以使用相同名字的变量,他们代表不同的对象,互不干扰。
- 在一个函数内部,可以在复合语句中定义变量,这些变量只在本复合语句中有效。
C程序的编译单位是源程序文件,一个源文件可以包含多个函数。在函数外部定义的变量就是全局变量,作用域是从定义变量的位置到本源文件结束。
- 若局部变量定义时未初始化,其值就不确定,而全局变量定义时未初始化,系统自动为其赋初值0;
- 如果在同一个源文件中,全局变量与局部变量同盟,则在局部变量的作用域内,同名的全局变量暂时被屏蔽,不起作用。
根据函数能否被其他文件调用,可以将函数分为内部函数和外部函数。
1,内部函数:如果一个函数只能被本文件中的其他函数所调用,则称它为内部函数,在定义内部函数时,在函数名和函数类型前面加static:
Static 类型标识符 函数名(形参表)
内部函数又称为静态函数。使用内部函数,可以使得函数只局限在所在文件,如果在不同的文件中有同名的内部函数,也互不干扰。
2,外部函数
在定义函数时,如果在函数前面加一个extern,表示该函数可以被其他文件调用,是外部文件。C语言规定,如果在定义函数时省略extern,则默认该函数为外部函数。
变量的存储类别:
从变量的生命周期来看,变量的存储方式可以分为静态存储方式和动态存储方式。
所谓静态存储方式就是指在程序运行期间分配固定的存储空间方式;
而动态存储方式是指在程序运行期间根据需要进行动态分配存储空间的方式。
在计算机内部供用户使用的空间可以分为程序区、静态存储区和动态存储区3个部分。
程序代码被放在程序区。数据分别被放在静态存储区和动态存储区。
静态存储区中存放的是全局变量和静态变量,在程序开始执行时就给全局变量和静态变量分配空间。在执行过程中他们占据固定的存储单元,程序执行完毕之后这些存储单元就被释放。
在C语言中每个变量和函数都有2个属性:数据类型和数据的存储类别。存储类别指的是数据的存储方式,分为2大类:静态存储方式和动态存储方式。具体包括4种存储类别:自动(auto)、静态(static)、寄存器(register)和外部(extern)。
变量定义的一般形式为:
存储类别标识符 类型标识符 变量名列表;
Auto(自动)变量:定义自动变量时,前面的auto可加可不加,一般在函数内部或者复合语句中使用。系统每次进入函数或者复合语句时,都会为定义的自动变量在动态存储区分配存储空间。在函数执行结束或者复合语句结束,控制返回时,存储空间得以释放。
Static(静态)变量:静态变量分为静态全部变量和静态局部变量。
静态局部变量
定义静态局部变量时,前面要加static,特点是在程序执行前变量的存储空间被分配在静态存储区,并赋初值一次,如果没有,系统自动赋值0.当包含静态变量的函数调用结束后,静态变量的存储空间不释放,所以他的值一九存在,当再次调用该函数时,则静态变量上次调用结束的值就作为本次的初值使用。
静态全局变量:
静态全局变量只能被所定义的本文件中的所有函数引用,而不能被其他文件中的函数引用。
如果已知其他的文件不引用本文件中的外部变量,则可以为本文件中的外部变量都加上static,使之成为静态外部变量,以免被其他文件误用。
Register(寄存器)变量
寄存器变量和自动变量的不同之处在于寄存器变量被存放在寄存器中,因此比自动变量的存取速度快很多。通常将频繁使用的变量放在寄存器中,以提高程序的执行速度。比如循环体内涉及的变量。
- 计算机中寄存器的数量是有限的,因此寄存器变量不能定义太多。
- 只有局部自动变量和形参可以作为寄存器变量