Chapter 6 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.

    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.

    Functions that do not return a value should be typed as void. Functions may NOT be nested. All functions are at the same level.

    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.

  3. When a function is invoked, control is passed to the function.
    #include <iostream>
    using namespace std;
    void main()
    {
     void sub1(),sub2();  //  prototype 
     cout << "main" << endl;
     sub1();
     cout << "main" << endl;
    }
    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
    

  4. 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.

  5. Variable scope

    Variables may declared anywhere in a program after the start of a block { }.
    #include <iostream>
    using namespace std;
    void main()
    {
     int i=2;
     
     cout << i << " - ";
     if(i) {
         float i=3.14159;
         cout << i << endl;
     }
    }
     
    2 - 3.14159
    
    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. In the following example the if block cannot reference the int i value.

    Variables defined outside of a function block are global to the whole program.
    #include <iostream>
    using namespace std;
    int i=1;
    void main()
    { 
      void sub1();
      i++;
      cout << i << endl;
      sub1();
    }
    void sub1()
    {
      i++;
      cout << i << endl;
      return;
    }
     
    2
    3
    




    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;
    void 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--;
      }
    }
     
    10
    10
    10
    10
    9
    8
    

  6. 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).
    void main()
    {
      int sub1(int, int);  /* prototype */
      int x=1,y=2,z;
      z=sub1(x,y);       /*actual parameters */
      cout << x << " " << y << " " << z << endl;
    }
    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? 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
    void main()
    { 
      int sub1(int, int*); /* prototype */
      int x=1,y=2,z;
      z=sub1(x,&y);       /*actual parameters */
      cout << x << " " << y << " " << z << endl;
      return;
    }
    int sub1(int a,int *b)           /* formal parameters */
    {
      a++;
      *b+=1;
      return(a+*b);
    }
     
    1 3 5
    

  7. C++ extensions
    1. Reference type

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

    2. Default Arguments.
      #include <iostream>
       
      void area(int length=2, int width=2);   // prototype
       
      void main()
      {
       
       area(3,4);
       area(7);
       area();
      }
       
      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.h>
      int fun(int);
      int fun(float);
      void main()
      {
       int x=1;
       float y=1.5;
       int z;
       z=fun(x);
       z=fun(y);
      }
      int fun(int a)
      { 
        cout << "called integer function with " << a << endl;
        return 1;
      }
      int fun(float a)
      {
        cout << "called float  function with " << a << endl;
        return 1;
      }
       
      called integer function with 1
      called float  function with 1.5
      


  8. Examples
    1. Simple function.
      #include <iostream.h>
      void main()
      {
       int i;
       int prime(int);  // Prototype
       
       for(i=2;i<10;i++)
          if(prime(i)) cout << i << " is prime" << endl;
          else cout << i << " is not prime" << endl;
      }
      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.h>
      void main()
      {
       float hmean(float, float);  // Prototype
       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;
       }
      }
      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.h>
      void main()
      {
       int fib();
       int i;
       for(i=1;i<11;i++) 
           cout << fib() << endl;
      }
      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.h>
      int f1=0,f2=0;
      void main()
      { 
       int fib();
       int i;
       for(i=1;i<11;i++) 
         cout << fib() << endl;
      }
      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.h>
      void main()
      {
       void swap(int*, int*);
       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;
      }
      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 . . .
      

  9. Partial C/C++ Function List
    1. abs()
      Prototype: int abs(int aNum);
      Header File: cmath and cstdlib
      Explanation: The abs function returns the absolute value of a number (makes it positive).
    2. atof()
      Prototype: float atof(const char *string);
      Header File: cstdlib
      Explanation: This function accepts a string and converts it into a floating point number. For example, if "1234.34" is passed into the function, it will return 1234.34. If the string contains a decimal place, the number will not be truncated. If a valid number is contained in the string, but is terminated by a non-valid character, the number will be returned, and the non-valid character will be ignored
    3. atoi()
      Prototype: int atoi(const char *string);
      Header File: cstdlib
      Explanation: This function accepts a string and converts it into an integer. For example, if "1234" is passed into the function, it will return 1234, an integer. If the string contains a decimal place, the number will be truncated. Eg, "104.21" will be returned as 104.
    4. clock()
      Prototype: clock_t clock(void);
      Header File: time.h
      Explanation: This function returns the number of clock ticks (the CPU time taken) the program has taken. To convert to the number of seconds, divide by CLOCKS_PER_SEC, which is defined in time.h
    5. ctime()
      Prototype: char *ctime(const time_t *time)
      Header File: time.h
      ANSI: C and C++
      Explanation: Use ctime to convert a time_t variable into a string of 26 characters in the format Fri Jan 28 09:12:21 2000. The string it returns will be overwritten unless you copy the string to another variable before calling ctime again.
    6. fabs()
      Prototype: double fabs(double number);
      Header File: cmath
      Explanation: This function returns the absolute value of a number. It will not truncate the decimal like abs() will, so it is better for certain calculations.
    7. floor()
      Prototype: double floor(double Value);
      Header File: cmath
      Explanation: Returns the largest interger value smaller than or equal to Value. (Rounds down)
    8. isalnum()
      Prototype: int isalnum(int ch);
      Header File: ctype.h
      Explanation: Isalnum does exactly what is sounds like, checks if the ASCII value passed in has a character equivalent to a number of letter. It returns non-zero for true, and zero for false.
    9. isalpha()
      Prototype: int isalpha(int ch);
      Header File: ctype.h
      Explanation: Even though it accepts an int, it really deals with characters. Based on the ASCII value of the character it will determine if it is an alphabetical character or not.
    10. isdigit()
      Prototype: int isdigit(int ch);
      Header File: ctype.h
      Explanation: This function accepts an ASCII value, and returns whether or not it is a digit (0 to 9) when converted to its equivalent ASCII character. It returns a zero if it is not a digit, and non-zero if it is.
    11. ispunct()
      Prototype: int ispunct (int c);
      Header File: ctype.h
      Explanation: Tests if the ASCII character corresponding to the integer stored in c is a punctuation character.
    12. isspace()
      Prototype: int isspace(int ch);
      Header File: ctype.h
      Explanation: Isspace does exactly what is sounds like, checks if the ASCII value passed in is that of a space key (such as tab, space, newline, etc). It returns non-zero for true, and zero for false.
    13. isupper()
      Prototype: int isupper (int c);
      Header File: ctype.h
      Explanation: Tests to see if the ASCII character associated with the integer c is an uppercase letter.
    14. modf()
      Prototype: double modf(double number, double *intpart);
      Header File: cmath
      Explanation: This function will return the decimal part of number, and it will place the integer part of number into the variable pointed to by intpart.
    15. pow()
      Prototype: double pow(double b, double p);
      Header File: cmath
      Explanation: This function raises b to the p power.
    16. srand()
      Prototype: void srand(unsigned int seed);
      Header File: cstdlib
      Explanation: Srand will seed the random number generator to prevent random numbers from being the same every time the program is executed and to allow more pseudorandomness.
    17. time()
      Prototype: time_t time(time_t* timer);
      Header File: time.h
      ANSI: C and C++
      Explanation: Returns and sets the passed in variable to the number of seconds that have passed since 00:00:00 GMT January 1, 1970. If NULL is passed in, it will work as if it accepted nothing and return the same value.
    18. tolower()
      Prototype: int tolower(int chr);
      Header File: ctype.h
      Explanation: Tolower will return the ASCII value for the lowercase equivalent of the ASCII character chr, if it is a letter. If the character is already lowercase, it remains lowercase
    19. toupper()
      Prototype: int toupper(int aChar);
      Header File: ctype.h and cstdlib
      Explanation: toupper accepts a character as an argument (it actually accepts an integer, but the two are interchangeable) and will convert it to uppercase, and will return the uppercase character, in the form of an ASCII integer, and leave the parameter unchanged.

  10. Code example
    //
    // functions example
    //
    #include <iostream>
    #include <cstdlib>
    #include <cmath>
    #include <time.h>
     
    using namespace std;
    int main()
    {
      // abs example
      {
       int iNum;
       iNum=-1;
       cout << "abs example" << endl;
       cout << iNum << " abs = " << abs(iNum) << endl;
       cout << endl;
      }
      // atof example;
      {
       char ascii[]="3.14159"; // ascii
       float fNum;
       fNum=atof(ascii);
       cout << "ascii -> float example " << endl;
       cout << fNum << endl;
       cout << endl;
      }
      // atoi example
      {
       char ascii1[]="1234";
       char ascii2[]="1234.567";
       int iNum1, iNum2;
       iNum1=atoi(ascii1);
       iNum2=atoi(ascii2);
       cout << "ascii -> integer example " << endl;
       cout << iNum1 << "\t" << iNum2 << endl;
       cout << endl;
      }
      // clock example
      {
       int iStartTic,iEndTic;
       float a,b=7.4,c=3.2;
       iStartTic=clock();
       cout << "clock example" << endl;
       for(int x=0; x<100000000; x++) a=b/c; // waste some time
       iEndTic=clock();
       cout << "Start tic     = " << iStartTic << endl;
       cout << "End tic       = " << iEndTic << endl;
       cout << "Tics          = " << iEndTic - iStartTic << endl;
       cout << "Tics per sec  = " << CLOCKS_PER_SEC << endl;
       cout << "Full seconds  = " << (iEndTic - iStartTic)
                                       / CLOCKS_PER_SEC << endl;
       // CLOCKS_PER_SEC defined in time.h
       cout << endl;
      }
      // ctime example
      {
       time_t hold_time;      // time_t defined in time.h
       hold_time=time(NULL);  // get the current time
       cout << "ctime example " << endl;
       cout << "The date is: " << ctime(&hold_time) << endl;
       cout << endl;
      }
      // fabs example
      {
       float fNum=-3.14159;
       cout << "fabs example " << endl;
       cout << fNum << " fabs = " << fabs(fNum) << endl;
       cout << endl;
      }
      //  floor example
      {
       float fNum=5.9;
       cout << "floor example " << endl;
       cout << fNum << " floor = " << floor(fNum) << endl;
       cout << endl;
      }
      // isalnum example
      {
       cout << "isalnum example " <<  endl;
       cout << "," << (isalnum(',') ? " is " : " is not ") << "alphanumeric " <<endl;
       cout << "a" << (isalnum('a') ? " is " : " is not ") << "alphanumeric " <<endl;
       cout << endl;
      }
      // isalpha example
      {
       cout << "isalpha example " <<  endl;
       cout << "1" << (isalpha('1') ? " is " : " is not ") << "alphabetic " <<endl;
       cout << "a" << (isalpha('a') ? " is " : " is not ") << "alphabetic " <<endl;
       cout << endl;
      }
      // isdigit example
      {
       cout << "isdigit example " <<  endl;
       cout << "0" << (isdigit('0') ? " is " : " is not ") << "digit " <<endl;
       cout << "a" << (isdigit('a') ? " is " : " is not ") << "digit " <<endl;
       cout << endl;
      }
      // islower example
      {
       cout << "islower example " <<  endl;
       cout << "A" << (islower('A') ? " is " : " is not ") << "lower case " <<endl;
       cout << "a" << (isalnum('a') ? " is " : " is not ") << "lower case " <<endl;
       cout << endl << endl;
      }
      // ispunct example
      {
       cout << "ipunct example " <<  endl;
       cout << "," << (ispunct(',') ? " is " : " is not ") << "punctuation" <<endl;
       cout << "a" << (ispunct('a') ? " is " : " is not ") << "punctuation " <<endl;
       cout << endl;
      }
      // isspace example
      {
       cout << "isspace example " <<  endl;
       cout << " " << (isspace(' ') ? " is " : " is not ") << "space " <<endl;
       cout << "a" << (isspace('a') ? " is " : " is not ") << "space " <<endl;
       cout << endl << endl;
      }
      // isupper example
      {
       cout << "isupper example " <<  endl;
       cout << "A" << (isupper('A') ? " is " : " is not ") << "upper case " <<endl;
       cout << "a" << (isupper('a') ? " is " : " is not ") << "upper case " <<endl;
       cout << endl << endl;
      }
      // modf example
      {
       double dNum=123.456;
       double dDecimal,dWhole;
       dDecimal=modf(dNum,&dWhole);
       cout << "modf example " << endl;
       cout << "number          = " << dNum << endl;
       cout << "decimal part    = " << dDecimal << endl;
       cout << "whole part      = " << dWhole << endl;
       cout << endl;
      }
      // pow example
      {
       cout << "pow example " << endl;
       cout << "10.5 rasied to the 4.2 is " << pow(10.5,4.2) << endl;
       cout << endl;
      }
      // srand example
      {
       cout << "srand example " << endl;
       cout << " unseeded sequence ";
       for(int x=0; x < 3 ; x++) cout << rand()%100 << " ";
       cout << endl;
       cout << " seeded   sequence ";
       srand(time(0));
       for(int x=0; x < 3 ; x++) cout << rand()%100 << " ";
       cout << endl;
       cout << endl;
      }
      // time example
      {
       time_t seconds;
       seconds=time(0);
       cout << "time example " << endl;
       cout << seconds << " seconds since 00:00:00 Jan 1, 1970" << endl;
       cout << endl;
      }
      // tolower and toupper example
      {
       cout << "tolower and toupper example" << endl;
       char lChar='a',uChar='A';
       
       cout << lChar << " as upper " << (char)toupper(lChar) << endl;
       cout << uChar << " as lower " << (char)tolower(uChar) << endl;
       cout << endl;
      }
     
      system("pause");
      return 0;
    }
    

  11. Example output
    abs example
    -1 abs = 1
     
    ascii -> float example
    3.14159
     
    ascii -> integer example
    1234    1234
     
    clock example
    Start tic     = 15
    End tic       = 1703
    Tics          = 1688
    Tics per sec  = 1000
    Full seconds  = 1
     
    ctime example
    The date is: Wed Jun 17 12:27:33 2009
     
    
    fabs example
    -3.14159 fabs = 3.14159
     
    floor example
    5.9 floor = 5
     
    isalnum example
    , is not alphanumeric
    a is alphanumeric
     
    isalpha example
    1 is not alphabetic
    a is alphabetic
     
    isdigit example
    0 is digit
    a is not digit
     
    islower example
    A is not lower case
    a is lower case
     
    
    ipunct example
    , is punctuation
    a is not punctuation
     
    isspace example
      is space
    a is not space
     
    
    isupper example
    A is upper case
    a is not upper case
     
    
    modf example
    number          = 123.456
    decimal part    = 0.456
    whole part      = 123
     
    pow example
    10.5 rasied to the 4.2 is 19453.4
     
    srand example
     unseeded sequence 41 67 34
     seeded   sequence 57 63 22
     
    time example
    1245259653 seconds since 00:00:00 Jan 1, 1970
     
    tolower and toupper example
    a as upper A
    A as lower a
     
    Press any key to continue . . .