函数就是功能,每一个函数都对应着一种特定的功能。函数的名字应反映代表的功能。
在设计一个较大的程序时,常唱将其分为若干个模块,每个模块中编写有所需功能的函数。通常分为一个主函数和若干个其他函数。由主函数调用其他函数,其他函数也可相互调用。
示例
#include
int main()
{
void print_star(); //声明print_star函数
void print_message(); //声明print_message函数
print_star();
print_message();
print_star();
return 0;
}
void print_star() //定义print_star函数
{
printf("**************")
}
void print_message() //定义print_message函数
{
printf("你还好吗?\n"); //输出文本信息
}
//运行结果
开始运行...
**************
你还好吗?
**************
运行结束。
注:
(1)C程序的执行是从main函数开始的,在main函数中调用其他函数,应在调用后返回main函数。在main函数中结束整个程序的运行。
(2)所有的函数都是平行的,它们之间可以相互调用,但main函数除外;它是被操作系统调用的函数。函数不能嵌套定义,因为函数之间没有从属关系。
(3)库函数和自定义函数
库函数由系统提供,用户可以直接使用。自定义函数是用户自己编写并定义的用来解决用户需求的函数。
(4)无参函数与有参函数
调用无参函数时,主调函数不向被调用函数传递数据。无参函数一般用来执行指定的一组操作。无参函数可以带回或不带回函数值,一般以不带回函数值的居多
调用有参函数时,调用函数时,主调函数在调用被调用函数时,通过参数向被调用函数传递数据。一般情况下,执行被调用函数时会得到一个函数值,供主调函数使用。
(5)一个源程序文件是一个编译单位,一个源程序文件由一个或多个以及其它有关内容(如指令、数据声明与定义等)组成。程序编时是以源程序文件为单位进行编译的。
C语言要求,在程序中用到的所有函数,都必须先定义在使用。
一般形式:
类型名 函数名()
{
函数体
}
或
类型名 函数名(void)
{
函数体
}
void表示无参。函数体包含声明部分和语句部分。定义函数时要用“类型标识符”(即类型名)来指定函数值的类型。(函数带回值的类型)
一般形式:
类型名 函数名(形式参数表列)
{
函数体
}
示例:
int max(int a,int b)
{
int c; //声明部分
c=a>b?a:b; //执行语句部分
return(c); //将C(函数返回值)带回主函数
}
一般形式:
类型名 函数名()
{ }
空函数的作用是占一个位置(便于后期扩充新功能)。一般来说,函数名设定为将来要采用的实际函数名
一般形式:
函数名(实参表列)
示例:
print_star();
C=max(a,b);
按函数调用在程序中出现的形式和位置来分,有三种方法。
将函数调用单独作为一个语句。如:print_star();
,不要求函数带回值,只要求函数完成一定的操作。
函数调用出现在另一个表达式中,如:C=6*max(a,b);
,max(a,b)属于一次函数调用,它属于赋值语句的一部分,其要求函数带回一个确定的值参加表达式的运算
函数调用作为另一个函数调用时的参数,如:M=max(c,max(a,b));
,两次函数调用加上赋值,M的值为a,b,c三者中的最大者。
调用有参函数时,主调函数和被调用函数之间存在数据传递关系。已知:在定义函数时函数名后面的变量名称为“形参(即形式参数)或虚拟参数”;在主调函数中调用一个函数时,函数名后面括号中的参数称为“实参(即实际参数)”;实参可以是常量、变量或表达式。
调用函数过程中,系统会将实参的值传递给被调用函数的形参。形参从实参中得到一个值。该值在函数调用期间有效,可以参加该函数中的运算。在调用过程中发生的实参与形参间的数据传递称为“虚实结合”。
#include
int main()
{
int max(int x,int y);
int a,b,c;
printf("请输入数据:");
scanf("%d,%d",&a,&b);
c=max(a,b);
printf("最大值是%的\n",c);
return 0;
}
int max(int x,int y)
{
int z;
z=x>y?x:y;
return(z);
}
//运行结果
请输入数据:6,12
最大值是12
(1)在定义函数中指定的形参,在未出现函数调用时,不占用内存中的存储单元。只有发生了函数调用,函数max的形参才被临时分配内存单元。
(2)将实参的值传递给对应形参。
(3)在执行max函数期间,由于形参已经有值,就可以利用形参进行有关的运算
(4)通过return语句将函数值带回到主调函数,但要注意返回值的类型与函数类型一致。现在,max函数为int型,返回值是变量z,也是int型。若函数不需要return语句,则函数应定义为void类型。
(5)调用结束时,形参将被释放。注意:实参单元仍保留并维持原值,没有改变。若在执行一个被调用函数时,形参的值发生变化,不会改变主调函数的实参的值
注:
实参向形参的数据传递是“值传递”,是单向传递,只能由实参传给形参,而不能有形参传给实参。实参和形参占用不同的存储单元,实参无法得到形参的值。
调用主调函数会得到一个确定的值,这就是函数值(函数的返回值)。
(1)通过return语句获得。return语句将被调用函数中的一个确定值带回到主调函数。若需要从被调用函数带回一个函数值(供主调函数使用),被调用函数中必须包含return语句。若不需要,可以不要return语句。
(2)函数值的类型。既然函数有返回值,那这个值应属于某一个确定的类型,应当在定义函数时指定函数值的类型。
(3)函数类型一般应和return语句中的表达式类型一致。若函数值的类型和return语句中表达式的值不一致,则以函数类型为准。对数值型数据,可以自动进行类型转换。即函数类型决定返回值的类型。
#include
int main()
{
int max(float X,float Y);
float a,b;
int c;
scanf("%f,%f,",&a,&b);
c=max(a,b);
printf("最大值是%d\n",c);
return 0;
}
int max(float X,float Y)
{
float Z;
Z=X>Y?X:Y;
return(Z);
}
//运行结果
1.2 2.6
最大值是2
对于不带回值的函数,应定义为“void类型”(或称为“空类型”)
在一个函数中调用另一个函数(被调用的函数)需要具备如下条件:
(1)被调用的函数必须是已经定义的函数
(2)若使用库函数,应该在本文件开头用#include指令将调用有关库函数时所需用到的信息“包含”到本文件中来。
(3)若使用用户自定义的函数,则该函数的位置在调用它的函数(即主调函数)的后面(在同一文件中),应该在主调函数中对被调用的函数作声明。声明的作用是把函数名、函数参数的个数和参数类型等信息通知编译系统,以便在遇到函数调用时,编译系统能正确识别函数并检查调用是否合法。