一、函数定义:
1)从函数定义的角度看,函数可分为库函数和用户定义函数两种。
2)语言的函数兼有其它语言中的函数和过程两种功能,从这个角度看,又可把函数分为有返回值函数和无返回值函数两种。(有返回值函数,无返回值函数)
3)从主调函数和被调函数之间数据传送的角度看又可分为无参函数和有参函数两种。(主调函数:main函数,被调函数:用户定义函数这类)
二、无参函数定义:
函数格式:
函数名是由用户定义的标识符,函数名后有一个空括号,其中无参数,但括号不可少。无参函数一般都用void,无返回值。类型标识符 函数名()
{声明部分语句}
例:
void Hello()
{
printf ("Hello,world \n");
}
三、有参函数定义:
有参函数定义的一般形式如下:类型标识符 函数名(形式参数表列)
{声明部分语句}
有参函数比无参函数多了一个内容,即形式参数表列。在形参表中给出的参数称为形式参数,它们可以是各种类型的变量,各参数之间用逗号间隔。
例:
int max(int a, int b)
{
if (a>b) return a;
else return b;
}
函数说明与函数定义中的函数头部分相同,但是末尾要加分号。
#include
int max(int a,int b)
{
if(a>b)return a;
else return b;
}
int main(void)
{
int max(int a,int b);
int x,y,z;
printf("input two numbers:\n");
scanf("%d%d",&x,&y);
z=max(x,y);
printf("maxmum=%d",z);
return 0;
}
四、形式参数和实际参数:
1)形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。
2)实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须具有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使实参获得确定值。
3)实参和形参在数量上,类型上,顺序上应严格一致,否则会发生类型不匹配”的错误。
函数调用中发生的数据传送是单向的。即只能把实参的值传送给形参,而不能把形参的值反向地传送给实参。 因此在函数调用过程中,形参的值发生改变,而实参中的值不会变化。
五、函数的返回值:
1)函数的值只能通过return语句返回主调函数。return语句的一般形式为:return 表达式;或者为:return (表达式);
2)函数值的类型和函数定义中函数的类型应保持一致。如果两者不一致,则以函数类型为准,自动进行类型转换。
3)如函数值为整型,在函数定义时可以省去类型说明。
4)不返回函数值的函数,可以明确定义为“空类型”,类型说明符为“void”。
六、数组做为函数参数:
数组用作函数参数有两种形式,一种是把数组元素(下标变量)作为实参使用;另一种是把数组名作为函数的形参和实参使用。
例:
#include
void nzp(int v){
if(v>0)
printf("%d ",v);
else
printf("%d ",0);
}
int main(void){
int a[5],i;
printf("input 5 numbers\n");
for(i=0;i<5;i++){
scanf("%d",&a[i]);
nzp(a[i]);
}
return 0;
}
用数组名作函数参数时,则要求形参和相对应的实参都必须是类型相同的数组,都必须有明确的数组说明。当形参和实参二者不一致时,即会发生错误。
七、C语言局部变量和全局变量:
C语言中的变量,按作用域范围可分为两种,即局部变量和全局变量。
局部变量:
局部变量也称为内部变量。局部变量是在函数内作定义说明的。其作用域仅限于函数内, 离开该函数后再使用这种变量是非法的。例:
int f1(int a)
{
int b,c;
}
int f2(int x)
{
int y,z;
}
main()
{
int m,n;
}
全局变量:
全局变量也称为外部变量,它是在函数外部定义的变量。它不属于哪一个函数,它属于一个源程序文件。其作用域是整个源程序。
在函数中使用全局变量,一般应作全局变量说明。只有在函数内经过说明的全局变量才能使用。全局变量的说明符为extern。但在一个函数之前定义的全局变量,在该函数内使用可不再加以说明。
如果同一个源文件中,外部变量与局部变量同名,则在局部变量的作用范围内,外部变量被“屏蔽”,即它不起作用。
八、动态存储与静态存储:
用户存储空间可以分为三个部分:
1、程序区;
2、静态存储区;(全局变量
)
3、动态存储区;(函数形式参数;自动变量(未加static声明的局部变量);函数调用实的现场保护和返回地址。)
全局变量全部存放在静态存储区,在程序开始执行时给全局变量分配存储区,程序行完毕就释放。
在C语言中,每个变量和函数有两个属性:数据类型和数据的存储类别。
函数中的局部变量,如不专门声明为static存储类别,都是动态地分配存储空间的,数据存储在动态存储区中。
auto变量:
函数中的局部变量,如不专门声明为static存储类别,都是动态地分配存储空间的,数据存储在动态存储区中。
用static声明局部变量:
有时希望函数中的局部变量的值在函数调用结束后不消失而保留原值,这时就应该指定局部变量为“静态局部变量”,用关键字static进行声明。
对静态局部变量的说明:
1、静态局部变量属于静态存储类别,在静态存储区内分配存储单元。在程序整个运行期间都不释放。而自动变量(即动态局部变量)属于动态存储类别,占动态存储空间,函数调用结束后即释放。
2、静态局部变量在编译时赋初值,即只赋初值一次;而对自动变量赋初值是在函数调用时进行,每调用一次函数重新给一次初值,相当于执行一次赋值语句。
3、如果在定义局部变量时不赋初值的话,则对静态局部变量来说,编译时自动赋初值0(对数值型变量)或空字符(对字符变量)。而对自动变量来说,如果不赋初值则它的值是一个不确定的值。
#include
int fac(int n){
static int f=1;
f=f*n;
return f;
}
int main(void){
int i;
for(i=1;i<=5;i++)
printf("%d!=%d\n",i,fac(i));
return 0;
}
register变量:
为了提高效率,C语言允许将局部变量得值放在CPU中的寄存器中,这种变量叫“寄存器变量”,用关键字register作声明。
对寄存器变量的几点说明:
1、只有局部自动变量和形式参数可以作为寄存器变量;
2、一个计算机系统中的寄存器数目有限,不能定义任意多个寄存器变量;
3、局部静态变量不能定义为寄存器变量。
#include
int fac(int n){
register int i,f=1;
for(i=1;i<=n;i++)
f=f*i;
return f;
}
int main(void){
int i;
for(i=0;i<=5;i++)
printf("%d!=%d\n",i,fac(i));
return 0;
}
九、extern声明外部变量:
外部变量(即全局变量)是在函数的外部定义的,它的作用域为从变量定义处开始,到本程序文件的末尾。如果外部变量不在文件的开头定义,其有效的作用范围只限于定义处到文件终了。如果在定义点之前的函数想引用该外部变量,则应该在引用之前用关键字extern对该变量作“外部变量声明”。
例:
#include
int max(int x,int y)
{
int z;
z=x>y?x:y;
return z;
}
int main(void)
{
extern A,B;
printf("%d\n",max(A,B));
return 0;
}
int A=13, B=-8;