zoukankan      html  css  js  c++  java
  • 函数

     

    第一节  函数的定义

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

    重要程度:★★★

    概念题目:

    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 ",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 ", 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 ");
    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 ", 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 ");
    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);
    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 ", m);
    16. printf("1+2+3+...+%d+%d = %d ", 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! ");
    3. }

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

    int a = func();

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

  • 相关阅读:
    2017-2018-1 20155304 20155332 实验二 固件程序设计
    《信息安全技术》实验二 口令破解
    2017-2018-1 20155304 《信息安全系统设计基础》第六周学习总结
    2017-2018-1 20155304 20155310 20155337 实验一 开发环境的熟悉
    2017-2018-1 20155304 《信息安全系统设计基础》第五周学习总结
    第五周 加分题-mybash的实现
    2017-2018-1 20155304 《信息安全系统设计基础》第四周学习总结
    2017-2018-1 20155304 《信息安全系统设计基础》第三周学习总结
    课下作业2
    课下作业1
  • 原文地址:https://www.cnblogs.com/zhugeanran/p/8552489.html
Copyright © 2011-2022 走看看