函数也称子程序、例程或过程,它是把一些相关的语句组织在一起,用于解决某一特定问题的语句块。
函数分为系统函数和自定义函数两种。系统函数是C++标准函数库中提供的可以在任何程序中使用的公共函数,使用系统函数必须指定函数所在的包含文件,如sqrt()函数的使用要包含math.h头文件,自定义函数库是用户为了满足自己的需求自己定义的函数。
下面主要介绍自定义函数:
1.函数的定义:
函数必须先定义才能使用。函数的定义如下:
      <函数返回值的类型><函数名>(<函数的形式参数1,函数的形式参数2,…>)
        {                         
            <若干条语句>
            }
  说明:
      1)函数名需要符合标示符的命名规则;
2)类型是该函数即返回值的类型。类型可以是各种数据类型。如果没有返回值,函数类型为void。缺省的函数函数返回值的类型为整数类型int
3)函数的形式参数表,可以没有参数,也可以是多个参数,每个参数之间用逗号进行隔开。函数的形式参数可以看做函数的输入。
4)函数的返回值可以看作是执行函数后的输出。函数的输出用return语句返回,return语句用来结束函数的执行并返回一定的值,返回的值必须与定义的函数类型一致。如果函数是void类型,return语句后不带返回值。
例如:看下面是几个函数的参数及返回类型。
      (1)获取参数并返回值
       int bigger(int a, int b)
         {
          return(a>b)?a:b'
         }
    (2)获取参数但不返回值
         int delaylong a
         {
          for (int i=1;i<=a;i++); //时间延迟
         }
      (3)没有获取参数但返回值
         int geti( )
         {
          int x;
          cout <<"Please input a integer:\n";
          cin>>x;
          return x;
             }
    (4)没有获取参数也不返回值
         void message( )
         {
      cout <<"This is a message. \n"
         }
4.例如:
   int max(int x,int y)
{
  if(x>y) return x ;
  else  return y;
}
注意:return语句可以再语句中出现多次,但是只能返回一个结果,如例题中分支语句确保
只有一个值返回。
2.函数的调用:
调用函数的方式非常简单,其通用的格式为:
函数名(实际参数);
说明:
  函数有几个形式参数,就需要提供几个实际参数,实际参数要和形式参数从左到右一一对应,对应包括数据类型一致和和个数一致。
如果函数没有形式参数,只需要写函数名和括号即可。
在调用无参数函数时,注意不要遗忘括号,这是许多初学者经常犯的错误。
函数调用的过程是 把实际参数的值做个拷贝传递给形式参数,形式参数获取数值后利用该数值参与函数体内代码的运算,实际参数的值不作任何的改变,这个过程叫传值.pass_by_value.对形式参数的任何操作部影响对应的实际参数。
3.函数的返回值的使用:
对于具有返回值的函数,在调用函数时,需要获得函数的返回值,可以定义一个与函数返回值类型相同的变量,在调用函数时将函数的调用结果赋值给该变量。
例如,调用Add函数。
1:加法函数的定义与调用:
#include <iostream.h>
//函数的定义如下:
int add(int a,int b)//
{
    return a+b;//函数体
}
void main()
{
int x=100;
cout<<add(x,x)<<endl;//函数的调用
cout<<x<<endl;
}
执行函数调用后x的值仍然为100
2:素数函数的定义与调用
4.函数的声明:
C++中可以函数调用在前,函数定义在后,但必须在调用前对该函数进行声明,否则编译时候时候就会出现错误。函数的声明所起到的作用是告诉编译系统该函数的定义在后。
#include <iostream.h>
//函数的声明如下:
int add(int a,int b)
void main()
{
int x=100;
cout<<add(x,x)<<endl;//函数的调用
cout<<x<<endl;
}
//函数的定义如下:
int add(int a,int b)//
{
    return a+b;//函数体
}
仔细看一下,函数的声明与函数定义的区别,函数的声明是函数定义的第一行语句,以分号结束,函数的定义的第一行没有分号。函数的声明也叫函数原型,函数原型必须与函数定义一致,否则会引起编译错误
其他注意事项:
1.函数定义不允许嵌套,即函数中不允许再定义一个函数
如下:
#include <iostream.h>
//函数的声明如下:
int add(int a,int b)
void main()
{int x=100;
cout<<add(x,x)<<endl;//函数的调用
cout<<x<<endl;
//函数的定义如下:
int add(int a,int b)//
    {
    return a+b;//函数体
    }
}
错在把add() 函数定义在main ()函数的里面,出现了嵌套定义。
作业:
1. 自定义一个函数,求两个数中的最大数,然后在主函数中输入三个整数,两次调用自己定义的函数求3个数中的最大数。
2. 定义一个函数,求四个整数的平均值,并在主函数中,输入四门功课的成绩,调用自己定义的函数,求四门功课的平均分。
3. 编写一个判断素数的函数,在主函数中输入一个整数,判断输出是否是素数。
5、函数的递归调用
  1)函数的递归调用是指在调用一个函数的过程中又直接或间接调用了函数本身。
  1下面的函数用来求n
   long fact(int n)
   {
    if (n==1)
    return 1;
    return fact(n-1)*n;
   }
 这是直接递归调用的例子。
2:下面的函数调用是间接递归调用
调用子程序的例子//函数1的定义中调用了函数2    
int fn1(int a)
     {
      int b;
      b=fn2(a+1);
     ...
     }
//函数2的定义中调用了函数1    
  int fn2(int s)
     {
      int c;
      c=fn1(s-1);
     ...
     }
2 函数递归调用机制
  递归函数调用遵守函数调用机制,当函数自己调用调用自己时也要将函数状态、返回地址、函数参数、局部变量压入栈中进行保存。
  实际上函数被调用时执行的代码是函数的一个副本,与调用函数的代码无关。当一个函数被调用两次,则函数就会有两个副本在内存中运行,每个副本都有自己的栈空间且与调用函数的栈空间不同,因此不会相互影响。这种调用机制决定了函数是可以递归调用的。
3 递归的实现
一个问题能否用递归实现,看其是否具有下面的特点:
1 需有完成任务的递推公式。
2 结束递归的条件。
编写递归函数时,程序中必须有相应的语句:
3 一个递归调用语句。
4 测试结束语句。先测试,后递归调用
例编程求出Fibonacci数列的第n项。
 Fibonacci数列定义如下:
             Fn=1 n=1
                   Fn=1 n=2
            Fn-1+Fn-2 n>2
 假定求出第八项。
分析:Fibonacci数列的计算具备递归的条件。
首先有递推公式Fn=Fn-1+Fn-2),第二有结束递归的条件即n=0n=1时不再递
归。
编程如下:
 #include <iostream.h>
 const N=8;
 long fibo(int n);
 void main( )
 {
  long f=fibo(N);
  cout<<f<<endl;
 }
 long fibo(int n)
 {
  if (n==1) return 1;
  else if (n==2) return 1;
  else
  return fibo(n-1)+fibo(n-2);
 }
 程序执行结果如下:
 21
4) 递归的评价与消除递归
  递归程序虽然易读、易编,但需要占用额外的内存空间,并且执行速度也受影响。是否利用递归编程要看实际问题,如果要节约内存就用循环语句实现。若对内存要求并不高,用递归编程会更好。
5.内联函数
1 内联函数的意义
  内联函数就是在程序编译时,编译器将程序中出现的内联函数的调用表达式用内联函数的函数体来代替。
2 内联函数的实现
  定义内联函数的方法很简单。只要在函数定义的头前面加上关键字inline即可。其它与函数
定义相同。例如:
 inline int add_int(int x,int y,int z)
 {
  return x+y+z;
 }
 这里add_int就是一个内联函数。
3 内联函数的声明
  与其它函数一样,内联函数必须先声明后使用,如果要声明一个内联函数原型,则也必须加上声明关键字inline。例如:
 inline int add_int(int x,int y,int z)//函数原型
看下面的程序
 #include <iostream.h>
 int power_int(int x);
 void main( )
 {
  for (int i=1;i<=10;i++)
  {
   int p=power_int(i);
   cout<<i<<'*'<<i<<'='<<p<<endl;
  }
 }
 inline int power_int(int x)
 {
  return (x)*(x);
 }
  由于说明函数原型时未使用关键字inline,即使在函数定义时有关键字inline,函数add_int也不认为是一个内联函数。这是因为其替换代码必须在调用前就生成。相反的函数定义位置的inline可以省略。
4 内联函数的限制
1 在内联函数内部不允许使用循环语句和开关语句,否则系统将其视为普通函数。
2 内联函数不能是递归函数。
3 语句数尽可能少,一般不超过5行。
6函数重载
  所谓函数重载是指同一个函数名可以对应着多个函数的实现,每种实现对应一个函数体。也就是说函数名相同,但是函数的参数类型不同或者参数的个数不同,或者参数类型和个数都不同同名函数是重载函数。
例如,可以给函数名add()定义多个函数实现,该函数的功能是求和,即求两个操作数的和。其中,一个函数是求两个int型的和,另一个实现是求两个浮点型数之和。
1求两个操作数之和。
 #include <iostream.h>
//函数的声明 
int add(int,int);
double add(double,double);
 void main( )
 {
  cout<<add(5,10)<<endl;
  cout<<add(5.0,10.5)<<endl;
 }
 int add(int x,int y)
 {
  return x+y;
 }
 double add(double a,double b)
 {
  return a+b;
 }
 程序的输出结果为:
 15
 155
要求:自己定义函数求几个int型中的最小值

2 函数重载的匹配
  调用一个重载函数时,编译器是依据实际参数的类型和个数来确定该调用哪个同名函数,;
 ......
 void delay(int loops)
 {
  if (loops==0)
  return;
  for (int i=0;i<loops;i++);
 }
  这是一个时间延迟函数,调用该函数时必须指出参数。如果想要默认延迟为loops的值为1000,则在函数声明时为loops指定一个默认值即可。
 void delay(int loops=1000);
这样调用时可以指定或省略参数。例如
 delay(3000);
 delay( );

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。