您好,欢迎进入深圳市颖特新科技有限公司官方网站!

您现在的位置:首页 新闻资讯 >> 新闻头条 >> 函数
新闻资讯
NEWS INFORMATION

函数

发布时间:2019-05-22

 

第一节  函数的定义

知识点:函数的定义法则;

重要程度:★★★

概念题目:

1、C语言的程序设计中,基本组成单位就是函数。一个特定的函数是具有独立功能的C语言代码块,用于完成特定的运算任务。

2、一个C语言程序,可以由一个或多个函数组成。但是一定要注意:在一个程序中只能有一个main函数,无论其位置如何,总是程序开始运行的地方。

3、函数最大的用处是完成某项功能,函数可以用来解决相同的问题,这样可以减少重复编写的工作量,提高整个程序的可读性。

4、函数的返回值默认情况下为int。

5、在一个函数的函数体中不允许再定义新的函数。

6、函数使用两种规则:第一要求先定义,后调用。第二先声明,再调用,后定义。

练习题:以下叙述中错误的是(    )。c
A)C语言编写的函数源程序,其文件名后缀可以是.C
B)C语言编写的函数都可以作为一个独立的源程序文件
C)C语言编写的每个函数都可以进行独立的编译并执行
D)一个C语言程序只能有一个主函数

1、函数的定义

我们看到函数一般形式的定义如下:

函数返回值的类型名  函数名 (类型名1  形式参数名1,类型名2  形式参数名2,……)

{

说明部分

语句部分

}

在定义的形式中,第一行整体称之为函数的首部,圆括号中的形式参数简称为形参。函数体是指一对花括号括起来的部分,函数体中的主要功能是完成函数中需要使用的变量的定义说明、完成必要的功能的代码,也就是完成函数功能。

1:一个用来计算两个整型数据相加的函数。

 int add(int x,int y)

{

  int z ;

    z=x+y ;

    return z ;

}

对照函数的一般形式定义,我们可以知道该例中:

函数返回值的类型名:int         函数名: add

类型名1  形式参数名1:  int  x    类型名2  形式参数名2:  int  y

说明,语句部分:int z ;

          z=x+y ;

          return z ;

说明:

1)函数的返回值实际上就是函数的运算结果。当函数返回值的类型名缺省时,返回值类型默认为int类型,而不是无返回值。如果要函数只是进行运算,不要有运算结果,也就是要函数没有返回值,那么类型名应为void。

2)函数名实际上相当于人的姓名,是用户定义标识符。在同一程序中,函数的名称必须互不相同。主函数的函数名必须为main,且只有一个。

3)如果函数没有形式参数,也没有函数体具体的实现,那么这个函数就叫做空函数。如下面的函数wangcheng就是一个空函数:

wangcheng( )

{

}

对形参的一点说明。

形参与这些变量都是属于这个函数的。是函数被使用的时候临时分配的,一旦函数使用完毕,这些空间均被释放。它们作用的范围也只是本函数内,因此可以与其他函数的变量、形参同名。例如例1中,变量x、y、z都是属于函数add的,那么与其它函数中出现的x、y、z是不冲突的,同时,当add函数使用完成后,x、y、z使用也就完成,系统会自动把x、y、z释放掉。

第二节  函数的返回值

1、函数的返回值(考试重点)

1、函数的返回值实际上就是函数运行的结果。

2、如果要求函数没有返回值,即返回值类型为void

3、一个函数可以有多个return的语句,但是每次调用函数,只有一个return语句被执行。程序一旦执行return语句就会结束当前函数的运行,其作用有些类似于循环结构中的break语句。

4、一对圆括号可以缺省。以下的返回方式都正确return z;  return  x+y;  return  (x+y) 直接写上一个数值也是对的,如return 9。所以我们记住:return 是返回函数计算得到的结果。

5、函数的返回值就是表达式的值,返回值的类型必须与函数首部中返回值的类型一致。否则系统将强制的以首部中的类型为准。(近几年考得很多)

    int  add(float a,  flaot b)

{

  float  c;

  c= a+b;

  return c;

}   

这个地方注意虽然是return c为整型,但是函数首部中是int,最后是以首部为准,就是返回一个整型。

1:定义一个求矩形面积的函数:

double recarea ( double x, double y)

{     double area;

area=x*y;

return area;

}

在这个函数中:

1) 函数的首部是double recarea(double x, double y)。该函数的返回值类型为double,函数名为rearea,一共有2个形参,类型都是double,形参名分别为x,y。

2) 函数体部分中定义了一个double类型的变量area,它是用来存放矩形的面积。也就是把两个形参的乘积赋值给它。

3) 该函数是要有运算结果的,且结果是矩形的面积。也就是我们要把变量area中的内容作为函数的运算结果,这个是通过return area 语句完成的。

4) 该函数实际解决的问题是:只要知道了矩形的长和宽,就可以通过recarea函数求得矩形的面积。每次可以传递不同的长和宽的数值给recarea函数,这个叫做函数的调用,后面会详细介绍。

2:以下isprime函数的功能是判断形参a是否为素数,如果是素数,函数返回1,否则返回0。请填空。本题是2006年4月的考题,考察点return语句的使用,难度适中。

int  isprime(int  a)

{     int  i;

for(i=2;i<=a/2;i++)

if(a%i==0)                   ;

                       ;

}

分析:

从函数的首部了解函数名、函数的返回值类型、函数的形式参数。可知:返回值类型int,函数名isprime,形参为int类型,形参名字为a。在函数体中,定义一个int类型的变量i,后面语句部分是判定素数的方法:判断一个整数是不是素数,就要看除了1和它本身外,还有没有能被它整除的整数。

循环的变量i要从2开始一直到a/2,一旦有一个i能被a整除,那么a就不是素数。题目要求不是素数,函数返回0。所以if条件后面a%i==0表示a整除i,所以不是素数,应该填写return 0。如果整个for循环结束了if的条件a%i==0都为假,即表示没有哪一个i能被a整除,a必为素数,返回1。因此后面应填写 return 1 。

注意:执行了return语句后就会退出函数,不会再执行后面的语句,所以该函数虽然有两个return语句,但是每次只会执行一个return语句。

第三节  库函数

知识点:库函数的使用;返回类型、数值;形式参数的类型、个数;

重要程度:★★★★

库函数是不需要用户自己去编写,对于这些函数,用户不需要定义,就可以直接使用。

需要注意:

1) 不同的库函数放在不同的库中。所以使用某一类库函数的时候,首先要打开这个库才可以使用里面的库函数。打开库函数的方法是:在程序的开头使用include命令包含头文件。例如:printf函数是库函数,它是属于库“stdio.h”的。所以使用printf函数要在程序开头加上#include "stdio.h"。再举一个例子:在C语言中有一些处理数学方面的函数,如求根函数(sqrt函数)或求绝对值函数(abs函数),这些函数是放在库“math.h”中的。使用这些函数就必须在程序开头加上如下命令:#include "math.h"。

2) #include "stdio.h",其中的""也可以用一对< >代替:#include <stdio.h>

 

3) 库函数要掌握的是其使用的方法,返回的数值参数的个数参数的类型

 

4) 打开库函数#include "stdio.h"的后面是不要写分号的。

 

5)常考的库函数:(考试重点

1、sqrt(4)             返回√4的值

2、fabs(x)             返回双精度参数x的绝对值

3、pow( 2,3)         返回23的值(考得是最多的)

4、exp( 3 )            返回指数函数e3的值

 

第三节  调用函数

知识点:函数调用的规则;函数调用的实际作用是使用函数;

重要程度:★★★★★

调用函数实际上就是使用函数,调用一次就是使用一次。每次调用函数的时候,可以给函数传递不同的数值,得到不同的运行结果。

调用某些函数,可以求得函数值或者完成一些流程(如打印)的功能。

 

1、函数的调用形式

函数调用的一般形式为: 函数名(实际参数表)

1:一个具体的调用例子

int add(int x,int y)

{ int z ;

    z=x+y ;

    return z ;

}

main()

{ int sum;

  sum=add(5,6);

  printf(“sum=%d”,sum);

}

例1中:有两个函数,一个是main函数,也就是主函数。另一个是add函数,是用来处理两个数相加的。

说明:

1) 在main函数中,add(5,6);就称为函数的调用。可以看到函数调用时,与定义不同。不用写返回值类型和实际参数(简称“实参”)类型。函数add括号中5,6就是实际参数(它们有实际的意义)。    

2)实参可以是常量、变量、表达式,甚至是函数的调用(函数值)。所以这个地方

实参为常量:  sum=add(5,6);合法调用。

实参为变量:  sum=add(x,6);假定x给了一个初始数值5,也是合法调用。

实参为表达式: sum=add(x+y,6);只要x+y可得一个结果且类型为整型,也是合法调用。

实参为函数的返回数值:sum=add(add(5,6),6);由于add(5,6)可以得到一个结果11,所以也是合法调用。(近几次考试重点)

3)函数的调用可以作为一条独立的语句。add(5,6)这个函数调用有返回值时,函数调用可以作为一个表达式出现在任何合法的地方。如果add(5,6)这个调用函数无返回值(即返回值类型为void)时,不能把函数调用的结果通过赋值号进行赋值:sum=add(5,6)就错了,因为add(5,6)函数调用就没有运算的结果,无法给变量sum赋值。

下面通过几个例子来具体学习函数的调用:

2与数学式子        对应的C语言表达式是

 

A) 3*x^n(2*x-1)                               B) 3*x**n(2*x-1)

C) 3*pow(x,n)*(1/(2*x-1))          D) 3*pow(n,x)/(2*x-1)

分析:本题考察点:库函数的调用。^只是按位异或。x^n显然不是xn ,A显然是错误的。C语言中没有乘方的符号,xn要通过C语言的库函数来完成的。处理乘方的库函数是pow(x,n)。注意参数的先后次序。D选项错误地传递了参数,返回值为nx。B选项中没有“**”这种运算符号,错误。C选项正确的使用了库函数pow(),实参x和n正确的传入,返回值为xn。答案为C。

3 以下函数定义:

void fun( int  n, double  x)  { …… }

若以下选项中的变量都已正确定义并赋值,则对函数fun的正确调用语句是

A) fun(int  y,double  m);             B) k=fun(10,12.5);

C) fun(x,n);                           D) void fun(n,x);

分析:本题考察点:调用函数的语法规则。观察函数的首部,注意到fun函数返回类型为void,表示没有返回值。第一个形参类型为int,第二个形参类型为double。A项调用函数时写出实际参数类型,这个是错误的。B选项fun(10,12.5)是没有运算结果的,是无返回值。那么调用时不能赋值给变量k的。D项调用函数时不需写出返回值类型void。C选项形参与实参的同名不互相影响,是正确的。

4:本题是2006年9月的考题。以下程序中,函数fun的功能是计算x2-2x+6,主函数中将调用fun函数计算:

y1=(x+8)2-2(x+8)+6

y2=sin2(x)-2sin(x)+6

请填空。

#include   "math.h"

double  fun(double  x) { return(x*x-2*x+6);}

main( )

{     double x,y1,y2;

printf("Enter x: ");  scanf("%lf",&x);

y1=fun(              );

y2=fun(              );

printf("y1=%lf,y2=%lf\n",y1,y2);

}

分析:考察点:函数调用中实参与形参之间的传递。题目要求中有两个多项式的计算,实际上是多项式x2-2x+6的x取两次不同的数值来运算。也就是在C语言中两次调用函数,每次调用传递不同实参的问题。可知函数fun返回值为double类型。变量y1实际上存放当形参x为x+8时fun函数的计算结果。变量y2实际上存放形参x为sin(x)时fun函数的计算结果。因此,只需在两次调用fun函数的时候写出正确的实参就可以了。整个程序是实现了从键盘输入x的值,即达到了输出y1与y2值的功能。第一空填x+8,第二空填sinx

第四节  函数的声明

知识点: 函数声明合法的几种表示方式;

重要程度:★★★★

我们知道,每个人都是先起名字,才可以称呼其人。函数也是这样,一般情况下,函数应遵循“先定义后调用”的规则。当然,很多时候都把函数的定义统统放在主函数main的后面,即定义在调用之后。这样做,也可以。但必须是在调用之前对函数进行声明。声明是表示有这样的一个函数存在。

1、函数声明的一般形式

(函数声明必要的是函数名、参数个数、参数的类型、返回值的类型这四样,其中特别记住,函数声明中函数的参数的名字是可以变化甚至不写的!!!)

一个简单的例子

double recarea( double x, double y);           /*函数声明*/

main( )

{     double area;

area=recarea(2.2,3.3);                      /*函数调用*/

printf("area=%d",z);

}

double area( double x, double y)           /*函数定义*/

{     double area;

area=x*y;

return area;}

针对该例,我们写出几种合法的函数声明,

写法一:double recarea( double x, double y);  这个和我们后面函数定义的第一部分一模一样。

写法二:double recarea( double , double );  声明的时候,可以省略形式参数。

写法三:double recarea( double a, double y); 声明的时候,参数的名称可以和后面定义时候不同。

在使用函数时,可以有三种方式:

(1)先定义后调用。此时不需要进行函数声明。

(2)先声明,后调用,最后定义,就是上面例子中采用的方式。

(3)对于返回类型是int类型的,可以先调用,后定义。不需要声明。

有难度的考题;(含有指针的函数声明)

    int *max(int *x , int *y)

{if(*x>*y)return x;

else return y;}

这种函数的声明的方法:

1、    int *max(int *x , int *y) 这个是与定义一样的声明。

2、    int *max(int * , int *)   这个是省略了变量的声明。

3、    int *max(int *b  , int *a)这个是改变了变量的声明。

2、函数声明的位置

函数声明的位置有两种方式:

1)在函数的外部:那么只要出现了函数的声明,从声明之后的任何位置都可以调用该函数。

2)在某函数的内部:此时的函数声明就有使用范围了。函数的调用只能在函数声明出现的地方。其它函数中是不能调用该函数的。

1: 若程序中定义了以下函数

float add(float a, float b)

{ float c;  

c=a+b;

return c;}

并将其放在调用语句之后,则在调用之前应进行函数声明,以下选项中错误的是

A) float  add(float a, b);                   B) float  add(float, float);

C) float  add(float b, float a);       D) float  add(float x, float y);

分析:本题考察点:在函数声明的三种形式。A选项缺少第二个参数的类型名。答案选择A。

2本题是2006年4月的考题,若各选项中所用变量已正确定义,函数fun中通过return语句返回一个函数值, 以下选项中错误的程序是

A) main( )                                         B) float fun(int  a,int  b){……}

{ …… x=fun(2,10); …… }                       main( )

float fun(int  a,int  b){ …… }             { …… x=fun(i,j); …… }

C) float fun(int,int);                             D) main( )

main( )                                                         {  float fun(int  i,int   j);

{ …… x=fun(2,10); …… }                   x=fun(i,j); …… }

float fun(int  a,int  b){ …… }             float fun(int  a,int  b){ …… }

分析:在函数的定义、调用和声明。A没有声明就调用函数了,A选项错误。D是在函数体内声明,然后调用。B和C都是在函数外面声明,再在声明之后调用。

函数是一段可以重复使用的代码,用来独立地完成某个功能,它可以接收用户传递的数据,也可以不接收。

无参函数的定义

如果函数不接收用户传递的数据,那么定义时可以不带参数。如下所示:

返回值类型  函数名(){
    函数体
}

说明:

  • 返回值类型可以是C语言中的任意数据类型,例如 int、float、char 等。
  • 函数名是标识符的一种,命名规则和标识符相同。函数名后面的括号( )不能少。
  • 函数体是函数需要执行的代码。即使只有一个语句,也要由{ }包围。
  • 在函数体中使用return语句返回数据。


例如,定义一个函数,计算1加到100的结果:

  1. int sum(){
  2. int i, sum=0;
  3. for(i=1; i<=100; i++){
  4. sum+=i;
  5. }
  6. return sum;
  7. }

计算结果保存在变量sum中,通过return语句返回。sum为int型,所以返回值类型也必须为int,要一一对应。

return是C语言中的一个关键字,只能用在函数中,用来返回处理结果。

将上面的代码补充完整:

  1. #include <stdio.h>
  2. int sum(){
  3. int i, sum=0;
  4. for(i=1; i<=100; i++){
  5. sum+=i;
  6. }
  7. return sum;
  8. }
  9. int main()
  10. {
  11. int a = sum();
  12. printf("The sum is %d\n", a);
  13. return 0;
  14. }

运行结果:
The sum is 5050

函数不能嵌套定义,main 也是一个函数定义,要将 sum 放在 main 外面。函数必须先定义后使用,所以 sum 只能在 main 前面。

注意:main 是函数定义,不是函数调用。当可执行文件加载到内存后,系统从 main 函数开始执行,也就是说,系统会调用我们定义的 main 函数。

无返回值函数

有的函数不需要有返回值,或者返回值类型不确定(很少见),那么用void表示,例如:

  1. void hello(){
  2. printf ("Hello,world \n");
  3. //没有返回值就不需要 return 语句
  4. }

void是C语言中的一个关键字,表示空类型或无类型,绝大部分情况下也就意味着没有 return 语句。

有参函数的定义

如果函数需要接收用户传递的数据,那么定义时就要带参数。如下所示:

返回值类型  函数名(参数列表){
    函数体
}

用户数据通过“参数列表”传递给函数,供函数处理。例如,定义一个函数求两个数中的最大值:

  1. int max(int a, int b){
  2. if (a>b){
  3. return a;
  4. }else{
  5. return b;
  6. }
  7. }

参数(Parameter)本质上也是变量,定义时要指明参数类型和参数名称。参数列表中可以定义一个或多个参数,多个参数之间用逗号,分隔。参数列表中给出的参数可以在函数体中使用。

调用 max() 函数时可以直接传递整数:

int n = max(10, 20);

也可以传递变量:

int a = 10, b = 20;
int n = max(a, b);

也可以整数和变量一起传递:

int a = 10;
int n = max(a, 20);

变量 n 得到的值都是20。

函数定义时给出的参数称为形式参数,简称形参;函数调用时给出的参数(传递的数据)称为实际参数,简称实参。函数调用时,将实参的值传递给形参,相当于一次赋值操作。注意:实参和形参的类型、数目必须一致。

将上面的代码补充完整:

  1. #include <stdio.h>
  2. int max(int a, int b){
  3. if (a>b){
  4. return a;
  5. }else{
  6. return b;
  7. }
  8. }
  9. int main(){
  10. int num1, num2, maxVal;
  11. printf("Input two numbers: ");
  12. scanf("%d %d", &num1, &num2);
  13. maxVal = max(num1, num2);
  14. printf("The max number: %d\n", maxVal);
  15. return 0;
  16. }

运行结果:
Input two numbers: 100 200
The max number: 200

定义max时,变量a、b的值都是未知的;调用max时,分别将num1、num2的值传递给a、b,类似于:

a=num1;
b=num2;

return 语句可以有多个,可以在函数体的任意位置。在max中,根据 if 的判断结果来执行不同的 return 语句。

函数一旦遇到 return 语句就返回(停止执行),后面的所有语句都不会被执行到,例如:

  1. int max(int a, int b){
  2. int n = (a>b) ? a : b;
  3. return n;
  4. printf("Function is performed\n");
  5. }

第4行代码是多余的,永远没有执行的机会。

如果把函数比喻成一台机器,那么参数就是原材料,返回值就是最终产品;函数的作用就是根据不同的参数产生不同的返回值。

函数的参数

在函数定义中出现的参数可以看做是一个占位符,它没有数据,只能等到函数被调用时接收传递进来的数据,所以称为形式参数,简称形参。

函数被调用时给出的参数包含了实实在在的数据,会被函数内部的代码使用,所以称为实际参数,简称实参。

形参和实参的功能是作数据传送,发生函数调用时,实参的值会传送给形参。

形参和实参有以下几个特点:
1) 形参变量只有在函数被调用时才会分配内存,调用结束后,立刻释放内存,所以形参变量只有在函数内部有效,不能在函数外部使用。

2) 实参可以是常量、变量、表达式、函数等,无论实参是何种类型的数据,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参,所以应该提前用赋值、输入等办法使实参获得确定值。

3) 实参和形参在数量上、类型上、顺序上必须严格一致,否则会发生“类型不匹配”的错误。

函数调用中发生的数据传送是单向的,只能把实参的值传送给形参,而不能把形参的值反向地传送给实参。 因此在函数调用过程中,形参的值发生改变,而实参中的值不会变化。

【示例】计算 1+2+3+...+(n-1)+n 的值。

  1. #include <stdio.h>
  2. int sum(int n){
  3. int i;
  4. for(i=n-1; i>=1; i--){
  5. n+=i;
  6. }
  7. printf("The inner n = %d\n",n);
  8. return n;
  9. }
  10. int main(){
  11. int m, total;
  12. printf("Input a number: ");
  13. scanf("%d", &m);
  14. total = sum(m);
  15. printf("The outer m = %d \n", m);
  16. printf("1+2+3+...+%d+%d = %d\n", m-1, m, total);
  17. return 0;
  18. }

运行结果:
Input a number: 100↙
The inner n = 5050
The outer m = 100
1+2+3+...+99+100 = 5050

通过 scanf 输入 m 的值,作为实参,在调用 sum 时传送给形参 n。

从运行情况看,输入 m 值为100,即实参 m 的值为100,把这个值传给函数 sum 时,形参 n 的初值也为100,在函数执行过程中,形参 n 的值变为 5050。函数运行结束后,输出实参 m 的值仍为100,可见实参的值不随形参的变化而变化。

函数的返回值

函数的返回值是指函数被调用之后,执行函数体中的程序段所取得的值,可以通过return语句返回。

return语句的一般形式为:

return 表达式;

或者:

return (表达式);

例如:

return max;
return a+b;
return (100+200);

函数中可以有多个 return 语句,但每次调用只能有一个return 语句被执行,所以只有一个返回值。

一旦遇到 return 语句,不管后面有没有代码,函数立即运行结束,将值返回。例如:

  1. int func(){
  2. int a=100, b=200, c;
  3. return a+b;
  4. return a*b;
  5. return b/a;
  6. }

返回值始终 a+b 的值,也就是300。

没有返回值的函数为空类型,用void进行说明。例如:

  1. void func(){
  2. printf("Hello world!\n");
  3. }

一旦函数的返回值类型被定义为 void,就不能再接收它的值了。例如,下面的语句是错误的:

int a = func();

为了使程序有良好的可读性并减少出错, 凡不要求返回值的函数都应定义为 void 类型。

联系方式0755-82591179

传真:0755-82591176

邮箱:vicky@yingtexin.net

地址:深圳市龙华区民治街道民治大道973万众润丰创业园A栋2楼A08