C Tutor chapter 5

                    Chapter 5 - Functions and variables


                      OUR FIRST USER DEFINED FUNCTION

             Load  and examine the file SUMSQRES.C for an example of

        a C program with functions.   Actually this is not the first

        function  we have encountered because the "main" program  we

        have been using all along is technically a function,  as  is

        the  "printf" function.   The "printf" function is a library

        function that was supplied with your compiler.

             Notice the executable part of this program.   It begins

        with a line that simply says "header()", which is the way to

        call any function.  The parentheses are required because the

        C compiler uses them to determine that it is a function call

        and not simply a misplaced variable.  When the program comes

        to this line of code, the function named "header" is called,

        its  statements  are executed,  and control returns  to  the

        statement  following this call.   Continuing on we come to a

        "for"  loop which will be executed 7 times and  which  calls

        another  function named "square" each time through the loop,

        and  finally  a function named "ending" will be  called  and

        executed.    For  the  moment  ignore  the  "index"  in  the

        parentheses of the call to "square".  We have seen that this

        program  therefore calls a header,  7 square calls,  and  an

        ending. Now we need to define the functions.

                           DEFINING THE FUNCTIONS

             Following the main program you will see another program

        that  follows all of the rules set forth so far for a "main"

        program  except that it is named "header()".   This  is  the

        function which is called from within the main program.  Each

        of  these  statements are executed,  and when they  are  all

        complete, control returns to the main program.

             The  first  statement sets the variable "sum" equal  to

        zero because we will use it to accumulate a sum of  squares. 

        Since  the  variable  "sum" is defined as  an  integer  type

        variable  prior to the main program,  it is available to  be

        used  in  any of the following functions.   It is  called  a

        "global" variable,  and it's scope is the entire program and

        all  functions.   More  will  be  said about  the  scope  of

        variables  at the end of this chapter.   The next  statement

        outputs  a header message to the monitor.   Program  control

        then  returns  to  the  main  program  since  there  are  no

        additional statements to execute in this function.

             It should be clear to you that the two executable lines

        from  this  function  could be moved to  the  main  program,

        replacing the header call,  and the program would do exactly

        the same thing that it does as it is now written.  This does

        not minimize the value of functions,  it merely  illustrates



                                  Page 29   









                    Chapter 5 - Functions and variables


        the operation of this simple function in a simple way.   You

        will find functions to be very valuable in C programming.

                       PASSING A VALUE TO A FUNCTION

             Going  back  to the main program,  and the  "for"  loop

        specifically,  we find the new construct from the end of the

        last  lesson used in the last part of the for  loop,  namely

        the "index++".   You should get used to seeing this,  as you

        will see it a lot in C programs.

             In the call to the function "square",  we have an added

        feature, namely the variable "index" within the parentheses. 

        This  is  an indication to the compiler that when you go  to

        the function,  you wish to take along the value of index  to

        use in the execution of that function.  Looking ahead at the

        function  "square",  we  find that another variable name  is

        enclosed in its parentheses,  namely the variable  "number". 

        This  is  the name we prefer to call the variable passed  to

        the  function when we are in the function.   We can call  it

        anything  we wish as long as it follows the rules of  naming

        an identifier.   Since the function must know what type  the

        variable  is,  it is defined following the function name but

        before the opening brace of the function itself.   Thus, the

        line  containing "int number;" tells the function  that  the

        value  passed to it will be an integer type variable.   With

        all of that out of the way,  we now have the value of  index

        from  the main program passed to the function "square",  but

        renamed "number", and available for use within the function.

             Following the opening brace of the function,  we define

        another  variable "numsq" for use only within  the  function

        itself,  (more  about  that  later)  and  proceed  with  the

        required  calculations.   We set "numsq" equal to the square

        of  number,  then add numsq to the current total  stored  in

        "sum".   Remember  that "sum += numsq" is the same as "sum =

        sum + numsq" from the last lesson.   We print the number and

        its square, and return to the main program.

                  MORE ABOUT PASSING A VALUE TO A FUNCTION

             When we passed the value of "index" to the function,  a

        little  more  happened  than meets  the  eye.   We  did  not

        actually  pass  the  value  of index  to  the  function,  we

        actually  passed  a  copy of the value.   In  this  way  the

        original value is protected from accidental corruption by  a

        called  function.   We  could  have  modified  the  variable

        "number" in any way we wished in the function "square",  and

        when we returned to the main program, "index" would not have

        been  modified.   We thus protect the value of a variable in

        the main program from being accidentally corrupted,  but  we



                                  Page 30   









                    Chapter 5 - Functions and variables


        cannot  return  a value to the main program from a  function

        using this technique.  We will find a well defined method of

        returning  values  to  the main program or  to  any  calling

        function  when we get to arrays and another method  when  we

        get  to pointers.   Until then the only way you will be able

        to  communicate  back to the calling function will  be  with

        global  variables.    We  have  already  hinted  at   global

        variables  above,  and will discuss them in detail later  in

        this chapter.

             Continuing  in  the main program,  we come to the  last

        function call, the call to "ending".  This call simply calls

        the last function which has no local variables defined.   It

        prints out a message with the value of "sum" contained in it

        to  end the program.   The program ends by returning to  the

        main  program and finding nothing else to do.   Compile  and

        run this program and observe the output.

                        NOW TO CONFESS A LITTLE LIE

             I told you a short time ago that the only way to get  a

        value  back to the main program was through use of a  global

        variable,  but  there  is another way which we will  discuss

        after  you load and display the file  named  SQUARES.C.   In

        this  file we will see that it is simple to return a  single

        value  from a called function to the calling function.   But

        once again,  it is true that to return more than one  value,

        we will need to study either arrays or pointers.

             In the main program, we define two integers and begin a

        "for"  loop  which  will be executed  8  times.   The  first

        statement  of the for loop is "y = squ(x);",  which is a new

        and rather strange looking construct.  From past experience,

        we  should have no trouble understanding that  the  "squ(x)"

        portion  of  the statement is a call to the  "squ"  function

        taking along the value of "x" as a variable.   Looking ahead

        to  the function itself we find that the function prefers to

        call  the variable "in" and it proceeds to square the  value

        of "in" and call the result "square".   Finally,  a new kind

        of a statement appears,  the "return" statement.   The value

        within  the parentheses is assigned to the  function  itself

        and  is  returned  as a usable value in  the  main  program. 

        Thus,  the  function call "squ(x)" is assigned the value  of

        the square and returned to the main program such that "y" is

        then  set  equal  to  that value.   If  "x"  were  therefore

        assigned the value 4 prior to this call,  "y" would then  be

        set to 16 as a result of this line of code.

             Another  way  to  think  of this  is  to  consider  the

        grouping  of characters "squ(x)" as another variable with  a

        value  that is the square of "x",  and this new variable can



                                  Page 31   









                    Chapter 5 - Functions and variables


        be used any place it is legal to use a variable of its type. 

        The values of "x" and "y" are then printed out.

             To  illustrate  that the grouping of  "squ(x)"  can  be

        thought  of as just another variable,  another "for" loop is

        introduced in which the function call is placed in the print

        statement rather than assigning it to a new variable.

             One  last  point must be made,  the  type  of  variable

        returned must be defined in order to make sense of the data,

        but the compiler will default the type to integer if none is

        specified.   If  any  other  type is  desired,  it  must  be

        explicitly defined.   How to do this will be demonstrated in

        the next example program.

             Compile and run this program.

                            FLOATING POINT FUNCTIONS

             Load the program FLOATSQ.C for an example of a function

        with a floating point type of return.  It begins by defining

        a global floating point variable we will use later.  Then in

        the  "main"  part  of the program,  an integer  is  defined,

        followed  by two floating point variables,  and then by  two

        strange  looking definitions.   The expressions "sqr()"  and

        "glsqr()"  look like function calls and they are.   This  is

        the proper way in C to define that a function will return  a

        value that is not of the type "int", but of some other type,

        in  this case "float".   This tells the compiler that when a

        value  is returned from either of these  two  functions,  it

        will be of type "float".

             Now  refer to the function "sqr" near the center of the

        listing and you will see that the function name is  preceded

        by the name "float".   This is an indication to the compiler

        that  this  function will return a value of type "float"  to

        any program that calls it.   The function is now  compatible

        with  the call to it.   The line following the function name

        contains  "float inval;",  which indicates to  the  compiler

        that  the variable passed to this function from the  calling

        program will be of type "float".

             The next function,  namely "glsqr",  will also return a

        "float"  type  variable,  but it uses a global variable  for

        input.   It  also does the squaring right within the  return

        statement  and  therefore has no need to define  a  separate

        variable to store the product.

             The  overall structure of this program should  pose  no

        problem and will not be discussed in any further detail.  As





                                  Page 32   









                    Chapter 5 - Functions and variables


        is customary with all example programs, compile and run this

        program.

             There  will  be times that you will have a need  for  a

        function   to   return  a  pointer  as  a  result  of   some

        calculation.  There is a way to define a function so that it

        does  just that.   We haven't studied pointers yet,  but  we

        will soon.  This is just a short preview of things to come.

                             SCOPE OF VARIABLES

             Load the next program,  SCOPE.C,  and display it for  a

        discussion of the scope of variables in a program.

             The first variable defined is a global variable "count"

        which  is available to any function in the program since  it

        is defined before any of the functions.   In addition, it is

        always  available  because  it does not come and go  as  the

        program  is  executed.   (That  will  make  sense  shortly.)

        Farther down in the program,  another global variable  named

        "counter"  is  defined  which  is also  global  but  is  not

        available  to the main program since it is defined following

        the main program.  A global variable is any variable that is

        defined  outside of any function.   Note that both of  these

        variables  are sometimes referred to as  external  variables

        because they are external to any functions.

             Return  to  the  main  program and  you  will  see  the

        variable  "index"  defined as an integer.   Ignore the  word

        "register" for the moment.   This variable is only available

        within the main program because that is where it is defined. 

        In addition, it is an "automatic" variable, which means that

        it  only comes into existence when the function in which  it

        is  contained  is  invoked,  and ceases to  exist  when  the

        function  is  finished.   This  really  means  nothing  here

        because the main program is always in operation,  even  when

        it  gives  control to another function.  Another integer  is

        defined  within  the  "for"  braces,  namely  "stuff".   Any

        pairing  of braces can contain a variable  definition  which

        will  be  valid  and  available only while  the  program  is

        executing statements within those braces.  The variable will

        be  an  "automatic" variable and will cease  to  exist  when

        execution leaves the braces.   This is convenient to use for

        a loop counter or some other very localized variable.

                       MORE ON "AUTOMATIC" VARIABLES

             Observe  the  function named "head1".   It  contains  a

        variable  named  "index",  which has nothing to do with  the

        "index" of the main program,  except that both are automatic

        variables.   When  the  program is  not  actually  executing



                                  Page 33   









                    Chapter 5 - Functions and variables


        statements  in  this function,  this variable named  "index"

        does not even exist.   When "head1" is called,  the variable

        is  generated,  and  when "head1" completes  its  task,  the

        variable  "index" is eliminated completely  from  existence. 

        Keep  in mind however that this does not affect the variable

        of  the  same  name  in the main  program,  since  it  is  a

        completely separate entity.

             Automatic   variables  therefore,   are   automatically

        generated and disposed of when needed.   The important thing

        to remember is that from one call to a function to the  next

        call,  the  value of an automatic variable is not  preserved

        and must therefore be reinitialized.

                         WHAT ARE STATIC VARIABLES?

             An  additional variable type must be mentioned at  this

        point,  the "static" variable.  By putting the reserved word

        "static"  in  front  of  a  variable  declaration  within  a

        function,  the variable or variables in that declaration are

        static  variables  and will stay in existence from  call  to

        call  of  the  particular function. 

             By  putting  the  same reserved word  in  front  of  an

        external variable, one outside of any function, it makes the

        variable  private  and  not accessible to use in  any  other

        file.  This implies that it is possible to refer to external

        variables  in other separately compiled files,  and that  is

        true.  Examples of this usage will be given in chapter 14 of

        this tutorial.

                         USING THE SAME NAME AGAIN

             Refer  to  the  function named  "head2".   It  contains

        another  definition  of the variable  named  "count".   Even

        though  "count"  has  already  been  defined  as  a   global

        variable,  it  is  perfectly all right to reuse the name  in

        this  function.   It is a completely new variable  that  has

        nothing to do with the global variable of the same name, and

        causes  the  global  variable  to  be  unavailable  in  this

        function.   This allows you to write programs using existing

        functions  without worrying about what names were  used  for

        variables in the functions because there can be no conflict. 

        You  only  need to worry about the variables that  interface

        with the functions.

                        WHAT IS A REGISTER VARIABLE?

             Now  to  fulfill  a promise made earlier about  what  a

        register  variable  is.   A  computer can  keep  data  in  a

        register  or  in  memory.   A  register is  much  faster  in



                                  Page 34   









                    Chapter 5 - Functions and variables


        operation  than  memory  but there are  very  few  registers

        available for the programmer to use.   If there are  certain

        variables  that are used extensively in a program,  you  can

        designate  that  those  variables  are to  be  stored  in  a

        register  if possible in order to speed up the execution  of

        the program.   Depending on the computer and the compiler, a

        small  number  of register variables may be allowed and  are

        designated  by putting the word "register" in front  of  the

        desired variable.  Check your compiler documentation for the

        availability  of  this  feature and the number  of  register

        variables.   Most  compilers that do not have  any  register

        variables available,  will simply ignore the word "register"

        and run normally, keeping all variables in memory.

             Register  variables  are only available  for  use  with

        integer  and character type variables.   This may or may not

        include  some  of the other integer-like variables  such  as

        unsigned,  long, or short.  Check the documentation for your

        compiler.

                        WHERE DO I DEFINE VARIABLES?

             Now for a refinement on a general rule stated  earlier. 

        When  you have variables brought to a function as  arguments

        to  the  function,  they are defined immediately  after  the

        function  name  and  prior  to the  opening  brace  for  the

        program.   Other  variables used in the function are defined

        at the beginning of the function,  immediately following the

        opening  brace of the function,  and before  any  executable

        statements.

                         STANDARD FUNCTION LIBRARIES

             Every  compiler  comes  with some  standard  predefined

        functions  which  are available for  your  use.   These  are

        mostly   input/output   functions,   character  and   string

        manipulation functions,  and math functions.   We will cover

        most of these in subsequent chapters.

             In addition,  most compilers have additional  functions

        predefined that are not standard but allow the programmer to

        get the most out of his particular computer.  In the case of

        the  IBM-PC and compatibles,  most of these functions  allow

        the  programmer  to use the BIOS services available  in  the

        operating system,  or to write directly to the video monitor

        or to any place in memory.  These will not be covered in any

        detail  as  you will be able to study the unique aspects  of

        your compiler on your own.  Many of these kinds of functions

        are used in the example programs in chapter 14.





                                  Page 35   









                    Chapter 5 - Functions and variables


                             WHAT IS RECURSION?

             Recursion  is another of those  programming  techniques

        that  seem very intimidating the first time you come  across

        it,  but  if  you will load and display the example  program

        named RECURSON.C, we will take all of the mystery out of it. 

        This  is probably the simplest recursive program that it  is

        possible  to write and it is therefore a stupid  program  in

        actual  practice,  but for purposes of illustration,  it  is

        excellent.

             Recursion  is  nothing more than a function that  calls

        itself.   It is therefore in a loop which must have a way of

        terminating.   In the program on your monitor,  the variable

        "index"  is  set to 8,  and is used as the argument  to  the

        function  "count_dn".   The function simply  decrements  the

        variable, prints it out in a message, and if the variable is

        not  zero,  it calls itself,  where it decrements it  again,

        prints it,  etc.  etc. etc. Finally, the variable will reach

        zero,  and the function will not call itself again. Instead,

        it  will  return  to the prior time it  called  itself,  and

        return  again,  until  finally it will return  to  the  main

        program and will return to DOS.

             For  purposes  of understanding you can think of it  as

        having 8 copies of the function "count_dn" available and  it

        simply  called all of them one at a time,  keeping track  of

        which  copy it was in at any given time.   That is not  what

        actually  happened,  but it is a reasonable illustration for

        you to begin understanding what it was really doing.

                              WHAT DID IT DO?

             A  better explanation of what actually happened  is  in

        order.   When you called the function from itself, it stored

        all  of the variables and all of the internal flags it needs

        to  complete the function in a block  somewhere.   The  next

        time it called itself,  it did the same thing,  creating and

        storing  another  block of everything it needed to  complete

        that  function call.   It continued making these blocks  and

        storing them away until it reached the last function when it

        started  retrieving the blocks of data,  and using  them  to

        complete  each function call.   The blocks were stored on an

        internal part of the computer called the "stack".  This is a

        part  of  memory carefully organized to store data  just  as

        described above.  It is beyond the scope of this tutorial to

        describe the stack in detail,  but it would be good for your

        programming  experience to read some material describing the

        stack.   A stack is used in nearly all modern computers  for

        internal housekeeping chores.




                                  Page 36   









                    Chapter 5 - Functions and variables


             In using recursion,  you may desire to write a  program

        with  indirect recursion as opposed to the direct  recursion

        described  above.    Indirect  recursion  would  be  when  a

        function  "A"  calls the function "B",  which in turn  calls

        "A",  etc.   This is entirely permissible,  the system  will

        take  care of putting the necessary things on the stack  and

        retrieving  them when needed again.   There is no reason why

        you  could not have three functions calling each other in  a

        circle,  or four,  or five,  etc.   The C compiler will take

        care of all of the details for you.

             The thing you must remember about recursion is that  at

        some  point,  something  must  go to  zero,  or  reach  some

        predefined  point to terminate the loop.   If not,  you will

        have  an  infinite  loop,  and the stack will  fill  up  and

        overflow,  giving  you  an error and  stopping  the  program

        rather abruptly.

                        ANOTHER EXAMPLE OF RECURSION

             The  program  named  BACKWARD.C is another  example  of

        recursion,  so load it and display it on your screen.   This

        program  is  similar to the last one except that it  uses  a

        character array.  Each successive call to the function named 

        "forward_and_backward"  causes one character of the  message

        to be printed.   Additionally,  each time the function ends,

        one of the characters is printed again,  this time backwards

        as the string of recursive function calls is retraced.

             Don't worry about the character array defined in line 3

        or  the  other  new  material  presented  here.   After  you

        complete chapter 7 of this tutorial,  this program will make

        sense.   It  was  felt that introducing a second example  of

        recursion was important so this file is included here.

             One additional feature is built into this program.   If

        you observe the two calls to the function,  and the function

        itself, you will see that the function name is spelled three

        different  ways in the last few  characters.   The  compiler

        doesn't  care how they are spelled because it only uses  the

        first  8 characters of the function name so as far as it  is

        concerned,  the function is named "forward_".  The remaining

        characters  are simply ignored.   If your compiler uses more

        that  8 characters as being significant,  you will  need  to

        change  two  of  the  names  so that  all  three  names  are

        identical.

             Compile and run this program and observe the results.






                                  Page 37   









                    Chapter 5 - Functions and variables


        PROGRAMMING EXERCISES

        1.   Rewrite  TEMPCONV.C,  from an earlier chapter, and move

             the temperature calculation to a function.

        2.   Write a program that writes your name on the monitor 10

             times by calling a function to do the writing. Move the

             called function ahead of the "main" function to see  if

             your compiler will allow it.












































                                  Page 38   

Comments

Popular posts from this blog

BOTTOM LIVE script

Fawlty Towers script for "A Touch of Class"