资源描述
函数
在C语言中一个较大的程序往往都是由多个模块构成,好处是:
一可以对每个模块单独编制和调试,简化程序。
二可由多人同时开发,加快软件的开发速度。
三可使程序模块化,一个程序模块可供不同程序使用。
四便于扩充软件新功能,即有良好的可维护性和可用性。
C语言往往由多个函数构成,一个或多个函数对应一个功能模块。
一:C程序的模块结构
1一个C程序由一个具有固定名称的main()函数和若干个以标识符命名的其他函数组成。
2C函数是一种独立性很强的程序模块,所有函数处于平等地位,不存在从属关系。
3一个C程序中的函数可以集中存放在一个程序文件中,也可以分散在几个程序文件中。
4函数间的逻辑关系是通过函数调用实现的。总是从main()开始的,当一个函数调用另一个函数时,前一个函数称调用函数,后者为被调用函数。
二:函数的定义和调用:
函数分:标准库函数:是系统定义的,分别存放在不同文件中,用#include直接调用。
用户自定义函数:用户为解决自己的问题建立的。
一) 定义:定义的格式也有两种:K&R格式和ANSI格式。
前者是早期编译系统使用的格式,后者是现代编译系统使用的格式。
ANSI格式:[存储类型] [数据类型] 函数名(形参表)
形参类型说明;-à如果是K&R格式
{
函数体;
}
如同样一个函数,两种定义格式如下:
product(int a,int b) product (a,b)
{int c; int a,int b;
c=a*b; {int c;
return(c) ; c=a*b;
} return(c );
}
从上可看出:ANSI格式在形参表中即说明其名称又说明其类型,K&R格式只在形参中说明名称,而类型说明放在函数名和函数体左花括号之间。
所以,目前用ANSI格式较多。
定义时注意事项:
1) 函数名:
它是编译系统识别函数的依据,在名称和()之间不能有空格,函数名也是常量,代表该段程序代码在内存中的首地址,也叫函数入口地址。
2) 函数的形参:
形参用来建立函数之间的数据联系,放在函数名后边的括号里。
当函数被调用时,形参接受来自函数中的实际参数。
形参可以是变量、数组、指针、也可以是函数等。
如果函数交换需要形参交换,则函数可以是无参函数。如:
float sub(void)或float sub()
3) 函数的返回值:
函数运行结束时,将运行的结果返回到调用函数,称为函数的返回值。
一般用return返回,也可不用。因为C语言规定,当被调用函数结束时,控制权将转回调用函数。
4)函数的数据类型:
指该函数返回值的类型,可以是char、int 、float、double、指针等。
没有定义的默认是int。无值类型函数名前不加任何关键字,或加void
void print(float x,float y)
void input(void)
5)函数的存储类型:
当一个程序文件中的函数允许被另一个程序文件中的函数调用时,可以将它定义成extern型,否则,就要定义成static型。默认为extern型。
6)函数体:
是函数实现预定处理功能的语句集合,其形式与main()函数完全相同。
二) 函数的调用:
在完整的C程序中,各函数之间的逻辑关系是通过函数调用实现的。
调用方式:
即可以用函数名,也可以用指向函数的指针来调用函数。
一般形式:函数名([实际参数表]);
有返回值的函数可以通过表达式的方式调用。如:
main()
{int a,b,c;
scanf(“%d%d”,&a,&b);
c=sum(a,b); 表达式调用
printf(“%d\n”,c);
}
sum(int x,int y)
{return (x+y);}
当程序结束时,子函数sum的值x+y再返回主函数main()
无返回值的函数不能参加表达式的计算,只能以独立的表达式语句的方式被调用。
Void p()
{ printf(“c 2.0\n”);};
main()
{
printf(“Turbo “);
p(); 表达式调句调用
}
因为p()是个无参函数,所以main()不向p()传递数据。
当一个函数调用另一个函数时,总是先暂停执行自己后边的语句,使程序控制转去执行被调用函数,当被调用函数执行完成后,再由调用函数接收程序控制权,继续执行先有中止后的命令。
三) 函数的作用域:
从作用的位置起,直到源程序文件的未尾。
位置靠后的可直接调用前面的函数;前面的函数如调用后面的函数,除int、char外,必须进行函数说明后才能调用。
函数说明:
函数说明的一般形式为:数据类型 函数名([形式参数表])
如:float ff(int x,float y); 有完整的形参说明
float ff(int,float); 只说明形参的个数和类型
float ff() 不带形参的
函数说明对函数作用域的影响:
若说明在函数体内,则该函数作用域仅限于调用函数体内说明位置之后;若在函数体内说明,则被说明函数的作用域是从说明处开始直到整个源文件结束。
三:用参数传递数据:
函数之间的数据联系是通过数据传递实现的。传递的数据即可以是变量的值,也可以是变量的地址。
数据传递的方式有:函数返回值、虚实结合、全局变量三种。
一) 虚实结合的过程和特点。
虚实结合适用于所有的有参函数,传递的数据可以是变量、数组、指针、函数等。
结合的过程:
有参函数在被调用前,形参是没有值的,它的值要在调用时由调用它的函数通过实参传递过来,称为虚实结合。其过程就是调用函数将实参的值复制到被调用函数对应的形参中。
实参的值即可是数据,也可是指针。
特点:
1形参是一种auto型的局部变量,与实参各自占用自己的存储单元,在虚实结合前,形参与实参并无联系,此时形参的值是不确定的,不能引用。
2当函数被调用时,虚实才会结合。这时实参的值被复制到对应的形参中,形参有了初值,但当形参所在的函数运行结束时,形参所占的存储单元将被释放,其值也不复存在。
3在虚实结合中,形参与实参不是靠名称相同来传递数据,而是在对应位置之间传递数据,这就要求形参与实参在数据类型、个数和顺序上一一对应,否则就会出错。
二) 变量的传递:
分值传递和地址传递。
值传递:
当实参是变量、数组元素或表达式时,对应的形参必须是变量。虚实结合时,实参的值被复制到对应的形参中,形参获得实参的值后就终止与实参的联系。调用结束后,尽管形参的值发生了改变,但不会影响实参的值。这种传递是单向传递。
读懂下列程序:
main()
{ int x,y,swap(int a,int b);
scanf(“%d%d”,&x,&y);
printf(“output in main before calling swap: x=%d,y=%d\n”,x,y);
swap(x,y); 函数调用
printf(“output in main after calling swap: x=%d,y=%d\n”,x,y);
}
swap(int a,int b)
{int t;
t=a,a=b,b=t; 变量交换
printf(“output in swap:a=%d,b=%d\n”,a,b);
}
输出的结果是两次printf是一样的,如:123 456
地址传递:
当实参是变量的地址或指向变量的指针时,对应的形参必须是指针变量。虚实结合时,形参获得实参中的地址值,从而成为指向实参所指向变量的指针,对参形的操作实际上是在实参所指向的存储单元中进行的,因此,形参的改变将导致对应的实参所指向的存储单元发生相同的变化。
特点:可以在被调用函数中直接对实参所指的存储单元进行访问和处理,从而实现了数据的双向传递。
读懂下列程序:
main()
{int x,y,swap(int *,int *);
scanf(“%d%d”,&x,&y);
printf(“output in main before calling swap: x=%d,y=%d\n”,x,y);
swap(&x,&y);
printf(“output in main after calling swap: x=%d,y=%d\n”,x,y);
}
swap(int *a,int *b)
{int t;
t=*a,*a=*b,*b=t;
printf(“output in swap:a=%d,b=%d\n”,*a,*b);
}
结果是:两次运行的printf输出值正好相反,如:123 456和 456 123
展开阅读全文