Functions
  1. All programs are a series of functions, one of which must be called main.

  2. Function form.

    All functions have the following form:
    <type> function name(<list of parameters>)
    {
     <body of function>
    }
    
    < > indicate that this is optional. If the type is omitted, then int is assumed.

  3. C/C++ do not support procedures, only functions. The same result as using a procedure can be achieved by ignoring the return value or by not not returning a value.

  4. Functions that do not return a value should be typed as void.

  5. Functions may NOT be nested. All functions are at the same level.

  6. Functions may be coded in any order it is not necessary for a function to be ahead of its invocation. However before using a function it must be prototyped to declare the number and types of arguments.

  7. When a function is invoked, control is passed to the function.
    #include <iostream>
    
    void sub1();  //  prototype
    void sub2();  //  prototype 
    using namespace std;
    int main()
    {
     cout << "main" << endl;
     sub1();
     cout << "main" << endl;
     system("pause");
     return 0;
    }
    void sub1()
    {
     cout << "Sub 1" << endl;
     sub2();
     cout << "Sub 1" << endl;
     return;
    }
    void sub2()
    {
     cout << "Sub 2" << endl;
     return;
    }
    
    main
    Sub 1
    Sub 2
    Sub 1
    main
    


  8. return

    Functions may or may not contain a return statement. If there is not a return statement, control is passed back to the calling function after all statements have been executed in order. If a return statement is present control is return as soon as a return is executed. If a function uses return without a value the function type should be void. A function may have multiple return statements.

    The return statement has two forms:
     return ;
     return (expression);
    
    The first form transfers control, the second form returns the value of the expression.

  9. Variable scope

    Variables may declared anywhere in a program after the start of a block { }. The following is an example of name overloading, using the same name for different variables. In the following example the if block cannot reference the int i value.
    #include <iostream>
    using namespace std;
    int main()
    {
     int i=2;
     
     cout << i << " - ";
     if(i) {
         float i=3.14159;
         cout << i << " - ";
     }
     cout << i << endl;;
     system("pause");
     return 0;
    }
    
    2 - 3.14159 - 2


  10. Local vs Global Variables.
    Variables inside a block are local to it and may only be used in that block. If there is name overloading as in the example, local variables precede global variables.

    Variables defined outside of a function block are global to the whole program.
    #include <iostream>
    using namespace std;
    
    void sub1(); // prototype
    
    int i=1;  // global
    
    int main()
    { 
      i++;
      cout << i << endl;
      sub1();
      system("pause");
      return 0;
    }
    void sub1()
    {
      i++;
      cout << i << endl;
      return;
    }
    
    2
    3
    
    Generally the use of global variables is frowned upon as it can lead to side effects.



  11. static variables.
    Variables declared inside of a block are deallocated when the code leaves the block. A special type of variable, static is retained so it value can be used. But it is not available outside the block.
    #inclue <iostream>
    using namespace std;
    int main()
    {
      int x;
      for(x=0;x<3;x++) {
        int i=10;
        cout << i << endl;
        i--;
      }
      for(x=0;x<3;x++) {
        static int i=10;
        cout << i << endl;
        i--;
      }
      system("pause");
      return 0;
    }
    
     
    10
    10
    10
    10
    9
    8
    

  12. Parameters
    Values may be passed to functions using the parameter passing mechanism. The actual arguments are specified in the function call, the formal parameters are in the function definition. All scalar arguments are passed by value, while all array references are passed by address. There is a one to one correspondence between actual and formal arguments based on position (not name).
    #include <iostream>
    using namespace std;
    
    int sub1(int, int);  // prototype 
    
    int main()
    {
      int x=1,y=2,z;
      z=sub1(x,y);       /*actual parameters */
      cout << x << " " << y << " " << z << endl;
      system("pause");
      return 0;
    }
    int sub1(int a,int b)           /* formal parameters */
    {
      a++;
      b++;
      return(a+b);
    }
    
     
    1 2 5
    
    Note changing a and b in the function sub1 did not affect the values in x and y in function main. Why? Only the value of the variables was passed to the function. This is commonly known as call by value. In order to change the value in a variable, the invoking function will pass the address of the variable the using function will need to use indirection. This is commonly known as call by reference or call by name.
    #include <iostream>
    
    using namespace std;
    
    int sub1(int, int*); // prototype 
    
    int main()
    { 
      int x=1,y=2,z;
      z=sub1(x,&y);       /*actual parameters */
      cout << x << " " << y << " " << z << endl;
      system("pause");
      return 0;
    }
    int sub1(int a,int *b)           /* formal parameters */
    {
      a++;
      *b+=1;
      return(a+*b);
    }
    
     
    1 3 5
    

  13. C++ extensions
    1. Reference type

      This feature removes the need for passing by address and using pointer notation.
      #include <iostream.h>
      
      using namespace std;
      
      void fun(int&);  // protoype
      
      int main()
      { 
        int i=1,j;
        fun(i);
        cout << i <<endl;
        system("pause");
        return 0;
      }
      void fun(int& x)
      {
       x++;
       return;
      }
      

    2. Default Arguments.
      #include <iostream>
       
      using namespace std;
       
      void area(int length=2, int width=2);   // prototype
       
      int main()
      {
       area(3,4);
       area(7);
       area();
       system("pause");
       return 0;
      }
       
      void area(int length, int width)
      {
       cout << endl;
       cout << "length=" << length << endl;
       cout << "width=" << width << endl;
      }
      
      
      length=3
      width=4
       
      length=7
      width=2
       
      length=2
      width=2
      
      

    3. Overloaded Functions.
      #include <iostream>
      using namespace std;
      
      float area(float);         // area of a circle pass the radius
      float area(float, float); // area of rectange pass length and width
      
      int main()
      {
         cout << "The area of a circle with  a diameter of 10 is "
              << area(10.0/2) << endl;
         cout << "The area of a rectangle with sides of 3 and 4 is "
              << area(3,4) << endl;
         system("pause");
         return 0;
      }
      
      float area(float radius)
      {
         return radius * radius * 3.14159;
      }
              
      float area(float length, float width)
      {
         return length * width;
      }
      
      
      The area of a circle with  a diameter of 10 is 78.5397
      The area of a rectangle with sides of 3 and 4 is 12
      Press any key to continue . . .
      
      


  14. Examples
    1. Simple function.
      #include <iostream.h>
      
      using namepsace std;
      
      int prime(int);  // prototype
      
      int main()
      {
       int i;
       
       for(i=2;i<10;i++)
          if(prime(i)) cout << i << " is prime" << endl;
          else cout << i << " is not prime" << endl;
       system("pause");
       return 0;
      }
      int prime(int x)
      {
       int i;
       for(i=2;i<=x/2;i++)
          if(!(x%i)) return (0);
       return (1);
      }
      
       
      2 is prime
      3 is prime
      4 is not prime
      5 is prime
      6 is not prime
      7 is prime
      8 is not prime
      9 is not prime
       
      
      


    2. Float example
      #include <iostream>
      using namespace std;
       
      float hmean(float, float);  // Prototype
      
      int main()
      {
       float a,b,c;
       int i;
       
       for(i=1;i<10;i++) {
          a=rand()%100;
          b=rand()%100;
          c=hmean(a,b);
          cout << "harmonic mean of " << a << " and " << b  
                   << " is " << c << endl;
       }
       system("pause");
       return 0;
      }
      float hmean(float x,float y)
      {
       float hm;
       hm = (2*x*y)/(x+y);
       return hm;
      }
      
       
      harmonic mean of 38 and 58 is 45.9167
      harmonic mean of 13 and 15 is 13.9286
      harmonic mean of 51 and 27 is 35.3077
      harmonic mean of 10 and 19 is 13.1034
      harmonic mean of 12 and 86 is 21.0612
      harmonic mean of 49 and 67 is 56.6034
      harmonic mean of 84 and 60 is 70
      harmonic mean of 25 and 43 is 31.6176
      harmonic mean of 89 and 83 is 85.8953
      
      

    3. Using static variables
      #include <iostream>
      using namespace std;
      
      int fib(); // prototype
      
      int main()
      {
       int i;
       for(i=1;i<11;i++) 
           cout << fib() << endl;
       system("pause");
       return 0;
      }
      int fib()
      {
       static int f1=0,f2=0;
       int nf;
       if(!f2) {
             f2=1;
             return 1;
       }
       nf=f1+f2;
       f1=f2;
       f2=nf;
       return nf;
      }
      
       
      1
      1
      2
      3
      5
      8
      13
      21
      34
      55
      

    4. Using global variables
       
      #include <iostream>
      using namespace std;
      
      int fib();  // prototype
      
      int f1=0,f2=0; //globals
      
      int main()
      { 
       int i;
       for(i=1;i<11;i++) 
         cout << fib() << endl;
       system("pause");
       return 0;
      }
      int fib()
      {
       int nf;
       if(!f2) {
             f2=1;
             return 1;
       }
       nf=f1+f2;
       f1=f2;
       f2=nf;
       return nf;
      }
      
      1
      1
      2
      3
      5
      8
      13
      21
      34
      55
      

    5. Using pointers to change variables;
      #include <iostream>
      
      using namespace std;
       
      void swap(int*, int*);  // prototype
      
      int main()
      {
       int a,b,c;
       a=rand()%100;
       b=rand()%100;
       c=rand()%100;
       if(a>b) swap(&a,&b);
       if(a>c) swap(&a,&c);
       if(b>c) swap(&b,&c);
       cout << a << " " << b << " " << c << endl;
       system('pause");
       return 0;
      }
      void swap(int *x,int *y)
      {
       int t;
       t=*x;
       *x=*y;
       *y=t;
       return;
      }
      
       
      14 27 53
      
      

    6. Financial example
      Value of an Annuity.
      An Annuity, or installment plan, is a series of payments made at equal intervals of time. Examples are pensions, IRAs and premiums on life insurance. More often than not, the interest conversion period is unequal to the payment interval. The Following formula determines the eventual cash cash value, s, of an annuity of r dollars paid per year in p installments for n years at an interest rate of j percent converted m times per year.

      x = 1 + j/m

      s = r [ (xmn-1)/ p(xm/p-1)]

      Where s = eventual cash value 
      r = payment per year 
      p = installments per year 
      n = duration of the annuity in years 
      j = nominal interest rate 
      m = conversions per year 
      


      Write a program to determine the eventual cash value after requesting the necessary information. To test use r=2000 p=12 n=20 j=13% m=2, you should get 180,330.40
      //
      // value of an annuity
      //
      #include <iostream>
      #include <iomanip>
      #include <cmath>
       
      using namespace std;
      using std::string;
       
      float prompt(string);   //  prototype
       
      int main()
      {
          float r;  //  payment per year 
          float p;  //  installments per year 
          float n;  //  duration of the annuity in yea
          float j;  //  nominal interest rate 
          float m;  //  conversions per year
          float x;  //  working variable
          float numerator, denominator;
          float s;  // eventual value
          
          r=prompt("payment per year");
          p=prompt("installments per year");
          n=prompt("duration of the annuity in years");
          j=prompt("nominal interest rate");
          m=prompt("conversions per year");
          
          if(j > 1.0) j/=100.0;
          
          x=1 + j/m;
          
          numerator=pow(x,m*n)-1;
          denominator=p * (pow(x,m/p)-1);
          
          s=r*(numerator/denominator);
          
          cout << setiosflags( ios:: showpoint | ios::fixed);
          cout << "The cash value of this annuity is " 
               << setprecision(2) << s << endl;
               
          system("pause");
          return(0);
       
      }
      
      float prompt(string text)
      {
            float fValue=0.0;
            while (fValue <= 0) 
            { 
              cout << "Enter the " << text << " : ";
              cin >> fValue;
            }
            return fValue;
      }
      
      Enter the payment per year : 2000
      Enter the installments per year : 12
      Enter the duration of the annuity in years : 20
      Enter the nominal interest rate : .13
      Enter the conversions per year : 2
      The cash value of this annuity is 180330.44
      Press any key to continue . . .