/---------------------\ | Notes for lecture07 | | 12 October 1999 | | CS 125-609 | | Michael Goldwasser | \---------------------/ ========================================================================= GENERAL PROCEDURES (Chapter 2.6) ========================================================================= PREFACE: The book gives good examples and details about syntax, but it lacks an overall discussion of the concepts. To complement this, my lecture will start with a good overall explanation of the concepts, but will lack examples and details of Visual Basic syntax. ------------------------------------------------------------------------- We have already seen the example of procedures and functions which are built into Visual Basic. For example, Private Sub command1_Click() End Sub Did you know: WE CAN CREATE AND DEFINE OTHER NEW PROCEDURES Generally, it is good to try to define a procedure which will accomplish some specific "task" which you find useful. "It's like having a personal assistant" ------------------------------------------------------------------------- Why does this help? * Can simplify a very long block of code by reorganizing it into natural pieces, and moving chunks of code elsewhere. * More importantly, some tasks need to be executed many different times in a program. By creating a procedure for that task, you only need to specify the details of how to accomplish the task once! -- shorter code -- less chance of typos/mistakes -- if we ever need to change the behavior for the task, we only have to make a change in ONE PLACE of our program ------------------------------------------------------------------------- Examples: ----------------------------- Private Sub ReadDataFromFile() End Sub ----------------------------- Private Sub DisplayResults() End Sub ----------------------------- ------------------------------------------------------------------------- You can even write procedures which call other procedures (which call other procedures...) ------------------------------------------------------------------------- How does this work? When you call a procedure, that part of your code execution is temporarily put on hold while the procedure runs. When the procedure is finally complete, the code which originally called the procedure continues from where it left off. ***Suggested Exercise*** step through such a program with the debugger What if procedures call other procedures and so on...? Answer: The computer keeps track of all the placeholders in a "stack" (like a pushdown stack of plates/trays in a cafeteria) ========================================================================= WHAT ARE ALL OF THOSE PARENTHESES FOR? Sometimes you can define a nice, logical task, but the precise behavior depends on a few variables. e.g. ReadDataFromFile --- Which file???? So we can define a procedure which takes one or more "parameters" e.g. Private Sub ReadDataFromFile(dataname As String) End Sub *** Hey! -- we already saw this in a way. Remember how event handlers *** for a control array receive the "Index" parameter? ------------------------------------------------------------------------- Question: How does this work? Answer: There are really two ways! -- pass by value (ByVal) -- pass by reference (ByRef) Abstract Example: let's say that you want someone to create a poster which has your bank account value on it. You could either: (1) write down the dollar amount of your bank account value and pass this piece of paper to the person making the poster (2) give this person your bank account number and have them call and get your balance (1) is passing them the balance "by value" (2) is passing them the balance "by reference" Okay..on a computer, things are much clearer than the above example. Passing by value will pass a copy of the value of the data, whereas passing by reference will pass a reference to YOUR OWN variable location. ------------------------------------------------------------------------- What is the difference? Why use one method versus the other? Issues: * Which is easier to pass? -- probably easier to pass the value of an integer, rather than passing a reference to where the person can find the value. -- but if passing a very long string, it is probably easier (i.e. less data) to pass a reference to the string, rather than a copy of all the characters in the string. * Can you pass an expression rather than a variable? -- Yes, but it will automatically be passed by value! OutputNumber(x+5) * What if the procedure you call tries to CHANGE the value of your variable? -- if you pass by value, this cannot happen! -- if you pass by reference, this is possible (did you really want it this way?) ========================================================================= GETTING INFORMATION BACK FROM A PROCEDURE Sometimes procedures just do things, but sometimes you want them to also give you some feedback. -- by passing variables by reference, you already have a way to have the procedure give you information. They can change your variables. (in fact, you can even have some arguments which contained junk going into the procedure, but get set to meaningful values from within the procedure) -- since it is very common programming technique to define a procedure which gives back EXACTLY ONE result, there is a special type of procedure called a Function to do this. -------- In fact, we have already seen some functions defined by Visual Basic: Val("1034") ' takes a String parameter and returns a Single Sqr(9) ' takes a Single parameter and returns a Single FormatNumber(14/3, 3) ' takes a Single and an Integer, returns a String ========================================================================= Visual Basic Syntax: * subroutines (general procedures) Here is an example of how to define a subroutine: Private Sub DisplaySum(ByVal num1 As Single, ByVal num2 As Single) End Sub Another example would be Private Sub SetValues(ByRef X As Integer, ByRef Y As Integer) End Sub Within this procedure, you may now use the arguments "num1" and "num2", or arguments "X" and "Y" just as if they were standard variables. The names used within the procedure are local, and have nothing to do with the names used for these parameters by the caller. Of course, they will either be "pseudonyms" for variables in the calling procedure (if passed by reference), or they will be new local variables created and initialized with the parameter value (if passed by value). *************************************** The default in Visual Basic is to define arguments to be passed ByRef *************************************** To call a procedure from elsewhere in the code, you may use either of the following two syntaxes: Call DisplaySum(X,5) DisplaySum X, 5 Your parameters will automatically get passed ByRef or ByVal depending on the definition of the procedure. If there are no parameters, you can omit the parenthesis completely: Call SetDefaults HOWEVER --- There is a slight exception to the rule. If a procedure defines an argument to be passed ByVal, it will always be passed ByVal. But if an argument is defined to be passed ByRef, and yet you use an "expression" when calling the procedure, this will end up getting passed by value! That is, if you say: Call Sample(X, X+5) for a procedure Sample which asks for two parameter ByRef, the first one will indeed be passed by ByRef, however the second one will get passed ByVal instead. (after all, there is no variable currently holding the expression X+5, so what reference would it pass?) Finally, if you are calling a procedure which asks for arguments to be passed ByRef, but you wish to absolutely disallow the possibility of the procedure modifying your variable, you may outsmart it by placing an extra set of parenthesis around your variable. That is if you say, Call Sample(X,(Y)) Your variable X will be sent ByRef however (Y) will be read as an expression rather than the original variable, and so it will be passed ByVal. ------------------------------------------------------------------------- * functions Here is an example of how to define a function: Private Function Square(ByVal num As Single) As Single Square = num*num End Function The syntax for listing arguments is identical to with general procedures Notice three differences: - the word "Sub" is replaced by the word "Function" - the data type which is returned by the function is specified in the function definition (e.g. "As Single") - The return value is set within the function by assigning a value to the symbolic name of the function (e.g. "Square = num*num") To call a function from elsewhere uses a different syntax. You can place the expression "Square(5)" anywhere in your code where you could normally use a value of that type. For example, picture1.Print Square(5) result = 2 * Square(X) Fourth = Square( Square(num) ) ' will evaluate to num^4 =========================================================================