06 - Methods

65
© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01 6 Methods Objectives To understand how to construct programs modularly from small pieces called methods. To introduce the common math methods available in the .NET Framework Library. To be able to create new methods. To understand the mechanisms used to pass information between methods. To introduce simulation techniques using random number generation. To understand how the visibility of identifiers is limited to specific regions of programs. To understand how to write and use methods that call themselves. Form ever follows function. Louis Henri Sullivan E pluribus unum. (One composed of many.) Virgil O! call back yesterday, bid time return. William Shakespeare, Richard II Call me Ishmael. Herman Melville, Moby Dick When you call me that, smile. Owen Wister

Transcript of 06 - Methods

Page 1: 06 - Methods

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

6Methods

Objectives• To understand how to construct programs modularly

from small pieces called methods.• To introduce the common math methods available in

the .NET Framework Library.• To be able to create new methods.• To understand the mechanisms used to pass

information between methods.• To introduce simulation techniques using random

number generation.• To understand how the visibility of identifiers is

limited to specific regions of programs.• To understand how to write and use methods that call

themselves.Form ever follows function.Louis Henri Sullivan

E pluribus unum.(One composed of many.)Virgil

O! call back yesterday, bid time return.William Shakespeare, Richard II

Call me Ishmael.Herman Melville, Moby Dick

When you call me that, smile.Owen Wister

Page 2: 06 - Methods

260 Methods Chapter 6

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

6.1 IntroductionMost computer programs that solve real-world problems are much larger than the programspresented in the first few chapters. Experience has shown that the best way to develop andmaintain a large program is to construct it from small, simple pieces or modules. This tech-nique is called divide and conquer. This chapter describes many key features of the C# lan-guage that facilitate the design, implementation, operation and maintenance of largeprograms.

6.2 Program Modules in C#Modules in C# are called methods and classes. C# programs are written by combining newmethods and classes the programmer writes with “prepackaged” methods and classes avail-able in the .NET Framework Library (also called the Base Class Library or BCL) and invarious other method and class libraries. In this chapter, we concentrate on methods; wewill discuss classes in detail beginning with Chapter 8.

The .NET Framework Library provides a rich collection of classes and methods forperforming common mathematical calculations, string manipulations, character manipula-tions, input/output, error checking and many other useful operations. This makes the pro-grammer’s job easier because these methods provide many of the capabilities programmersneed. The .NET Framework methods are provided as part of the .NET Framework.

Outline

6.1 Introduction6.2 Program Modules in C#6.3 Math Class Methods6.4 Methods6.5 Method Definitions6.6 Passing Arguments: Call-by-Value vs. Call-by-Reference6.7 Random Number Generation6.8 Example: Game of Chance6.9 Duration of Identifiers6.10 Scope Rules6.11 Recursion6.12 Example Using Recursion: The Fibonacci Series6.13 Recursion vs. Iteration6.14 Method Overloading

Summary • Terminology • Self-Review Exercises • Answers to Self-Review Exercises • Exercises

Page 3: 06 - Methods

Chapter 6 Methods 261

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

Good Programming Practice 6.1Familiarize yourself with the rich collection of classes and methods in the .NET Frameworkand with the rich collections of classes available in various class libraries. 6.1

Software Engineering Observation 6.1Avoid reinventing the wheel. When possible, use .NET Framework classes and methods in-stead of writing new classes and methods. This reduces program development time andavoids introducing new errors. 6.1

Portability Tip 6.1Using the methods in the .NET Framework helps make programs more portable. 6.1

Performance Tip 6.1Do not try to rewrite existing .NET Framework classes and methods to make them more ef-ficient. You usually will not be able to increase the performance of these classes and methods. 6.1

The programmer can write methods to define specific tasks that may be used at manypoints in a program. These are sometimes referred to as programmer-defined methods. Theactual statements defining the method are written only once and these statements are hiddenfrom other methods.

A method is invoked (i.e., made to perform its designated task) by a method call. Themethod call specifies the method name and provides information (as arguments) that thecalled method needs to do its task. A common analogy for this is the hierarchical form ofmanagement. A boss (the calling method or caller) asks a worker (the called method) toperform a task and return (i.e., report back) the results when the task is done. The bossmethod does not know how the worker method performs its designated tasks. The workermay call other worker methods and the boss will be unaware of this. We will soon see howthis “hiding” of implementation details promotes good software engineering. Figure 6.1shows the boss method communicating with several worker methods in a hierarchicalmanner. Note that worker1 acts as a “boss” method to worker4 and worker5. Rela-tionships among methods may be other than the hierarchical structure shown in this figure.

6.3 Math Class MethodsMath class methods allow the programmer to perform certain common mathematical cal-culations. We use various Math class methods here to introduce the concept of methods.Throughout the book, we discuss many other methods from the classes of the .NET Frame-work.

Methods are called by writing the name of the method followed by a left parenthesisfollowed by the argument (or a comma-separated list of arguments) of the method followedby a right parenthesis. For example, a programmer desiring to calculate and print the squareroot of 900.0 might write

Console.WriteLine( Math.Sqrt( 900.0 ) );

Page 4: 06 - Methods

262 Methods Chapter 6

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

When this statement is executed, the method Math.Sqrt is called to calculate the squareroot of the number contained in the parentheses (900.0). The number 900.0 is the argu-ment of the Math.Sqrt method. The preceding statement would print 30.0. TheMath.Sqrt method takes an argument of type double and returns a result of type dou-ble. Note that all Math class methods must be invoked by preceding the method namewith the class name Math and a dot (.) operator. Our Main methods defined in previousexamples have been called automatically or have been called using the syntax class namefollowed by a dot (.) operator followed by a method name like the Math methods (e.g.,Int32.FromString, Double.Format and MessageBox.Show). Normally, mostmethods in C# are invoked through a reference to an object as in the following line of codefrom an application:

string1.CompareTo( string2 );

This statement might appear in your application’s Main method. The statement invokes theCompareTo method of the String object to which string1 refers (also referred to assending the CompareTo message to object to which string1 refers). In Chapter 8, wediscuss in detail the different types of methods associated with classes and how they areinvoked.

Software Engineering Observation 6.2It is not necessary to import the Math class into a program to use Math class methods. TheMath class is part of the System namespace which is automatically included by the com-piler. 6.2

Common Programming Error 6.1Forgetting to invoke a Math class method by preceding the method name with the class nameMath and a dot operator (.) results in a syntax error. 6.1

Method arguments may be constants, variables or expressions. If c1 = 13.0, d = 3.0and f = 4.0, then the statement

Console.WriteLine( Math.Sqrt( c1 + d * f ) );

calculates and prints the square root of 13.0 + 3.0 * 4.0 = 25.0, namely 5.0.

Fig. 6.1Fig. 6.1Fig. 6.1Fig. 6.1 Hierarchical boss method/worker method relationship.

boss

worker1 worker2 worker3

worker4 worker5

Page 5: 06 - Methods

Chapter 6 Methods 263

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

Some Math class methods are summarized in Fig. 6.2. In the figure, the variables xand y are of type double, however many of the methods provide versions that take valuesof other data types as arguments. The Math class also defines two commonly used mathe-matical constants—Math.PI and Math.E. The constant Math.PI(3.1415926535897931) of class Math is the ratio of a circle’s circumference to its diam-eter. The constant Math.E (2.7182818284590451) is the base value for natural logarithms(calculated with the Math.Log method).

Method Description Example

Abs( x ) absolute value of x if x > 0 then Abs( x ) is x if x = 0 then Abs( x ) is 0 if x < 0 then Abs( x ) is -x

Ceiling( x ) rounds x to the smallest integer not less than x

Ceil( 9.2 ) is 10.0Ceil( -9.8 ) is -9.0

Cos( x ) trigonometric cosine of x(x in radians)

Cos( 0.0 ) is 1.0

Exp( x ) exponential method ex Exp( 1.0 ) is 2.7182818284590451Exp( 2.0 ) is 7.38905609893065

Floor( x ) rounds x to the largest integer not greater than x

Floor( 9.2 ) is 9.0Floor( -9.8 ) is -10.0

Log( x ) natural logarithm of x (base e) Log( 2.7182818284590451 )is 1.0Log( 7.38905609893065 ) is 2.0

Max( x, y ) larger value of x and y (this method also has versions for float, int and long val-ues)

Max( 2.3, 12.7 ) is 12.7Max( -2.3, -12.7 ) is -2.3

Min( x, y ) smaller value of x and y (this method also has versions for float, int and long val-ues)

Min( 2.3, 12.7 ) is 2.3Min( -2.3, -12.7 ) is -12.7

Pow( x, y ) x raised to power y (xy) Pow( 2.0, 7.0 ) is 128.0Pow( 9.0, .5 ) is 3.0

Sin( x ) trigonometric sine of x (x in radians)

Sin( 0.0 ) is 0.0

Sqrt( x ) square root of x Sqrt( 900.0 ) is 30.0Sqrt( 9.0 ) is 3.0

Tan( x ) trigonometric tangent of x (x in radians)

Tan( 0.0 ) is 0.0

Fig. 6.2Fig. 6.2Fig. 6.2Fig. 6.2 Commonly used Math class methods.

Page 6: 06 - Methods

264 Methods Chapter 6

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

6.4 MethodsMethods allow the programmer to modularize a program. All variables declared in methoddefinitions are local variables—they are known only in the method in which they are de-fined. Most methods have a list of parameters that provide the means for communicatinginformation between methods via method calls. A method’s parameters are also local vari-ables.

There are several motivations for modularizing a program with methods. The divide-and-conquer approach makes program development more manageable. Another motivationis software reusability—using existing methods as building blocks to create new programs.With good method naming and definition, programs can be created from standardizedmethods rather than being built by using customized code. For example, we did not have todefine how to convert strings to integers—such methods are already defined for us inclass Convert ( ToInt32 ). With more programming experience, it will become clearthat several classes in the .NET Framework contain a similar function. A third motivationis to avoid repeating code in a program. Packaging code as a method allows that code to beexecuted from several locations in a program by calling the method.

Software Engineering Observation 6.3Each method should be limited to performing a single, well-defined task, and the methodname should effectively express that task. This promotes software reusability. 6.3

Software Engineering Observation 6.4If you cannot choose a concise name that expresses what the method does, it is possible thatyour method is attempting to perform too many diverse tasks. It is usually best to break sucha method into several smaller methods. 6.4

6.5 Method DefinitionsEach program we have presented has consisted of a class definition that contained at leastone method definition that called .NET Framework Library methods to accomplish itstasks. We now consider how programmers write their own customized methods.

Consider a Windows application (Fig. 6.3) that uses a method Square (invoked fromthe applications’s Main method) to calculate the squares of the integers from 1 to 10

1 // Fig. 6.3: SquareInt.cs2 // A programmer-defined Square method.34 using System;5 using System.Drawing;6 using System.Collections;7 using System.ComponentModel;8 using System.Windows.Forms;9 using System.Data;

1011 namespace SquareIntSpace12 {13 /// <summary>

Fig. 6.3Fig. 6.3Fig. 6.3Fig. 6.3 Using programmer-defined method SquareInt. (part 1 of 3)

Page 7: 06 - Methods

Chapter 6 Methods 265

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

14 /// Summary description for Form1.15 /// </summary>16 public class SquareInt : System.Windows.Forms.Form17 {18 /// <summary>19 /// Required designer variable.20 /// </summary>21 private System.ComponentModel.Container components = null;22 private System.Windows.Forms.Label outputLabel;2324 public SquareInt()25 {26 //27 // Required for Windows Form Designer support28 //29 InitializeComponent();3031 //32 // TODO: Add any constructor code after InitializeComponent33 // call3435 int result;3637 for ( int x = 1; x <= 10; x++ )38 {39 result = square( x );40 outputLabel.Text += "The square of " + x + " is " +41 result + "\n";42 }43 }4445 /// <summary>46 /// Clean up any resources being used.47 /// </summary>48 protected override void Dispose( bool disposing )49 {50 if( disposing )51 {52 if ( components != null ) 53 {54 components.Dispose();55 }56 }57 base.Dispose( disposing );58 }5960 #region Windows Form Designer generated code61 /// <summary>62 /// Required method for Designer support - do not modify63 /// the contents of this method with the code editor.64 /// </summary>65 private void InitializeComponent()66 {67 this.outputLabel = new System.Windows.Forms.Label();

Fig. 6.3Fig. 6.3Fig. 6.3Fig. 6.3 Using programmer-defined method SquareInt. (part 2 of 3)

Page 8: 06 - Methods

266 Methods Chapter 6

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

When the application begins execution, its Main method is called first. As in our Win-dows application from Chapter 4, we create a label called outputLabel. Every label

68 this.SuspendLayout();69 // 70 // outputLabel71 // 72 this.outputLabel.Location = new System.Drawing.Point(8, 8);73 this.outputLabel.Name = "outputLabel";74 this.outputLabel.Size = new System.Drawing.Size(176, 136);75 this.outputLabel.TabIndex = 0;76 // 77 // SquareInt78 // 79 this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);80 this.ClientSize = new System.Drawing.Size(192, 149);81 this.Controls.AddRange(new System.Windows.Forms.Control[] 82 {this.outputLabel});83 this.Name = "SquareInt";84 this.Text = "SquareInt";85 this.ResumeLayout(false);8687 }88 #endregion8990 /// <summary>91 /// The main entry point for the application.92 /// </summary>93 [STAThread]94 95 static void Main()96 {97 Application.Run( new SquareInt() );98 }99 100 int square( int y )101 {102 return y * y;103 }104105 }// end of class SquareInt106107 } // end of namespace SquareIntSpace

Fig. 6.3Fig. 6.3Fig. 6.3Fig. 6.3 Using programmer-defined method SquareInt. (part 3 of 3)

Page 9: 06 - Methods

Chapter 6 Methods 267

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

contains a string property called Text, which can be accessed using the same dot operator(.) that we use to access the method in a class. You will learn more about properties inChapter 8. Lines 39–41 creates a string reference output and assigns it to this Textproperty. This string will contain the results of squaring the values from 1–10. Thestring will be displayed on this label.

Line 35 declares int variable result, in which the result of each square calculationis stored. Lines 37–42 contain a for repetition structure in which each iteration of the loopcalculates the Square of the current value of control variable x, stores the value inresult and concatenates the result to the end of output.

Method Square is invoked or called on line 39 with the statement

result = Square( x );

When program control reaches this statement, method Square (defined on lines 100–103)is called. In fact, the () represent the method call operator which has high precedence. Atthis point, a copy of the value of x (the argument to the method call) is made automaticallyby the program and program control transfers to the first line of method Square. Methodsquare receives the copy of the value of x in the parameter y. Then Square calculatesy * y. The result is passed back to the point in SquareInt where Square was invoked.The value returned is then assigned to variable result. Lines 40–41 concatenate "Thesquare of," the value of x, " is ," the value of result and a newline character to theend of outputLabel.Text. This process is repeated ten times using the for repetitionstructure.

The definition of method Square (line 100) shows that Square expects an integerparameter y—this will be the name used to manipulate the value passed to Square in thebody of method Square. Keyword int preceding the method name indicates thatSquare returns an integer result. The return statement in Square passes the result ofthe calculation y * y back to the calling method. Note that the entire method definition iscontained between the braces of the class SquareInt. All methods must be definedinside a class definition.

Good Programming Practice 6.2Place a blank line between method definitions to separate the methods and enhance programreadability. 6.2

Common Programming Error 6.2Defining a method outside the braces of a class definition is a syntax error. 6.2

The format of a method definition is

attributes modifiers return-value-type method-name( parameter-list ){ declarations and statements}

The first line, attributes modifiers return-value-type method-name( parameter-list ), issometimes known as the method header. The attributes and modifiers are used to specifyextra information about the method, such as public or static. The different attributesand modifiers will be discussed in several places throughout the book. The method-name

Page 10: 06 - Methods

268 Methods Chapter 6

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

is any valid identifier. The return-value-type is the data type of the result returned from themethod to the caller. The return-value-type void indicates that a method does not return avalue. Methods can return at most one value.

Common Programming Error 6.3Omitting the return-value-type in a method definition is a syntax error. 6.3

Common Programming Error 6.4Forgetting to return a value from a method that is supposed to return a value is a syntax er-ror. If a return-value-type other than void is specified, the method must contain a returnstatement. 6.4

Common Programming Error 6.5Returning a value from a method whose return type has been declared void is a syntax er-ror. 6.5

The parameter-list is a comma-separated list containing the declarations of the param-eters received by the method when it is called. There must be one argument in the methodcall for each parameter in the method definition. The arguments must also be compatiblewith the type of the parameter. For example, a parameter of type double could receivevalues of 7.35, 22 or –.03546, but not "hello" (because a double variable cannot con-tain a string). If a method does not receive any values, the parameter-list is empty (i.e.,the method name is followed by an empty set of parentheses). A type must be listed explic-itly for each parameter in the parameter list of a method or a syntax error occurs.

Common Programming Error 6.6Declaring method parameters of the same type as float x, y instead of float x, floaty is a syntax error because types are required for each parameter in the parameter list. 6.6

Common Programming Error 6.7Placing a semicolon after the right parenthesis enclosing the parameter list of a method def-inition is a syntax error. 6.7

Common Programming Error 6.8Redefining a method parameter as a local variable in the method is a syntax error. 6.8

Common Programming Error 6.9Passing to a method an argument that is not compatible with the corresponding parameter’stype is a syntax error. 6.9

Good Programming Practice 6.3Although it is not incorrect to do so, do not use the same names for the arguments passed toa method and the corresponding parameters in the method definition. This helps avoid am-biguity. 6.3

The declarations and statements within braces form the method body. The methodbody is also referred to as a block. A block is a compound statement that includes declara-tions. Variables can be declared in any block and blocks can be nested. A method cannotbe defined inside another method.

Page 11: 06 - Methods

Chapter 6 Methods 269

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

Common Programming Error 6.10Defining a method inside another method is a syntax error. 6.10

Good Programming Practice 6.4Choosing meaningful method names and meaningful parameter names makes programsmore readable and helps avoid excessive use of comments. 6.4

Software Engineering Observation 6.5A method should usually be no longer than one page. Better yet, a method should usually beno longer than half a page. Regardless of how long a method is, it should perform one taskwell. Small methods promote software reusability. 6.5

Testing and Debugging Tip 6.1Small methods are easier to test, debug and understand than large ones. 6.1

Software Engineering Observation 6.6Programs should be written as collections of small methods. This makes programs easier towrite, debug, maintain and modify. 6.6

Software Engineering Observation 6.7A method requiring a large number of parameters may be performing too many tasks. Con-sider dividing the method into smaller methods that perform the separate tasks. The methodheader should fit on one line if possible. 6.7

Software Engineering Observation 6.8The method header and method calls must all agree in the number, type and order of param-eters and arguments. 6.8

There are three ways to return control to the point at which a method was invoked. Ifthe method does not return a result, control is returned when the method-ending right braceis reached or by executing the statement

return;

If the method does return a result, the statement

return expression;

returns the value of expression to the caller. When a return statement is executed, controlreturns immediately to the point at which a method was invoked.

Note that the example of Fig. 6.3 actually contains four method definitions—Squa-reInt (line 1), Dispose (line 31), InitializeComponent (line 45), Square (line71) and Main (line 76). Remember that the Main method is automatically called as it isthe entry point in the application. In this example, method Main repeatedly invokes theSquare method to perform a calculation, then displays the results on the Form that is cre-ated in our program. In this example, almost all of the automatically generated code hasbeen included. Future examples will not include methods such as Dispose and Ini-tializeComponent because the user will not alter code within those definitions.

Page 12: 06 - Methods

270 Methods Chapter 6

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

Notice the syntax used to invoke method Square—we use just the method name fol-lowed by the arguments to the method in parentheses. Methods in a class definition areallowed to invoke all other methods in the same class definition using this syntax (there isan exception to this discussed in Chapter 8). Methods in the same class definition are boththe methods defined in that class and the inherited methods (the methods from the class thatthe current class inherits from—System.Windows.Forms.Form in the last example).We have now seen three ways to call a method—a method name by itself (as shown withSquare( x ) in this example), a reference to an object followed by the dot (.) operatorand the method name (such as string1.CompareTo(string2)) and a class namefollowed by a method name (such as Math.Sqrt( 9.0 )). The last syntax is only forstatic methods of a class (discussed in detail in Chapter 8).

The application in our next example (Fig. 6.4) uses a programmer-defined methodcalled Maximum to determine and return the largest of three floating-point values.

1 // Fig 6.4: MaximumValue.cs2 // Finding the maximum of three doubles.34 using System;56 class MaximumValue7 {8 static void Main( string[] args )9 {

10 Console.Write( "Enter first floating-point value: " );11 string s1 = Console.ReadLine();12 13 Console.Write( "Enter second floating-point value: " );14 string s2 = Console.ReadLine();15 16 Console.Write( "Enter third floating-point value: " );17 string s3 = Console.ReadLine();18 19 double number1 = Double.FromString( s1 );20 double number2 = Double.FromString( s2 );21 double number3 = Double.FromString( s3 );2223 double max = Maximum( number1, number2, number3 );2425 Console.WriteLine( "\nnumber1: {0}\nnumber2: {1}" +26 "\nnumber3: {2}\nmaximum is: {3}", number1, number2, 27 number3, max );28 }2930 static double Maximum( double x, double y, double z )31 {32 return Math.Max( x, Math.Max( y, z ) );33 }34 }

Fig. 6.4Fig. 6.4Fig. 6.4Fig. 6.4 Programmer-defined Maximum method. (part 1 of 2)

Page 13: 06 - Methods

Chapter 6 Methods 271

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

The three floating-point values are input by the user via the command prompt (lines11–17 of Main). Lines 19–21 use method Double.FromString to convert thestrings input by the user to double values. Line 23 passes the three double values tomethod Maximum, which determines the largest double value. This value is returned tomethod Main by the return statement in method Maximum. The value returned isassigned to the variable max. The three double values input by the user and the max valueare concatenated and displayed to the user on lines 25–27.

Notice the implementation of the method Maximum (line 30). The first line indicatesthat the method returns a double floating-point value, that the method’s name is Max-imum and that the method takes three double parameters (x, y and z) to accomplish itstask. Also, the body of the method contains the statement

return Math.Max( x, Math.Max( y, z ) );

which returns the largest of the three floating-point values using two calls to theMath.Max method. First, method Math.Max is invoked with the values of variables yand z to determine the larger of these two values. Next, the value of variable x and the re-sult of the first call to Math.Max are passed to method Math.Max. Finally, the result ofthe second call to Math.Max is returned to the point at which Maximum was invoked (i.e.,the Main method in this program).

Another important feature of method definitions is the coercion of arguments (i.e., theforcing of arguments to the appropriate type to pass to a method). For example, the Mathclass method Sqrt can be called with an integer argument even though the method isdefined in the Math class to receive a double argument and the method will still workcorrectly. The statement

Console.WriteLine( Math.Sqrt( 4 ) );

correctly evaluates Math.Sqrt( 4 ) and prints the value 2. The method definition’s pa-rameter list causes the integer value 4 to be converted to the double value 4.0 before thevalue is passed to Math.Sqrt. In many cases, argument values that do not correspondprecisely to the parameter types in the method definition are converted to the proper typebefore the method is called. In some cases, attempting these conversions leads to compilererrors if C#’s promotion rules are not satisfied. The promotion rules specify how types canbe converted to other types without losing data. In our Math.Sqrt example above, anint is automatically converted to a double without changing its value. However, a dou-ble converted to an int truncates the fractional part of the double value. Converting

Enter first floating-point value: 37.3Enter second floating-point value: 99.32Enter third floating-point value: 27.1928

number1: 37.3number2: 99.32number3: 27.1928maximum is: 99.32

Fig. 6.4Fig. 6.4Fig. 6.4Fig. 6.4 Programmer-defined Maximum method. (part 2 of 2)

Page 14: 06 - Methods

272 Methods Chapter 6

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

large integer types to small integer types (e.g., long to int) may also result in changedvalues.

The promotion rules apply to expressions containing values of two or more data types(also referred to as mixed-type expressions) and to primitive data type values passed asarguments to methods. This promotion is also referred to as coersion of arguments. Thetype of each value in a mixed-type expression is promoted to the “highest” type in theexpression (actually, a temporary version of each value is created and used for the expres-sion—the original values remain unchanged). The type of a method argument can be pro-moted to any “higher” type. Figure 6.5 lists the primitive data types and the types to whicheach is allowed to be promoted automatically.

Converting values to lower types can result in different values. Therefore, in caseswhere information may be lost due to conversion, the C# compiler requires the programmerto use a cast operator to force the conversion to occur. To invoke our Square method,which uses an integer parameter (Fig. 6.3) with the double variable y, the method call iswritten as Square( ( int ) y ). This explicitly casts (converts) the value of y to aninteger for use in method Square. Thus, if y’s value is 4.5, method Square returns 16,not 20.25.

Common Programming Error 6.11Converting a primitive-data-type value to another primitive data type may change the valueif the new data type is not an allowed promotion (e.g., double to int). Also, convertingany integral value to a floating-point value and back to an integral value may introducerounding errors into the result. 6.11

Type Allowed promotions

bool object

byte decimal, double, float, int, uint, long, ulong, object, short or ushort

sbyte decimal, double, float, int, long, object or short

char decimal, double, float, int, uint, long, ulong, object or ushort

decimal object

double object

float double or object

int decimal, double, float, long or object

uint decimal, double, float, long, ulong or object

long decimal, double, float or object

ulong decimal, double, float or object

object None

short decimal, double, float, int, long or object

ushort decimal, double, float, int, uint, long, ulong or object

string object

Fig. 6.5Fig. 6.5Fig. 6.5Fig. 6.5 Allowed promotions for primitive data types.

Page 15: 06 - Methods

Chapter 6 Methods 273

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

6.6 Passing Arguments: Call-by-Value vs. Call-by-ReferenceTwo ways to pass arguments to methods (or functions) in many programming languages(like C and C++) are call-by-value and call-by-reference (also called pass-by-value andpass-by-reference). When an argument is passed call-by-value, a copy of the argument’svalue is made and passed to the called method.

Testing and Debugging Tip 6.2With call-by-value, changes to the called method’s copy do not affect the original variable’svalue in the calling method. This prevents the accidental side effects that so greatly hinderthe development of correct and reliable software systems. 6.2

With call-by-reference, the caller gives the called method the ability to directly accessthe caller’s data and to modify that data if the called method so chooses. Call-by-referencecan improve performance because it can eliminate the overhead of copying large amountsof data, but call-by-reference can weaken security because the called method can access thecaller’s data.

Software Engineering Observation 6.9Unlike other languages, C# does not allow the programmer to choose whether to pass eachargument call-by-value or call-by-reference. Primitive data type variables are alwayspassed call-by-value. Objects are not passed to methods; rather, references to objects arepassed to methods. The references themselves are also passed call-by-value. When a methodreceives a reference to an object, the method can manipulate the object directly. 6.9

Software Engineering Observation 6.10When returning information from a method via a return statement, primitive-data-typevariables are always returned by value (i.e., a copy is returned) and objects are always re-turned by reference (i.e., a reference to the object is returned). 6.10

To pass a reference to an object into a method, simply specify in the method call thereference name. Mentioning the reference by its parameter name in the body of the calledmethod actually refers to the original object in memory, and the original object can beaccessed directly by the called method.

Because arrays are treated as objects by C#, arrays are passed to the methods call-by-reference—a called method can access the elements of the caller’s original arrays. Thename of an array is actually a reference to an object that contains the array elements and thelength instance variable, which indicates the number of elements in the array. In the nextsection, we demonstrate call-by-value and call-by-reference using arrays.

Performance Tip 6.2Passing arrays by reference makes sense for performance reasons. If arrays were passed byvalue, a copy of each element would be passed. For large, frequently passed arrays, thiswould waste time and would consume considerable storage for the copies of the arrays. 6.2

Earlier in this book we discussed the difference between value types and referencetypes. At this point it is possible for the reader to understand one of the major differencesbetween the two data types—value type variables are passed to methods using call-by-value, whereas reference type variables are passed to methods using call-by-reference.What if the programmer would like to pass a value type by reference? To do this, C# pro-

Page 16: 06 - Methods

274 Methods Chapter 6

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

vides the ref parameter and the out parameter. The ref parameter is used to specifythat an argument being passed can be directly modified as if it were passed by reference.The ref parameter is used for variables that have already been initialized. The out param-eter, on the other hand, is used for values that we want initialized (and possibly modified)by the method. Normally when we send an uninitialized value to a method, the compilerwill generate an error. By using out in place of ref, we are specifying that we expect thisvariable to be initialized in the method being called, and so no error will occur.

Common Programming Error 6.12Although using out will suppress a syntax error for uninitialized variables, this should notalways be used in place of ref. Doing so may make your code harder to understand. 6.12

Figure 6.6 demonstrates the ref and out parameters to manipulate integer values.

1 // Fig. 6.6: RefOutTest.cs2 // Demonstrating ref and out parameters.34 using System;5 using System.Windows.Forms;67 // Class used to initialize and modify an integer value8 class RefOutTest9 {

10 // x is changed, rather than a copy of x11 static void SquareRef( ref int x )12 {13 x = x * x;14 }1516 // x is changed and can be passed without being initialized17 static void SquareOut( out int x )18 {19 x = 6;20 x = x * x;21 }2223 // x is not changed, it is passed-by-value24 static void Square( int x )25 {26 x = x * x;27 }2829 static void Main()30 {31 // Create a new integer value, set it to 532 int x = 5;33 int y; // Declare y, but do not initialize it3435 string output1 = "The value of x begins as " 36 + x + ", y begins uninitialized.\n\n\n";3738 // values of x and y are changed

Fig. 6.6Fig. 6.6Fig. 6.6Fig. 6.6 Demonstrating ref and out parameters. (part 1 of 2)

Page 17: 06 - Methods

Chapter 6 Methods 275

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

This program contains 3 methods to calculate the square of an integer. The firstmethod, SquareRef (lines 11–14), simply multiplies x by itself, and assigns the newvalue to x. The argument x is passed in as ref int, specifying that x is an integer, but isbeing passed by reference. As a result, the argument passed is directly changed, rather thana copy of it being changed. The second method, SquareOut (lines 17–21), does the samething but initializes x to 6 on line 19. The argument x is passed in as an out int, speci-fying that x is an integer being passed by reference, but has not yet been initialized. Thefinal method, Square (lines 24–27), simply takes x as a regular integer argument, andsquares it’s value.

Method Main (lines 29–59), tests SquareRef, SquareOut and Square. Webegin by initializing x to 5 and simply declaring (but not initializing) y. On lines 39–40 we

39 RefOutTest.SquareRef( ref x );40 RefOutTest.SquareOut( out y );4142 string output2 = "After calling SquareRef with x as an " +43 "argument and SquareOut with y as an argument,\n" +44 "the values of x and y are:\n\n" + 45 "x: " + x + "\n" + "y: " + y + "\n\n\n";4647 // values of x and y are not changed48 RefOutTest.Square( x );49 RefOutTest.Square( y );5051 string output3 = "After calling Square on both x and y, " +52 "the values of x and y are:\n\n" +53 "x: " + x + "\n" + "y: " + y + "\n\n";5455 MessageBox.Show( output1 + output2 + output3, 56 "Using ref and out Parameters", MessageBoxButtons.OK,57 MessageBoxIcon.Information );5859 } // end of method Main6061 } // end of class RefOutTest

Fig. 6.6Fig. 6.6Fig. 6.6Fig. 6.6 Demonstrating ref and out parameters. (part 2 of 2)

Page 18: 06 - Methods

276 Methods Chapter 6

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

call methods SquareRef and SquareOut. Notice the syntax used for passing x and y—in both cases we have preceded the argument with either ref or out. In the output we havedisplayed the values of x and y after the function calls. Notice that x has been changed to25, and y has been set to 36. Finally, on lines 48–49 we call method Square. Since x andy are both passed as regular integers, only a copy of their value is actually passed to themethod. As the output shows, the values of x and y remain 25 and 36 after the calls toSquare.

Common Programming Error 6.13The ref and out parameters in a method call must match those specified in the method def-inition. For instance, if a method calls for a ref double z, the double value passed asan argument must be preceded by the ref keyword, or a syntax error is generated. The sameis true for keyword out. 6.13

6.7 Random Number GenerationWe now take a brief and, it is hoped, entertaining diversion into a popular programmingapplication, namely simulation and game playing. In this section and the next section, wewill develop a nicely structured game-playing program that includes multiple methods. Theprogram uses most of the control structures we have studied.

There is something in the air of a gambling casino that invigorates people, from thehigh-rollers at the plush mahogany-and-felt craps tables to the quarter-poppers at the one-armed bandits. It is the element of chance, the possibility that luck will convert a pocketfulof money into a mountain of wealth. The element of chance can be introduced through theRandom class.

Consider the following statements:

Random randomObject = new Random();int randomNumber = randomObject.Next();

The Next method generates a int value that is positive, being between 0 and the maxi-mum integer value (which is different depending on the system). If Next truly producesvalues at random, every value in this range has an equal chance (or probability) of beingchosen each time Next is called.

The range of values produced directly by Next is often different than what is neededin a specific application. For example, a program that simulates coin tossing might requireonly 0 for “heads” and 1 for “tails.” A program that simulates rolling a six-sided die wouldrequire random integers in the range 1–6. A program that randomly predicts the next typeof spaceship (out of four possibilities) that will fly across the horizon in a video game wouldrequire random integers in the range 1–4.

To demonstrate using class Random and method Next, let us develop a program thatsimulates 20 rolls of a six-sided die and prints the value of each roll. We use the additionoperator (+) in conjunction with Next as follows:

value = 1 + r.Next( 6 );

to produce integers in the range 0 to 5. When Next is passed one argument, the values re-turned will be in the range 0 up to (but not including) the value of the argument passed. If

Page 19: 06 - Methods

Chapter 6 Methods 277

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

two arguments are passed to Next, the resulting value will be within a range defined bythe two values passed. This is called scaling. The number 6 is called the scaling factor. Wethen shift the range of numbers produced by adding 1 to our previous result, so that the re-turn values are between 1 and 6, rather than 0 and 5.

To show that these numbers occur with approximately equal likelihood, let us simulate12 rolls of a die with the program of Fig. 6.8.

1 // Fig 6.7: RandomInt.cs2 // Generating Random integers34 using System;5 using System.Windows.Forms;67 class RandomInt8 {9 static void Main()

10 {11 Random r = new Random();12 int value;13 string output = "";1415 for ( int i = 1; i <=20; i++ ) 16 {17 value = 1 + r.Next( 6 );18 output += value + " ";1920 if ( i % 5 == 0 )21 output += "\n";22 }2324 MessageBox.Show( output, 25 "20 Random Numbers from 1 to 6"\,26 MessageBoxButtons.OK, MessageBoxIcon.Information );27 }28 }

Fig. 6.7Fig. 6.7Fig. 6.7Fig. 6.7 Shifted random integers.

1 // Fig. 6.8: RollDie.cs2 // Rolling 12 dice3

Fig. 6.8Fig. 6.8Fig. 6.8Fig. 6.8 Rolling dice in a windows application. (part 1 of 4)

Page 20: 06 - Methods

278 Methods Chapter 6

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

4 using System;5 using System.Drawing;6 using System.Collections;7 using System.ComponentModel;8 using System.Windows.Forms;9 using System.IO;

10 using System.Data;1112 public class RollDie : System.Windows.Forms.Form13 {14 /// <summary>15 /// Required designer variable.16 /// </summary>17 private System.ComponentModel.Container components = null;18 private System.Windows.Forms.Button rollButton;19 private System.Windows.Forms.Label dieLabel12;20 private System.Windows.Forms.Label dieLabel11;21 private System.Windows.Forms.Label dieLabel10;22 private System.Windows.Forms.Label dieLabel9;23 private System.Windows.Forms.Label dieLabel8;24 private System.Windows.Forms.Label dieLabel7;25 private System.Windows.Forms.Label dieLabel6;26 private System.Windows.Forms.Label dieLabel5;27 private System.Windows.Forms.Label dieLabel4;28 private System.Windows.Forms.Label dieLabel3;29 private System.Windows.Forms.Label dieLabel2;30 private System.Windows.Forms.Label dieLabel1;31 private Random r = new Random();3233 public RollDie()34 {35 // Required for Windows Form Designer support36 InitializeComponent();37 }3839 // Visual Studio.NET Generated Code4041 [STAThread]4243 public static void Main()44 {45 Application.Run( new RollDie() );46 }4748 protected void rollButton_Click (object sender, 49 System.EventArgs e)50 {51 // Pass the labels to a method that will randomly assign52 // a face to each die.53 DisplayDie( dieLabel1 );54 DisplayDie( dieLabel2 );55 DisplayDie( dieLabel3 );56 DisplayDie( dieLabel4 );57 DisplayDie( dieLabel5 );

Fig. 6.8Fig. 6.8Fig. 6.8Fig. 6.8 Rolling dice in a windows application. (part 2 of 4)

Page 21: 06 - Methods

Chapter 6 Methods 279

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

58 DisplayDie( dieLabel6 );59 DisplayDie( dieLabel7 );60 DisplayDie( dieLabel8 );61 DisplayDie( dieLabel9 );62 DisplayDie( dieLabel10 );63 DisplayDie( dieLabel11 );64 DisplayDie( dieLabel12 );65 }6667 public void DisplayDie( Label dieLabel )68 {69 int face = 1 + r.Next( 6 );70 dieLabel.Image = Image.FromFile( 71 Directory.CurrentDirectory + "\\images\\die" + face 72 + ".gif" );73 }74 75 }

Fig. 6.8Fig. 6.8Fig. 6.8Fig. 6.8 Rolling dice in a windows application. (part 3 of 4)

Page 22: 06 - Methods

280 Methods Chapter 6

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

Until now, many of our user interactions with applications have been through the com-mand prompt (in which the user could type an input value into the program) or a messagedialog (which displayed a message to the user and allowed the user to click OK to dismissthe dialog). In Chapter 4, we gave a brief introduction to windows applications by creatingsome programs that display information using a label on a form.

Although these are valid ways to receive input from a user and display output in a C#program, they are fairly limited in their capabilities—the command prompt can obtain onlyone value at a time from the user and a message dialog can display only one message. It ismuch more common to receive multiple inputs from the user at once (such as the user

Fig. 6.8Fig. 6.8Fig. 6.8Fig. 6.8 Rolling dice in a windows application. (part 4 of 4)

Page 23: 06 - Methods

Chapter 6 Methods 281

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

entering name and address information) or display many pieces of data at once (such as thevalues of the dice, the sum of the dice and the point in this example). To begin our intro-duction to more elaborate user interfaces, this program illustrates two new graphical userinterface concepts—attaching several GUI components to an application and graphical userinterface event handling.

When this program is created in design mode, the user needs to create a GUI compo-nent known as a Button. Like a label, a button can simply be chosen from the ToolBoxand added to our form using the drag-and-drop method. There are also 12 labels that wewill be using to display our dice. When the user double-clicks on a button that they havecreated, they will be taken to the code for this program, and specifically to a method calledan event handler. An event is a signal that is sent when some action takes place, such as abutton being clicked, or a value being changed. The programmer writes the application toperform certain tasks when these events occur. Using objects and events together allowsthe programmer to create applications that can interact with the user in more sophisticatedways than we have previously seen. An event handler is a method that is executed (called)when a certain event occurs (sometimes we say an event is raised). The event handler bydefault will be named using the name of the object followed by an underscore and then thename of the event. In this case, the name of the method becomes rollButton_Click.Whenever the user clicks on rollButton, this method will be called. This functionsimply calls method DisplayDie twelve times, for each label.

Function DisplayDie (lines 67–73) specifies the correct image based on the facevalue calculated on line 69. On line 70 we see the use of the Image property. Propertiesare members of classes that we will discuss in detail in Chapter 8. For now you simply needto know that a property is used to specify certain information about an object, in this casea label. The property is accessed and assigned values by using the dot operator, and is usedto specify which image will be displayed on the label. We set this value using an assign-ment statement on lines 70–72. Notice that we specify which image will be displayed byusing method FromFile in class Image. We use this method to specify where the imageis coming from. This causes each of the 12 dice to appear as if they are being rolled againevery time rollButton is clicked. Directory.CurrentDirectory returns thelocation of the folder where the current project is including "bin/Debug," the location inwhich the solution is being executed. The die images need to be placed in this folder for thesolutions in both Fig. 6.8 and Fig. 6.9 to operate properly. These images are placed in theproper folders on the CD that accompanies this book.

To show that these numbers occur approximately with equal likelihood, let us modifythe program of Fig. 6.8 to keep some simple statistics. The frequency of each face value (1through 6) should be approximately the same. The GUI and code shown in Fig. 6.9 displayshow the program begins and the results after clicking Roll 10 times.

1 // Fig. 6.9: RollDie2.cs2 // Rolling 12 dice with Frequency Chart34 using System;5 using System.Drawing;6 using System.Collections;7 using System.ComponentModel;

Fig. 6.9Fig. 6.9Fig. 6.9Fig. 6.9 Simulating rolling 12 six-sided dice. (part 1 of 5)

Page 24: 06 - Methods

282 Methods Chapter 6

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

8 using System.Windows.Forms;9 using System.Data;

10 using System.IO;1112 public class RollDie2 : System.Windows.Forms.Form13 {14 private System.ComponentModel.Container components;15 private System.Windows.Forms.RichTextBox displayTextBox;16 private System.Windows.Forms.Button rollButton;17 private System.Windows.Forms.Label dieLabel12;18 private System.Windows.Forms.Label dieLabel11;19 private System.Windows.Forms.Label dieLabel10;20 private System.Windows.Forms.Label dieLabel9;21 private System.Windows.Forms.Label dieLabel8;22 private System.Windows.Forms.Label dieLabel7;23 private System.Windows.Forms.Label dieLabel6;24 private System.Windows.Forms.Label dieLabel5;25 private System.Windows.Forms.Label dieLabel4;26 private System.Windows.Forms.Label dieLabel3;27 private System.Windows.Forms.Label dieLabel2;28 private System.Windows.Forms.Label dieLabel1;29 private Random r = new Random();30 private int ones, twos, threes, fours, fives, sixes;3132 public RollDie2()33 {34 // Required for Windows Form Designer support35 InitializeComponent();3637 // TODO: Add any code after InitializeComponent call38 ones = twos = threes = fours = fives = sixes = 0;39 }4041 // Visual Studio.NET generated code4243 protected void rollButton_Click (object sender, 44 System.EventArgs e)45 {46 // Pass the labels to a method that will randomly assign47 // a face to each die.48 DisplayDie( dieLabel1 );49 DisplayDie( dieLabel2 );50 DisplayDie( dieLabel3 );51 DisplayDie( dieLabel4 );52 DisplayDie( dieLabel5 );53 DisplayDie( dieLabel6 );54 DisplayDie( dieLabel7 );55 DisplayDie( dieLabel8 );56 DisplayDie( dieLabel9 );57 DisplayDie( dieLabel10 );58 DisplayDie( dieLabel11 );59 DisplayDie( dieLabel12 );6061 double total = ones + twos + threes + fours + fives + sixes;

Fig. 6.9Fig. 6.9Fig. 6.9Fig. 6.9 Simulating rolling 12 six-sided dice. (part 2 of 5)

Page 25: 06 - Methods

Chapter 6 Methods 283

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

6263 displayTextBox.Text = "Frequency\tFace\tPercent\n1\t\t" + 64 ones + "\t" + 65 double.Format( ones / total * 100, "0.00" ) +66 "%\n2\t\t" + twos + "\t" + 67 double.Format( twos / total * 100, "0.00" ) + 68 "%\n3\t\t" + threes + "\t" + 69 double.Format( threes / total * 100, "0.00" ) + 70 "%\n4\t\t" + fours + "\t" + 71 double.Format( fours / total * 100, "0.00" ) +72 "%\n5\t\t" + fives + "\t" + 73 double.Format( fives / total * 100, "0.00" ) +74 "%\n6\t\t" + sixes + "\t" + 75 double.Format( sixes / total * 100, "0.00" ) + "%";76 }7778 public void DisplayDie( Label dieLabel )79 {80 int face = 1 + r.Next( 6 );81 dieLabel.Image = Image.FromFile( 82 Directory.CurrentDirectory + "\\images\\die" + face +83 ".gif" );8485 switch ( face )86 {87 case 1: ones++;88 break;89 case 2: twos++;90 break;91 case 3: threes++;92 break;93 case 4: fours++;94 break;95 case 5: fives++;96 break;97 case 6: sixes++;98 break;99 }100 }101 102 public static void Main()103 {104 Application.Run( new RollDie2() );105 }106 }

Fig. 6.9Fig. 6.9Fig. 6.9Fig. 6.9 Simulating rolling 12 six-sided dice. (part 3 of 5)

Page 26: 06 - Methods

284 Methods Chapter 6

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

Fig. 6.9Fig. 6.9Fig. 6.9Fig. 6.9 Simulating rolling 12 six-sided dice. (part 4 of 5)

Page 27: 06 - Methods

Chapter 6 Methods 285

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

As the program output shows, by scaling and shifting we have utilized function Nextto realistically simulate the rolling of a six-sided die (i.e., over a large number of die rolls,each of the six possible faces from 1 through 6 appears with equal likelihood about onesixth of the time). Note that no default case is provided in the switch structure. Afterwe study arrays in Chapter 7, we will show how to replace the entire switch structure inthis program with a single-line statement.

Run the program several times and observe the results. Notice that a different sequenceof random numbers is obtained each time the program is executed, so the program resultsshould vary.

The values produced directly by Next are always in the range

0 ≤ r.Next( x ) < ( x - 1 )

Previously we demonstrated how to write a single statement to simulate the rolling of a six-sided die with the statement

face = 1 + r.Next( 6 );

which always assigns an integer (at random) to variable face in the range 1 ≤ face ≤ 6.Note that the width of this range (i.e., the number of consecutive integers in the range) is 6and the starting number in the range is 1. Referring to the preceding statement, we see that

Fig. 6.9Fig. 6.9Fig. 6.9Fig. 6.9 Simulating rolling 12 six-sided dice. (part 5 of 5)

Page 28: 06 - Methods

286 Methods Chapter 6

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

the width of the range is determined by the Next argument (i.e., 6) and the starting numberof the range is equal to the number (i.e., 1) added to r.Next( 6 ). We can generalize thisresult as follows:

n = a + r.Next( b );

where a is the shifting value (which is equal to the first number in the desired range of con-secutive integers) and b is the scaling factor (which is equal to the width of the desiredrange of consecutive integers).

6.8 Example: Game of ChanceOne of the most popular games of chance is a dice game known as “craps,” which is playedin casinos and back alleys throughout the world. The rules of the game are straightforward:

A player rolls two dice. Each die has six faces. These faces contain 1, 2, 3, 4, 5 and 6 spots,respectively. After the dice have come to rest, the sum of the spots on the two upward faces iscalculated. If the sum is 7 or 11 on the first throw, the player wins. If the sum is 2, 3 or 12 onthe first throw (called “craps”), the player loses (i.e., the “house” wins). If the sum is 4, 5,6, 8, 9 or 10 on the first throw, that sum becomes the player’s “point.” To win, you must con-tinue rolling the dice until you “make your point” (i.e., roll your point value). The playerloses by rolling a 7 before making the point.

The application in Fig. 6.10 simulates the game of craps. Notice that the player must roll two dice on the first and all subsequent rolls. When you

execute the application, click the Play button to play the game. The form displays theresults of each roll. The screen captures show the execution of a single game.

1 // Fig 6.10: CrapsGame.cs2 // Craps Game34 using System;5 using System.Drawing;6 using System.Collections;7 using System.ComponentModel;8 using System.Windows.Forms;9 using System.Data;

10 using System.IO;1112 public class CrapsGame : System.Windows.Forms.Form13 {14 private System.ComponentModel.Container components = null;15 private System.Windows.Forms.PictureBox imgPointDie2;16 private System.Windows.Forms.PictureBox imgDie2;17 private System.Windows.Forms.PictureBox imgDie1;18 private System.Windows.Forms.Label lblStatus;19 private System.Windows.Forms.Button rollButton;20 private System.Windows.Forms.Button playButton;21 private System.Windows.Forms.PictureBox imgPointDie1;

Fig. 6.10Fig. 6.10Fig. 6.10Fig. 6.10 Program to simulate the game of craps. (part 1 of 6)

Page 29: 06 - Methods

Chapter 6 Methods 287

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

22 private System.Windows.Forms.GroupBox fraPoint;2324 //declare other variables25 int myPoint;26 int myDie1;27 int myDie2;2829 public enum DiceNames30 {31 snakeEyes = 2,32 trey = 3,33 yoLeven = 11,34 boxCars = 12,35 }3637 public CrapsGame()38 {39 // Required for Windows Form Designer support40 InitializeComponent();41 }4243 // Visual Studio.NET generated code4445 [STAThread]4647 protected void rollButton_Click (object sender, 48 System.EventArgs e)49 {50 int sum;51 sum = rollDice();5253 if ( sum == myPoint )54 {55 lblStatus.Text = "You Win!!!";56 rollButton.Enabled = false;57 playButton.Enabled = true;58 }59 else60 if ( sum == 7 )61 {62 lblStatus.Text = "Sorry. You lose.";63 rollButton.Enabled = false;64 playButton.Enabled = true;65 }66 }6768 protected void playButton_Click ( object sender, 69 System.EventArgs e )70 {71 int sum;72 myPoint = 0;73 fraPoint.Text = "Point";74 lblStatus.Text = "";75 imgPointDie1.Image = null;

Fig. 6.10Fig. 6.10Fig. 6.10Fig. 6.10 Program to simulate the game of craps. (part 2 of 6)

Page 30: 06 - Methods

288 Methods Chapter 6

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

76 imgPointDie2.Image = null;7778 sum = rollDice();7980 switch ( sum )81 {82 case 7:83 case ( int )DiceNames.yoLeven: 84 rollButton.Enabled = false; // Disable Roll button85 lblStatus.Text = "You Win!!!";86 break;87 case (int)DiceNames.snakeEyes:88 case (int)DiceNames.trey:89 case (int)DiceNames.boxCars:90 rollButton.Enabled = false; 91 lblStatus.Text = "Sorry. You lose.";92 break;93 default:94 myPoint = sum;95 fraPoint.Text = "Point is " + sum;96 lblStatus.Text = "Roll Again";97 displayDie( imgPointDie1, myDie1 );98 displayDie( imgPointDie2, myDie2 );99 playButton.Enabled = false;100 rollButton.Enabled = true;101 break;102 }103 }104105 private void displayDie( PictureBox imgDie, int face )106 {107 imgDie.Image = Image.FromFile( 108 Directory.CurrentDirectory + "\\images\\die" + face +109 ".gif" );110 }111112 private int rollDice()113 {114 int die1, die2, dieSum;115 Random r = new Random();116117 die1 = 1 + r.Next( 6 );118 die2 = 1 + r.Next( 6 );119120 displayDie( imgDie1, die1 );121 displayDie( imgDie2, die2 );122123 myDie1 = die1;124 myDie2 = die2;125 dieSum = die1 + die2;126 return dieSum;127 }128129 public static void Main()

Fig. 6.10Fig. 6.10Fig. 6.10Fig. 6.10 Program to simulate the game of craps. (part 3 of 6)

Page 31: 06 - Methods

Chapter 6 Methods 289

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

130 {131 Application.Run( new CrapsGame() );132 }133 }

Fig. 6.10Fig. 6.10Fig. 6.10Fig. 6.10 Program to simulate the game of craps. (part 4 of 6)

Page 32: 06 - Methods

290 Methods Chapter 6

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

Fig. 6.10Fig. 6.10Fig. 6.10Fig. 6.10 Program to simulate the game of craps. (part 5 of 6)

Page 33: 06 - Methods

Chapter 6 Methods 291

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

Lines 4–10 specify to the compiler where to locate the classes used in this application.The first using statement specifies that the program uses classes from namespaceSystem (specifically, classes Random and Double). Many of these namespaces areincluded automatically, but will not be used yet. The second using statement includes allthe classes in the System.Drawing namespace. This namespace gives the programmerthe ability to include various graphics in their program (see Chapter 16). The next line spec-

Fig. 6.10Fig. 6.10Fig. 6.10Fig. 6.10 Program to simulate the game of craps. (part 6 of 6)

Page 34: 06 - Methods

292 Methods Chapter 6

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

ifies the namespace System.Collections. This class allows us to include collectionsof objects, usually representing data structures (see Chapter 24). The fifth using state-ment specifies that the program uses classes from namespace System.Win-dows.Forms. This namespace contains many data types that enable a program to processa user’s interactions with a program’s GUI. In this program, we use the classes Pic-tureBox, Label, Button and GroupBox from namespace System.Win-dows.Forms. The last using statements include the namespaces System.Data andSystem.IO, which enable database work and input and output from files or streams(Chapter 17 and Chapter 19).

Every C# program is based on at least one class definition that extends and enhancesan existing class definition via inheritance. Remember that all forms inherit from classSystem.Windows.Forms.Form. Line 12 indicates that class CrapsGame inheritsfrom System.Windows.Forms.Form. A class can inherit existing attributes andbehaviors (data and methods) from another class specified to the right of operator : in theclass definition.

Before any method definitions, the reader will see several declarations, including ourfirst enumeration on lines 29–35. An enumeration is a data type that contains several con-stant values, and is created using the keyword enum. This enumeration is used for referencethroughout the program. Because we have used the identifiers snakeEyes, trey,yoLeven and boxCars, the program itself reads closer to English and less like severalnumbers and symbols.

In this program we have introduced a few new components. The first component,called a GroupBox, is used display the user’s point. A GroupBox is used as a containerfor other components, and can help aid in the management of these components. Within theGroupBox we add two PictureBoxes, components used to display images. These areadded in the same way as before, by clicking on PictureBox in the ToolBox and thendragging this component within the borders of the GroupBox.

In the Visual Studio.NET generated code, it is specified that the methodthis.rollButton_Click is the event handler for the event rollButton.Click.This method is also defined in the automatically generated code. This method’s task is toprocess a user’s interaction with the rollButton (called Roll Dice on the user interface)in this example. Line 51 calls method rollDice (defined on lines 112–127), which dis-plays the dice and returns their sum. The rest of rollButton_Click analyzes the roll,letting the user know if they won or lost. Depending on the value of the users roll, the but-tons rollButton and PlayButton will either become disabled or enabled. This isdone using the Enabled property, which is set to true or false.

Method playButton_Click is used for the beginning of the game. When the userclicks the Play button, this method will declare and initialize certain values (lines 71–76)and execute the opening roll of the game (line 78). The switch statement on lines 80–102will analyze this roll similarly to the if/else structure in methodrollButton_Click.

6.9 Duration of IdentifiersChapters 2–5 used identifiers for variable names and reference names. The attributes ofvariables and references include name, type, size and value. We also use identifiers as

Page 35: 06 - Methods

Chapter 6 Methods 293

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

names for user-defined methods and classes. Actually, each identifier in a program has oth-er attributes, including duration and scope.

An identifier’s duration (also called its lifetime) is the period during which that iden-tifier exists in memory. Some identifiers exist briefly, some are repeatedly created anddestroyed and others exist for the entire execution of a program.

An identifier’s scope is where the identifier can be referenced in a program. Someidentifiers can be referenced throughout a program, while others can be referenced fromonly limited portions of a program. This section discusses duration of identifiers. Section6.10 discusses the scope of identifiers.

Identifiers that represent local variables in a method (i.e., parameters and variablesdeclared in the method body) have automatic duration. Automatic duration variables arecreated when program control reaches their declaration, they exist while the block in whichthey are declared is active and they are destroyed when the block in which they are declaredis exited. For the remainder of the text, we will refer to variables of automatic duration asautomatic variables or local variables.

Software Engineering Observation 6.11Automatic duration is a means of conserving memory because automatic duration variablesare created when program control reaches their declaration and are destroyed when theblock in which they are declared is exited. 6.11

The instance variables of a class are automatically initialized by the compiler if theprogrammer does not provide initial values. Variables of most primitive data types are ini-tialized to zero and bool variables are initialized to false. References are initialized tonull. Unlike instance variables of a class, automatic variables must be initialized by theprogrammer before they can be used.

Testing and Debugging Tip 6.3Automatic variables must be initialized before they are used in a method; otherwise, the com-piler issues an error message. 6.3

C# also has identifiers of static duration. Variables and references of static durationexist from the point at which the class that defines them is loaded into memory for execu-tion until the program terminates. Their storage is allocated and initialized when theirclasses are loaded into memory. Even though the static duration variable and referencenames exist when their classes are loaded into memory, this does not mean that these iden-tifiers can be used throughout the program. Duration and scope (where a name can be used)are separate issues, as discussed in the next section.

6.10 Scope RulesThe scope (sometimes called a declaration space) of an identifier for a variable, referenceor method is the portion of the program in which the identifier can be referenced. A localvariable or reference declared in a block can be used only in that block or in blocks nestedwithin that block. The scopes for an identifier are class scope and block scope. There is alsoa special scope—method scope (label declaration space)—for labels used with the breakand continue statements (introduced in Chapter 5, “Control Structures: Part II”). Labelsare only visible in the block in which they are declared.

Page 36: 06 - Methods

294 Methods Chapter 6

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

Members of a class have class scope, and are visible in what is known as the declara-tion space of a class. Class scope begins at the opening left brace, {, of the class definitionand terminates at the closing right brace, }, of the class definition. Class scope enablesmethods of a class to directly invoke all members defined in that same class or inheritedinto that class. In Chapter 8, we will see that static members are an exception to thisrule. In a sense, all instance variables and methods of a class are global to the method ofthe class in which they are defined (i.e., the methods can modify the instance variablesdirectly and invoke other methods of the class).

Identifiers declared inside a block have block scope (local variable declaration space).Block scope begins at the identifier’s declaration and ends at the terminating right brace (})of the block. Local variables of a method have block scope as do method parameters, whichare also local variables of the method. Any block may contain variable or reference decla-rations. When blocks are nested in a method’s body and an identifier declared in an outerblock has the same name as an identifier declared in an inner block, the value in the outerblock is “hidden” until the block terminates execution. The same occurs if a local variablein a method has the same name as an instance variable. In Chapter 8, we discuss how toaccess such “hidden” instance variables. The reader should note that block scope appliesalso to methods and for structures. With for structures, any variable declared in the ini-tialization portion of the for header will only be visible within that for structure.

Good Programming Practice 6.5Avoid local variable names that hide instance variable names. This can be accomplished byavoiding the use of duplicate identifiers in a class. 6.5

Software Engineering Observation 6.12Automatic duration is an example of the principle of least privilege. This principle states thateach component of a system should have sufficient rights and privileges to accomplish itsdesignated task, but no additional rights or privileges. This helps prevent accidental and/ormalicious errors from occurring in systems. Why have variables stored in memory and ac-cessible when they are not needed? 6.12

The program of Fig. 6.11 demonstrates scoping issues with instance variables andlocal variables.

1 // Fig. 6.11: Scoping.cs2 // A Scoping example.34 using System;5 using System.Drawing;6 using System.Collections;7 using System.ComponentModel;8 using System.Windows.Forms;9 using System.Data;

1011 public class Scoping : System.Windows.Forms.Form12 {13 private System.ComponentModel.Container components = null;14 private System.Windows.Forms.Label outputLabel;

Fig. 6.11Fig. 6.11Fig. 6.11Fig. 6.11 A scoping example. (part 1 of 3)

Page 37: 06 - Methods

Chapter 6 Methods 295

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

1516 public int x = 1;1718 public Scoping()19 {20 InitializeComponent();21 int x = 5; // variable local to constructor2223 outputLabel.Text = outputLabel.Text +24 "local x in start is " + x;2526 MethodA(); // MethodA has automatic local x;27 MethodB(); // MethodB uses instance variable x28 MethodA(); // MethodA reinitializes automatic local x29 MethodB(); // instance variable x retains its value3031 outputLabel.Text = outputLabel.Text +32 "\n\nlocal x in start is " + x;33 }3435 // Visual Studio.NET generated code3637 public void MethodA()38 {39 int x = 25; // initialized each time a is called4041 outputLabel.Text = outputLabel.Text +42 "\n\nlocal x in MethodA is " + x +43 " after entering MethodA";44 ++x;45 outputLabel.Text = outputLabel.Text +46 "\nlocal x in MethodA is " + x + 47 " before exiting MethodA";48 }4950 public void MethodB()51 {52 outputLabel.Text = outputLabel.Text +53 "\n\ninstance variable x is " + x +54 " on entering MethodB";55 x *= 10;56 outputLabel.Text = outputLabel.Text + 57 "\ninstance varable x is " + x +58 " on exiting MethodB";59 }6061 public static void Main()62 {63 Application.Run( new Scoping() );64 }65 }

Fig. 6.11Fig. 6.11Fig. 6.11Fig. 6.11 A scoping example. (part 2 of 3)

Page 38: 06 - Methods

296 Methods Chapter 6

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

Instance variable x (line 15) is declared and initialized to 1. This instance variable ishidden in any block (or method) that declares a variable named x. Method Scopingdeclares a local variable x (line 20) and initializes it to 5. This variable is displayed in theoutputLabel to show that the instance variable x is hidden in Scoping. The programdefines two other methods—MethodA and MethodB—that each take no arguments andreturn nothing. Each method is called twice from method Scoping. Method MethodAdefines variable x (line 52) and initializes it to 25. When MethodA is called, the variableis displayed in outputLabel, incremented and displayed again before exiting themethod. Each time this method is called, automatic variable x is recreated and initializedto 25. Method MethodB does not declare any variables. Therefore, when it refers to vari-able x, the instance variable x is used. When MethodB is called, the instance variable isdisplayed in outputLabel, multiplied by 10 and displayed again before exiting themethod. The next time method MethodB is called, the instance variable has its modifiedvalue, 10. Finally, the program displays the local variable x in Scoping again to showthat none of the method calls modified the value of x because the methods all referred tovariables in other scopes.

6.11 RecursionThe programs we have discussed are generally structured as methods that call one anotherin a disciplined, hierarchical manner. For some problems, it is useful to have methods callthemselves. A recursive method is a method that calls itself either directly or indirectlythrough another method. Recursion is an important topic discussed at length in upper-levelcomputer science courses. In this section and the next, simple examples of recursion arepresented. This book contains an extensive treatment of recursion.

We consider recursion conceptually first, then examine several programs containingrecursive methods. Recursive problem-solving approaches have a number of elements incommon. A recursive method is called to solve a problem. The method actually knows howto solve only the simplest case(s) or so-called base case(s). If the method is called with abase case, the method returns a result. If the method is called with a more complex problem,the method divides the problem into two conceptual pieces: a piece that the method knows

Fig. 6.11Fig. 6.11Fig. 6.11Fig. 6.11 A scoping example. (part 3 of 3)

Page 39: 06 - Methods

Chapter 6 Methods 297

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

how to do (base case) and a piece that the method does not know how to do. To make recur-sion feasible, the latter piece must resemble the original problem, but be a slightly simpleror slightly smaller version of the original problem. Because this new problem looks like theoriginal problem, the method invokes (calls) a fresh copy of itself to go to work on thesmaller problem—this is referred to as a recursive call and is also called the recursion step.The recursion step also normally includes the keyword return because its result will becombined with the portion of the problem the method knew how to solve to form a resultthat will be passed back to the original caller.

The recursion step executes while the original call to the method is still open (i.e., ithas not finished executing). The recursion step can result in many more recursive calls, asthe method divides each new subproblem into two conceptual pieces. For the recursion toeventually terminate, each time the method calls itself with a slightly simpler version of theoriginal problem, the sequence of smaller and smaller problems must converge on the basecase. At that point, the method recognizes the base case, returns a result to the previouscopy of the method and a sequence of returns ensues up the line until the original methodcall eventually returns the final result to the caller. This sounds exotic compared to the con-ventional problem solving we performed to this point. As an example of these concepts atwork, let us write a recursive program to perform a popular mathematical calculation.

The factorial of a nonnegative integer n, written n! (and pronounced “n factorial”), isthe product

n · ( n - 1 ) · ( n - 2 ) · … · 1

with 1! equal to 1 and 0! defined to be 1. For example, 5! is the product 5 · 4 · 3 · 2 · 1, whichis equal to 120.

The factorial of an integer, number, greater than or equal to 0, can be calculated iter-atively (nonrecursively) using for as follows:

factorial = 1;for ( int counter = number; counter >= 1; counter-- ) factorial *= counter;

A recursive definition of the factorial method is arrived at by observing the followingrelationship:

n! = n · (n - 1)!

For example, 5! is clearly equal to 5 * 4!, as is shown by the following:

5! = 5 · 4 · 3 · 2 · 15! = 5 · ( 4 · 3 · 2 · 1 )5! = 5 · ( 4! )

The evaluation of 5! would proceed as shown in Fig. 6.12. Figure 6.12a shows how thesuccession of recursive calls proceeds until 1! is evaluated to be 1, which terminates therecursion. Figure 6.12b shows the values returned from each recursive call to its caller untilthe final value is calculated and returned.

Page 40: 06 - Methods

298 Methods Chapter 6

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

Figure 6.13 uses recursion to calculate and print the factorials of the integers 0–10 (thechoice of the data type long will be explained momentarily). The recursive method Fac-torial first tests to see if a terminating condition is true (i.e., is number less than orequal to 1). If number is indeed less than or equal to 1, factorial returns 1, no furtherrecursion is necessary and the method returns. If number is greater than 1, line 45

return number * Factorial( number - 1 );

expresses the problem as the product of number and a recursive call to Factorial eval-uating the factorial of number - 1. Note that Factorial( number - 1 ) is a slightlysimpler problem than the original calculation Factorial( number ).

Fig. 6.12Fig. 6.12Fig. 6.12Fig. 6.12 Recursive evaluation of 5!.

5!

5 * 4!

4 * 3!

3 * 2!

2 * 1!

1

5!

5 * 4!

4 * 3!

3 * 2!

2 * 1!

1

(a) Procession of recursive calls. (b) Values returned from each recursive call.

Final value = 120

5! = 5 * 24 = 120 is returned

4! = 4 * 6 = 24 is returned

2! = 2 * 1 = 2 is returned

3! = 3 * 2 = 6 is returned

1 returned

1 // Fig 6.13: FactorialTest.cs2 // Recursive factorial method.34 using System;5 using System.Drawing;6 using System.Collections;7 using System.ComponentModel;8 using System.Windows.Forms;9

10 public class FactorialTest : System.Windows.Forms.Form11 {12 private System.ComponentModel.Container components = null;13 private System.Windows.Forms.Label outputLabel;1415 public FactorialTest()16 {17 InitializeComponent();1819 for ( long i = 0; i <= 10; i++ )20 outputLabel.Text += i + "! = " +

Fig. 6.13Fig. 6.13Fig. 6.13Fig. 6.13 Calculating factorials with a recursive method. (part 1 of 2)

Page 41: 06 - Methods

Chapter 6 Methods 299

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

Method Factorial (line 40) receives a parameter of type long and returns a resultof type long. As can be seen in Fig. 6.13, factorial values become large quickly. We chosedata type long so the program can calculate factorials greater than 20! Unfortunately, theFactorial method produces large values so quickly that even long does not help usprint many factorial values before the size of a long variable is exceeded.

We explore in the exercises that float and double may ultimately be needed by theuser desiring to calculate factorials of larger numbers. This points to a weakness in mostprogramming languages, namely that the languages are not easily extended to handle theunique requirements of various applications.

Common Programming Error 6.14Forgetting to return a value from a recursive method when one is needed results in a syntaxerror. 6.14

Common Programming Error 6.15Either omitting the base case or writing the recursion step incorrectly so that it does not con-verge on the base case will cause infinite recursion, eventually exhausting memory. This isanalogous to the problem of an infinite loop in an iterative (nonrecursive) solution. 6.15

21 Factorial( i ) + "\n";22 }2324 // Visual Studio.NET generated code2526 public long Factorial( long number )27 {28 if ( number <= 1 ) // base case29 return 1;30 else31 return number * Factorial( number - 1 );32 }3334 public static void Main()35 {36 Application.Run( new FactorialTest() );37 }38 }

Fig. 6.13Fig. 6.13Fig. 6.13Fig. 6.13 Calculating factorials with a recursive method. (part 2 of 2)

Page 42: 06 - Methods

300 Methods Chapter 6

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

6.12 Example Using Recursion: The Fibonacci Series The Fibonacci series

0, 1, 1, 2, 3, 5, 8, 13, 21, …

begins with 0 and 1 and has the property that each subsequent Fibonacci number is the sumof the previous two Fibonacci numbers.

The series occurs in nature and, in particular, describes a form of spiral. The ratio ofsuccessive Fibonacci numbers converges on a constant value of 1.618…. This number, too,repeatedly occurs in nature and has been called the golden ratio or the golden mean.Humans tend to find the golden mean aesthetically pleasing. Architects often design win-dows, rooms and buildings whose length and width are in the ratio of the golden mean.Postcards are often designed with a golden mean length/width ratio.

The Fibonacci series may be defined recursively as follows:

Fibonacci( 0 ) = 0Fibonacci( 1 ) = 1Fibonacci( n ) = Fibonacci( n – 1 ) + Fibonacci( n – 2 )

Note that there are two base cases for the Fibonacci calculation—fibonacci(0) is defined tobe 0 and fibonacci(1) is defined to be 1. The application of Fig. 6.14 calculates the ith Fi-bonacci number recursively using method Fibonacci. The user enters an integer in thefirst textfield indicating the ith Fibonacci number to calculate and clicks the calculate-Button (which displays the text Calculate Fibonacci) button. MethodcalculateButton_Click executes automatically in response to the user interfaceevent and calls recursive method Fibonacci to calculate the specified Fibonacci number.Notice that Fibonacci numbers tend to become large quickly. Therefore, we use data typelong for the parameter type and the return type in method Fibonacci. In Fig. 6.14, thescreen captures show the results of calculating several Fibonacci numbers. Once again,method InitializeComponent of this application creates the GUI components andattaches them to the application’s form.

The event handling in this example is similar to the event handling of the Craps appli-cation in Fig. 6.10. Remember, the this keyword enables the application to refer to itself.In this example, the user clicks calculateButton while typing in inputTextBox togenerate the action event. Automatically, a message is sent to the application (i.e., amethod—calculateButton_Click—is called on the application indicating that theuser of the program interacted with one of the program’s GUI components (calculate-Button). Remember that this button will not cause any action to execute if an event han-dler for this action is not defined.

1 // Fig 6.14: FibonacciTest.cs2 // Recursive fibonacci method.34 using System;5 using System.Drawing;6 using System.Collections;7 using System.ComponentModel;

Fig. 6.14Fig. 6.14Fig. 6.14Fig. 6.14 Recursively generating Fibonacci numbers.

Page 43: 06 - Methods

Chapter 6 Methods 301

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

8 using System.Windows.Forms;9

1011 public class FibonacciTest : System.Windows.Forms.Form12 {13 private System.ComponentModel.Container components;14 private System.Windows.Forms.Button calculateButton;15 private System.Windows.Forms.TextBox inputTextBox;16 private System.Windows.Forms.Label displayLabel;17 private System.Windows.Forms.Label promptLabel;1819 // Visual Studio.NET generated code2021 protected void calculateButton_Click (object sender, 22 System.EventArgs e)23 {24 int number = Int32.FromString( inputTextBox.Text );25 int fibonacciNumber = Fibonacci( number );26 displayLabel.Text = "Fibonacci Value is " + fibonacciNumber;27 }2829 public int Fibonacci( int number )30 {31 if ( number == 0 || number == 1 )32 return number;33 else34 return Fibonacci( number - 1 ) + Fibonacci( number - 2 );35 }3637 public static void Main()38 {39 Application.Run( new FibonacciTest() );40 }4142 }

Fig. 6.14Fig. 6.14Fig. 6.14Fig. 6.14 Recursively generating Fibonacci numbers.

Page 44: 06 - Methods

302 Methods Chapter 6

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

The call to Fibonacci (line 65) from calculateButton_Click is not a recur-sive call, but all subsequent calls to Fibonacci are recursive. Each time Fibonacci isinvoked, it immediately tests for the base case—number equal to 0 or 1 (line 71). If thisis true, number is returned (fibonacci(0) is 0 and fibonacci(1) is 1). Interestingly, ifnumber is greater than 1, the recursion step generates two recursive calls, each of whichis for a slightly simpler problem than the original call to Fibonacci. Figure 6.15 showshow method Fibonacci would evaluate Fibonacci(3)—we abbreviateFibonacci as F to make the figure more readable.

This figure raises some interesting issues about the order in which C# compilers willevaluate the operands of operators. This is a different issue from the order in which opera-tors are applied to their operands, namely the order dictated by the rules of operator prece-dence. From Fig. 6.15 it appears that while evaluating F(3), two recursive calls will bemade, namely F(2) and F(1). But in what order will these calls be made? Most program-mers assume the operands will be evaluated left to right. In C# this is true.

The C and C++ languages (on which many of C#’s features are based) do not specifythe order in which the operands of most operators (including +) are evaluated. Therefore,

Fig. 6.14Fig. 6.14Fig. 6.14Fig. 6.14 Recursively generating Fibonacci numbers.

Page 45: 06 - Methods

Chapter 6 Methods 303

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

the programmer can make no assumption in those languages about the order in which thesecalls execute. The calls could in fact execute F(2) first, then F(1), or the calls could exe-cute in the reverse order: F(1), then F(2). In this program and in most other programs,it turns out the final result would be the same. But in some programs the evaluation of anoperand may have side effects that could affect the final result of the expression.

The C# language specifies that the order of evaluation of the operands is left to right.Thus, the method calls are in fact F(2) first, then F(1).

Good Programming Practice 6.6Do not write expressions that depend on the order of evaluation of the operands of an oper-ator. This often results in programs that are difficult to read, debug, modify and maintain. 6.6

A word of caution is in order about recursive programs like the one we use here to gen-erate Fibonacci numbers. Each invocation of the Fibonacci method that does not matchone of the base cases (i.e., 0 or 1) results in two more recursive calls to the Fibonaccimethod. This rapidly gets out of hand. Calculating the Fibonacci value of 20 using the pro-gram in Fig. 6.14 requires 21,891 calls to the Fibonacci method; calculating theFibonacci value of 30 requires 2,692,537 calls to the Fibonacci method.

As you try larger values, you will notice that each consecutive Fibonacci number youask the applet to calculate results in a substantial increase in calculation time and numberof calls to the Fibonacci method. For example, the Fibonacci value of 31 requires4,356,617 calls and the Fibonacci value of 32 requires 7,049,155 calls. As you can see, thenumber of calls to Fibonacci is increasing quickly—1,664,080 additional calls betweenFibonacci of 30 and 31 and 2,692,538 additional calls between Fibonacci of 31 and 32. Thisdifference in number of calls made between Fibonacci of 31 and 32 is more than 1.5 timesthe difference for Fibonacci of 30 and 31. Problems of this nature humble even the world’smost powerful computers! Computer scientists study in the field of complexity theory howhard algorithms have to work to do their jobs. Complexity issues are discussed in detail inthe upper-level computer science curriculum course generally called “Algorithms.”

Fig. 6.15Fig. 6.15Fig. 6.15Fig. 6.15 Set of recursive calls to method fibonacci.

F( 3 )

F( 1 )F( 2 )

F( 1 ) F( 0 ) return 1

return 1 return 0

return +

+return

Page 46: 06 - Methods

304 Methods Chapter 6

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

Performance Tip 6.3Avoid Fibonacci-style recursive programs, which result in an exponential “explosion” ofcalls. 6.3

6.13 Recursion vs. IterationIn the previous sections, we studied two methods that can easily be implemented either re-cursively or iteratively. In this section we compare the two approaches and discuss why theprogrammer might choose one approach over the other in a particular situation.

Both iteration and recursion are based on a control structure: Iteration uses a repetitionstructure (such as for, while or do/while); recursion uses a selection structure (suchas if, if/else or switch). Both iteration and recursion involve repetition: Iterationexplicitly uses a repetition structure; recursion achieves repetition through repeated methodcalls. Iteration and recursion each involve a termination test: Iteration terminates when theloop-continuation condition fails; recursion terminates when a base case is recognized. Iter-ation with counter-controlled repetition and recursion each gradually approach termination:Iteration keeps modifying a counter until the counter assumes a value that makes the loop-continuation condition fail; recursion keeps producing simpler versions of the originalproblem until the base case is reached. Both iteration and recursion can occur infinitely: Aninfinite loop occurs with iteration if the loop-continuation test never becomes false; infiniterecursion occurs if the recursion step does not reduce the problem each time in a mannerthat converges on the base case.

Recursion has many negatives. It repeatedly invokes the mechanism, and consequentlythe overhead, of method calls. This can be expensive in both processor time and memoryspace. Each recursive call causes another copy of the method (actually, only the method’svariables) to be created; this can consume considerable memory. Iteration normally occurswithin a method, so the overhead of repeated method calls and extra memory assignmentis omitted. So why choose recursion?

Software Engineering Observation 6.13Any problem that can be solved recursively can also be solved iteratively (nonrecursively).A recursive approach is normally chosen in preference to an iterative approach when the re-cursive approach more naturally mirrors the problem and results in a program that is easierto understand and debug. Another reason to choose a recursive solution is that an iterativesolution may not be apparent. 6.13

Performance Tip 6.4Avoid using recursion in performance situations. Recursive calls take time and consume ad-ditional memory. 6.4

Common Programming Error 6.16Accidentally having a nonrecursive method call itself either directly or indirectly through an-other method can cause infinite recursion. 6.16

Most programming textbooks introduce recursion much later than we have done here.We feel that recursion is a sufficiently rich and complex topic that it is better to introduceit earlier and spread the examples over the remainder of the text.

Page 47: 06 - Methods

Chapter 6 Methods 305

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

Let us reconsider some observations we make repeatedly throughout the book. Goodsoftware engineering is important. High performance is often important. Unfortunately,these goals are often at odds with one another. Good software engineering is key tomaking more manageable the task of developing larger and more complex software sys-tems. High performance in these systems is key to realizing the systems of the future, whichwill place ever greater computing demands on hardware. Where do methods fit in here?

Software Engineering Observation 6.14Modularizing programs in a neat, hierarchical manner promotes good software engineering.But it has a price. 6.14

Performance Tip 6.5A heavily modularized program—as compared to a monolithic (i.e., one-piece) programwithout methods—makes potentially large numbers of method calls and these consume exe-cution time and space on a computer’s processor(s). But monolithic programs are difficultto program, test, debug, maintain and evolve. 6.5

So modularize your programs judiciously, always keeping in mind the delicate balancebetween performance and good software engineering.

6.14 Method OverloadingC# enables several methods of the same name to be defined as long as these methods havedifferent sets of parameters (based on the number of parameters, the types of the parametersand the order of the parameters). This is called method overloading. When an overloadedmethod is called, the C# compiler selects the proper method by examining the number,types and order of the arguments in the call. Method overloading is commonly used to cre-ate several methods with the same name that perform similar tasks, but on different datatypes.

Good Programming Practice 6.7Overloading methods that perform closely related tasks can make programs more readableand understandable. 6.7

Figure 6.16 uses overloaded method Square to calculate the square of an int andthe square of a double.

Overloaded methods are distinguished by their signature—a combination of themethod’s name and its parameter types. If the C# compiler only looked at method namesduring compilation, the code in Fig. 6.16 would be ambiguous—the compiler would notknow how to distinguish the two Square methods. Logically, the compiler uses longer“mangled” or “decorated” names that include the original method name, the types of eachparameter, the exact order of the parameters and the return type to determine if the methodsin a class are unique in that class. C# executes a “best-fit” algorithm for matching themethod being called. If first searches for all the methods that can be used in this context. It

Page 48: 06 - Methods

306 Methods Chapter 6

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

may seem that only one method would match, but remember that C# will execute implicitconversions on variables. Once all of these methods are found, the closest match is chosen.

1 // Fig 6.17: MethodOverload.cs2 // Using overloaded methods.34 using System;5 using System.Drawing;6 using System.Collections;7 using System.ComponentModel;8 using System.Windows.Forms;9

1011 public class MethodOverload : System.Windows.Forms.Form12 {13 14 private System.ComponentModel.Container components = null;15 private System.Windows.Forms.Label outputLabel;1617 public MethodOverload()18 {19 InitializeComponent();2021 outputLabel.Text = 22 "The square of integer 7 is " + Square( 7 ) +23 "\nThe square of double 7.5 is " + Square ( 7.5 );24 }2526 // Visual Studio.NET generated code2728 public int Square ( int x )29 {30 return x * x;31 }3233 public double Square ( double y )34 {35 return y * y;36 }37 public static void Main()38 {39 Application.Run( new MethodOverload() );40 }41 }

Fig. 6.16Fig. 6.16Fig. 6.16Fig. 6.16 Using overloaded methods.

Page 49: 06 - Methods

Chapter 6 Methods 307

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

For example, in Fig. 6.16, the compiler might use the logical name “square of int” forthe Square method that specifies an int parameter and “square of double” for theSquare method that specifies a double parameter. If a method Foo’s definition beginsas follows:

void Foo( int a, float b )

the compiler might use the logical name “foo of int and float.” If the parameters are speci-fied as follows:

void Foo( float a, int b )

the compiler might use the logical name “foo of float and int.” Note that the order of theparameters is important to the compiler. The preceding two Foo methods are considered tobe distinct by the compiler.

So far, the logical names of methods used by the compiler did not mention the returntypes of the methods. This is because methods cannot be distinguished by return type. Theprogram of Fig. 6.17 illustrates the compiler errors generated when two methods have thesame signature and different return types. Overloaded methods can have different returntypes, but must have different parameter lists. Also, overloaded methods need not have thesame number of parameters.

Common Programming Error 6.17Creating overloaded methods with identical parameter lists and different return types is asyntax error. 6.17

1 // Fig. 6.18: MethodOverload2.cs2 // Overloaded methods with identical signatures and3 // different return types.45 using System;67 public class MethodOverload28 {9 public int Square( double x )

10 {11 return x * x;12 }1314 public double Square( double y )15 {16 return y * y;17 }1819 static void Main()20 {21 int squareValue = 2;22 Square( squareValue );

Fig. 6.17Fig. 6.17Fig. 6.17Fig. 6.17 Compiler error messages generated from overloaded methods with identical parameter lists and different return types.

Page 50: 06 - Methods

308 Methods Chapter 6

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

SUMMARY• The best way to develop and maintain a large program is to construct it from small, simple pieces

or modules. This technique is called divide and conquer.

• Modules in C# are called methods and classes.

• C# programs are written by combining new methods and classes the programmer writes with “pre-packaged” methods and classes available in the .NET Framework Library and in various othermethod and class libraries.

• The .NET Framework Library provides a rich collection of classes and methods for performingcommon mathematical calculations, string manipulations, character manipulations, input/output,error checking and many other useful operations.

• The programmer can write methods to define specific tasks that may be used at many points in aprogram. These are sometimes referred to as programmer-defined methods.

• The actual statements defining the method are written only once and these statements are hiddenfrom other methods.

• Methods are called by writing the name of the method (sometimes preceded by the class name anda dot operator) followed by a left parenthesis followed by the argument (or a comma-separated listof arguments) of the method followed by a right parenthesis.

• All variables declared in method definitions are local variables—they are known only in the meth-od in which they are defined.

• Packaging code as a method allows that code to be executed from several locations in a programby calling the method.

• The return statement in a method is used to pass the results of the method back to the main pro-gram.

• The format of a method definition is

attributes modifiers return-value-type method-name( parame-ter-list ){ declarations and statements}

23 }24 }

Fig. 6.17Fig. 6.17Fig. 6.17Fig. 6.17 Compiler error messages generated from overloaded methods with identical parameter lists and different return types.

Page 51: 06 - Methods

Chapter 6 Methods 309

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

• The first line of a method definition is sometimes known as the method header. The attributes andmodifiers in the method header are used to specify extra information about the method.

• The return-value-type is the data type of the result returned from the method to the caller. Methodscan return at most one value.

• The parameter-list is a comma-separated list containing the declarations of the parameters re-ceived by the method when it is called. There must be one argument in the method call for eachparameter in the method definition.

• The declarations and statements within the braces after the method header form the method body.

• Variables can be declared in any block and blocks can be nested.

• A method cannot be defined inside another method.

• Methods in the same class definition are both the methods defined in that class and the inheritedmethods.

• In many cases, argument values that do not correspond precisely to the parameter types in themethod definition are converted to the proper type before the method is called.

• When an argument is passed call-by-value, a copy of the argument’s value is made and passed tothe called method.

• With call-by-reference, the caller gives the called method the ability to directly access the caller’sdata and to modify that data if the called method so chooses.

• The class Random can be used to generate random numbers which are often used in applications.

• An event is a signal that is sent when some action takes place, such as a button being clicked, or avalue being changed. The programmer writes the application to perform certain tasks when theseevents occur. An event handler is a method that is executed (called) when a certain event occurs(sometimes we say an event is raised).

• A class can inherit existing attributes and behaviors (data and methods) from another class speci-fied to the right of operator : in the class definition.

• An identifier’s duration (also called its lifetime) is the period during which that identifier exists inmemory.

• Identifiers that represent local variables in a method (i.e., parameters and variables declared in themethod body) have automatic duration. Automatic duration variables are created when programcontrol reaches their declaration, they exist while the block in which they are declared is activeand they are destroyed when the block in which they are declared is exited.

• The scope (sometimes called a declaration space) of an identifier for a variable, reference or meth-od is the portion of the program in which the identifier can be referenced.

• A local variable or reference declared in a block can be used only in that block or in blocks nestedwithin that block.

• Members of a class have class scope, and are visible in what is known as the declaration space ofa class.

• Class scope enables methods of a class to directly invoke all members defined in that same classor inherited into that class (static members are an exception to this rule).

• Any variable declared in the initialization portion of the for header will only be visible withinthat for structure.

• A recursive method is one that calls itself either directly or indirectly through another method.

• A recursive method actually knows how to solve only the simplest case(s) or so-called basecase(s). If the method is called with a base case, the method returns a result. If the method is called

Page 52: 06 - Methods

310 Methods Chapter 6

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

with a more complex problem, the method divides the problem into two conceptual pieces: a piecethat the method knows how to do (base case) and a piece that the method does not know how to do.

• To make recursion feasible, the portion of the problem that the method does not know how to domust resemble the original problem, but be a slightly simpler or slightly smaller version of theoriginal problem.

• Certain recursive functions can lead to exponential "explosive" calls that the compiler or computercannot handle.

• Both iteration and recursion are based on a control structure: Iteration uses a repetition structure(such as for, while or do/while); recursion uses a selection structure (such as if, if/elseor switch).

• Both iteration and recursion involve repetition: Iteration explicitly uses a repetition structure; re-cursion achieves repetition through repeated method calls.

• Iteration and recursion each involve a termination test: Iteration terminates when the loop-contin-uation condition fails; recursion terminates when a base case is recognized.

• Both iteration and recursion can occur infinitely: An infinite loop occurs with iteration if the loop-continuation test never becomes false; infinite recursion occurs if the recursion step does not re-duce the problem each time in a manner that converges on the base case.

• A recursive approach is normally chosen in preference to an iterative approach when the recursiveapproach more naturally mirrors the problem and results in a program that is easier to understandand debug.

• C# enables several methods of the same name to be defined as long as these methods have differentsets of parameters (based on the number of parameters, the types of the parameters and the orderof the parameters). This is called method overloading.

• Method overloading is commonly used to create several methods with the same name that performsimilar tasks, but on different data types.

• C# executes a “best-fit” algorithm for matching the method being called.

TERMINOLOGY. (dot operator)argument to a method callarrayattributeautomatic durationautomatic initialization of a variablebase case(s)block scopeButton classcall-by-referencecall-by-valuecalling methodcast operatorclassclass scopeClick eventcoercion of argumentscomma-separated list of argumentscomplexity theory

Page 53: 06 - Methods

Chapter 6 Methods 311

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

computer-assisted instruction (CAI)concatenateconstant variablecontinue statementcontrol structures in iterationcontrol structures in recursionconvergencedeclarationdivide-and-conquer approachduration of an identifierevent handlingexhausting memoryexponential “explosion” of callsfactorial methodFibonacci series defined recursivelygolden ratiohierarchical structureinfinite loopinfinite recursioninheritanceinstance variables of a classinterfaceinvokeiterationlifetime of an identifierlocal variablemethodmethod bodymethod callmethod overloadingmixed-type expressionmodifiermodularizing a program with methodsmonolithic programnamed constantnested blocknested control structurenullout parameteroverloaded methodparameter listprecedenceprinciple of least privilegeprogrammer-defined methodpromotions for primitive data typesRandom classread-only variablerecursive evaluationrecursive methodref parameter

Page 54: 06 - Methods

312 Methods Chapter 6

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

return keywordreturn-value-typescaling factorscope of an identifiersequence of random numbersshifting valueside effectsignaturesimulationsingle-line statementsoftware reusabilitystackstatic durationtermination testuser interface eventvoid return-value-type

SELF-REVIEW EXERCISES6.1 Answer each of the following:

a) Program modules in C# are called ________ and________.b) A method is invoked with a ________.c) A variable known only within the method in which it is defined is called a ________.d) The ________ statement in a called method can be used to pass the value of an expres-

sion back to the calling method.e) The keyword ________ is used in a method header to indicate that a method does not

return a value.f) The ________ of an identifier is the portion of the program in which the identifier can

be used.g) The three ways to return control from a called method to a caller are ________,

________ and ________.h) The method is used to produce random numbers.i) Variables declared in a block or in a method’s parameter list are of ________ duration.j) A method that calls itself either directly or indirectly is a ________ method.k) A recursive method typically has two components: one that provides a means for the re-

cursion to terminate by testing for a ________ case and one that expresses the problemas a recursive call for a slightly simpler problem than the original call.

l) In C#, it is possible to have various methods with the same name that each operate ondifferent types and/or numbers of arguments. This is called method ________.

m) Local variables declared at the beginning of a method have ________ scope, as domethod parameters which are considered local variables of the method.

n) Iteration is based on a control structure: it uses a ________ structure. o) Recursion is based on a control structure: it uses a ________ structure.p) Recursion achieves repetition through repeated ________ calls. q) The best way to develop and maintain a large program is to divide it into several smaller

program ________ each of which is more manageable than the original program. r) It is possible to define methods with the same ________ but different parameter lists. s) Recursion terminates when a ________ is reached. t) Placing a semicolon after the right parenthesis enclosing the parameter list of a method

definition is a ________ error.

Page 55: 06 - Methods

Chapter 6 Methods 313

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

u) The ________ is a comma-separated list containing the declarations of the parametersreceived by the method when it is called.

v) The ________ is the data type of the result returned from the method to the called. w) A ________ is a signal that is sent when some action takes place, such as a button being

clicked or a value being changed.

6.2 State whether each of the following is true or false. If false, explain why.a) Math method Abs rounds its parameter to the smallest integer.

b) Math method Exp is the exponential method, ex. c) Variable type float can be promoted to type double. d) Variable type char cannot be promoted to type int.e) The line Application.Run appears at least once in every C# windows application.f) A recursive method is one that calls itself.g) When a method recursively calls itself it is known as the base case. h) 0! Is equal to 1.i) Forgetting to return a value from a recursive method when one is needed results in a syn-

tax error. j) Infinite recursion occurs when a method converges on the base case.k) A recursive implementation of the Fibonacci method is always efficient.l) Any problem that can be solved recursively can also be solved iteratively.

6.3 For the following program, state the scope (either class scope or block scope) of each of thefollowing elements.

a) The variable x.b) The variable y.c) The method cube.d) The method paint.e) The variable yPos.

public class CubeTest { int x;

public void paint() { int yPos = 25;

for ( x = 1; x <= 10; x++ ) { Console.WriteLine( x ); yPos += 15; } }

public int cube( int y ) { return y * y * y; }}

6.4 Write an application that tests if the examples of the math library method calls shown inFigure 6.2 actually produce the indicated results.

6.5 Give the method header for each of the following methods.a) Method hypotenuse, which takes two double-precision, floating-point arguments

side1 and side2 and returns a double-precision, floating-point result.

Page 56: 06 - Methods

314 Methods Chapter 6

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

b) Method smallest, which takes three integers, x, y, z and returns an integer.c) Method instructions, which does not take any arguments and does not return a val-

ue. [Note: Such methods are commonly used to display instructions to a user.]d) Method intToFloat, which takes an integer argument, number and returns a float-

ing-point result.

6.6 Find the error in each of the following program segments and explain how the error can becorrected:

e) int g() { Console.WriteLine( "Inside method g" ); int h() { Console.WriteLine( "Inside method h" ); }}

f) int sum( int x, int y ) { int result; result = x + y;}

g) int sum( int n ) { if ( n == 0 ) return 0; else n + sum( n - 1 );}

h) void f( float a ); { float a; Console.WriteLine( a );}

i) void product() { int a = 6, b = 5, c = 4, result; result = a * b * c; Console.WriteLine( "Result is " + result ); return result;}

ANSWERS TO SELF-REVIEW EXERCISES6.1 a) Methods and classes. b) Method call. c) Local variable. d) return. e) void. f) Scope.g) return; or return expression; or encountering the closing right brace of a method. h) Ran-dom.Next. i) Automatic. j) Recursive. k) Base. l) Overloading. m) Block . n) Repetition. o) Se-lection. p) Method. q) Modules . r) Name. s) Base case. t) Syntax. u) Parameter list. v) Return-value-type. w) event.

6.2 a) False. Math method Abs returns the absolute value of a number. b) True c) True d) False.Type char can be promoted to int, float, long, and double. e) True f) True g) False. When amethod recursively calls itself it is known as the recursive call or recursion step. h) True i) True j)False. Infinite recursion will occur when a recursive method does not converge on the base case. k)False. Recursion repeatedly invokes the mechanism, and consequently the overhead, of method calls.l) True

6.3 a) Class scope. b) Block scope. c) Class scope. d) Class scope. e) Block scope.

6.4 The following code demonstrates the use of some Math library method calls:

Page 57: 06 - Methods

Chapter 6 Methods 315

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

1 // Exercise 6.3: MathTest.cs2 // Testing the Math class methods34 public class MathTest {5 public static void Main( String [] args )6 {7 Console.WriteLine( "Math.Abs( 23.7 ) = " +8 Math.Abs( 23.7 ) );9 Console.WriteLine( "Math.Abs( 0.0 ) = " +

10 Math.Abs( 0.0 ) );11 Console.WriteLine( "Math.Abs( -23.7 ) = " +12 Math.Abs( -23.7 ) );13 Console.WriteLine( "Math.Ceiling( 9.2 ) = " +14 Math.Ceiling( 9.2 ) );15 Console.WriteLine( "Math.Ceiling( -9.8 ) = " +16 Math.Ceiling( -9.8 ) );17 Console.WriteLine( "Math.Cos( 0.0 ) = " +18 Math.Cos( 0.0 ) );19 Console.WriteLine( "Math.Exp( 1.0 ) = " +20 Math.Exp( 1.0 ) );21 Console.WriteLine( "Math.Exp( 2.0 ) = " +22 Math.Exp( 2.0 ) );23 Console.WriteLine( "Math.Floor( 9.2 ) = " +24 Math.Floor( 9.2 ) );25 Console.WriteLine( "Math.Floor( -9.8 ) = " +26 Math.Floor( -9.8 ) );27 Console.WriteLine( "Math.Log( 2.718282 ) = " +28 Math.Log( 2.718282 ) );29 Console.WriteLine( "Math.Log( 7.389056 ) = " +30 Math.Log( 7.389056 ) );31 Console.WriteLine( "Math.Max( 2.3, 12.7 ) = v +32 Math.Max( 2.3, 12.7 ) );33 Console.WriteLine( "Math.Max( -2.3, -12.7 ) = " +34 Math.Max( -2.3, -12.7 ) );35 Console.WriteLine( "Math.Min( 2.3, 12.7 ) = " +36 Math.Min( 2.3, 12.7 ) );37 Console.WriteLine( "Math.Min( -2.3, -12.7 ) = " +38 Math.Min( -2.3, -12.7 ) );39 Console.WriteLine( "Math.Pow( 2, 7 ) = " +40 Math.Pow( 2, 7 ) );41 Console.WriteLine( "Math.Pow( 9, .5 ) = " +42 Math.Pow( 9, .5 ) );43 Console.WriteLine( "Math.Sin( 0.0 ) = " +44 Math.Sin( 0.0 ) );45 Console.WriteLine( "Math.Sqrt( 25.0 ) = " +46 Math.Sqrt( 25.0 ) );47 Console.WriteLine( "Math.Tan( 0.0 ) = " +48 Math.Tan( 0.0 ) );49 }50 }

Page 58: 06 - Methods

316 Methods Chapter 6

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

6.5 a) double hypotenuse( double side1, double side2 )b) int smallest( int x, int y, int z )c) void instructions()d) float intToFloat( int number )

6.6 a) Error: Method h is defined in method g.Correction: Move the definition of h out of the definition of g.

b) Error: The method is supposed to return an integer, but does not.Correction: Delete variable result and place the following statement in the method: return x + y;or add the following statement at the end of the method body: return result;

c) Error: The result of n + sum(n - 1) is not returned by this recursive method, resultingin a syntax error.Correction: Rewrite the statement in the else clause as return n + sum(n - 1);

d) Error: The semicolon after the right parenthesis that encloses the parameter list and re-defining the parameter a in the method definition are each incorrect.Correction: Delete the semicolon after the right parenthesis of the parameter list and de-lete the declaration float a;.

e) Error: The method returns a value when it is not supposed to.Correction: Change the return type to int.

EXERCISES6.7 What is the value of x after each of the following statements is performed?

a) x = Math.Abs( 7.5 );b) x = Math.Floor( 7.5 );c) x = Math.Abs( 0.0 );

Math.Abs( 23.7 ) = 23.7Math.Abs( 0.0 ) = 0Math.Abs( -23.7 ) = 23.7Math.Ceiling( 9.2 ) = 10Math.Ceiling( -9.8 ) = -9Math.Cos( 0.0 ) = 1Math.Exp( 1.0 ) = 2.71828Math.Exp( 2.0 ) = 7.38906Math.Floor( 9.2 ) = 9Math.Floor( -9.8 ) = -10Math.Log( 2.718282 ) = 1Math.Log( 7.389056 ) = 2Math.Max( 2.3, 12.7 ) = 12.7Math.Max( -2.3, -12.7 ) = -2.3Math.Min( 2.3, 12.7 ) = 2.3Math.Min( -2.3, -12.7 ) = -12.7Math.Pow( 2, 7 ) = 128Math.Pow( 9, .5 ) = 3Math.Sin( 0.0 ) = 0Math.Sqrt( 25.0 ) = 5Math.Tan( 0.0 ) = 0

Page 59: 06 - Methods

Chapter 6 Methods 317

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

d) x = Math.Ceiling( 0.0 );e) x = Math.Abs( -6.4 );f) x = Math.Ceiling( -6.4 );g) x = Math.Ceiling( -Math.Abs( -8 + Math.Floor( -5.5 ) ) );

6.8 A parking garage charges a $2.00 minimum fee to park for up to three hours. The garagecharges an additional $0.50 per hour for each hour or part thereof in excess of three hours. The max-imum charge for any given 24-hour period is $10.00. Assume that no car parks for longer than 24hours at a time. Write a program that calculates and displays the parking charges for each customerwho parked a car in this garage yesterday. You should enter in a TextBox the hours parked for eachcustomer. The program should display the charge for the current customer. The program should usethe method calculateCharges to determine the charge for each customer. Use the techniquesdescribed in the chapter to read the double value from a TextBox.

6.9 Write a method integerPower( base, exponent ) that returns the value of

base exponent

For example, integerPower( 3, 4 ) = 3 * 3 * 3 * 3. Assume that exponent is a positive,nonzero integer and base is an integer. Method integerPower should use for or while tocontrol the calculation. Do not use any Math library methods. Incorporate this method into an appletthat reads integer values from TextBoxs for base and exponent from the user and performs thecalculation with the integerPower method.

6.10 Define a method hypotenuse that calculates the length of the hypotenuse of a right trian-gle when the other two sides are given. The method should take two arguments of type double andreturn the hypotenuse as a double. Incorporate this method into an applet that reads integer valuesfor side1 and side2 from TextBoxs and performs the calculation with the hypotenuse meth-od. Determine the length of the hypotenuse for each of the following triangles.

6.11 Write a method squareOfAsterisks that displays a solid square of asterisks whose sideis specified in integer parameter side. For example, if side is 4, the method displays

****************

Incorporate this method into an application that reads an integer value for side from the user at thekeyboard and performs the drawing with the squareOfAsterisks method. Note that thismethod should gather data from Textboxes and should print to a label.

6.12 Modify the method created in Exercise 6.18 to form the square out of whatever character iscontained in character parameter fillCharacter. Thus if side is 5 and fillCharacter is“#”, this method should print

Triangle Side 1 Side 2

1 3.0 4.0

2 5.0 12.0

3 8.0 15.0

Fig. 6.18Fig. 6.18Fig. 6.18Fig. 6.18

Page 60: 06 - Methods

318 Methods Chapter 6

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

#########################

6.13 Write an application that simulates coin tossing. Let the program toss the coin each time theuser presses the “Toss” button. Count the number of times each side of the coin appears. Display theresults. The program should call a separate method flip that takes no arguments and returns falsefor tails and true for heads. [Note: If the program realistically simulates the coin tossing, each sideof the coin should appear approximately half the time.]

6.14 Computers are playing an increasing role in education. Write a program that will help an el-ementary school student learn multiplication. Use the Next method from an object of type Randomto produce two positive one-digit integers. It should then display a question in the status bar such as

How much is 6 times 7?

The student then types the answer into a TextBox. Your program checks the student's answer. If itis correct, draw the string "Very good!" in a read-only TextBox, then ask another multiplica-tion question. If the answer is wrong, draw the string "No. Please try again." in the sameread-only TextBox, then let the student try the same question again repeatedly until the studentfinally gets it right. A separate method should be used to generate each new question. This methodshould be called once when the applet begins execution and each time the user answers the questioncorrectly.

6.15 (Towers of Hanoi) Every budding computer scientist must grapple with certain classic prob-lems and the Towers of Hanoi (Fig. 6.19) is one of the most famous of these. Legend has it that in atemple in the Far East, priests are attempting to move a stack of disks from one peg to another. Theinitial stack had 64 disks threaded onto one peg and arranged from bottom to top by decreasing size.The priests are attempting to move the stack from this peg to a second peg under the constraints thatexactly one disk is moved at a time and at no time may a larger disk be placed above a smaller disk.A third peg is available for temporarily holding disks. Supposedly, the world will end when the priestscomplete their task, so there is little incentive for us to facilitate their efforts.

Let us assume that the priests are attempting to move the disks from peg 1 to peg 3. We wish todevelop an algorithm that will print the precise sequence of peg-to-peg disk transfers.

If we were to approach this problem with conventional methods, we would rapidly find our-selves hopelessly knotted up in managing the disks. Instead, if we attack the problem with recursionin mind, it immediately becomes tractable. Moving n disks can be viewed in terms of moving onlyn – 1 disks (and hence the recursion) as follows:

a) Move n – 1 disks from peg 1 to peg 2, using peg 3 as a temporary holding area.b) Move the last disk (the largest) from peg 1 to peg 3.c) Move the n – 1 disks from peg 2 to peg 3, using peg 1 as a temporary holding area.

The process ends when the last task involves moving n = 1 disk (i.e., the base case). This isaccomplished by trivially moving the disk without the need for a temporary holding area.

Write an applet to solve the Towers of Hanoi problem. Allow the user to enter the number ofdisks in a TextBox. Use a recursive tower method with four parameters:

a) The number of disks to be movedb) The peg on which these disks are initially threadedc) The peg to which this stack of disks is to be movedd) The peg to be used as a temporary holding area

Page 61: 06 - Methods

Chapter 6 Methods 319

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

Your program should display in a read-only TextBox with scrolling functionality the preciseinstructions it will take to move the disks from the starting peg to the destination peg. For example,to move a stack of three disks from peg 1 to peg 3, your program should print the following series ofmoves:

1 → 3 (This means move one disk from peg 1 to peg 3.)

1 → 2

3 → 2

1 → 3

2 → 1

2 → 3

1 → 3

6.16 The greatest common divisor of integers x and y is the largest integer that evenly dividesboth x and y. Write a recursive method gcd that returns the greatest common divisor of x and y. Thegcd of x and y is defined recursively as follows: If y is equal to 0, then gcd( x, y ) is x; otherwise,gcd( x, y ) is gcd( y, x % y ), where % is the modulus operator. Use this method to replace theone you wrote in the applet of Exercise 6.28.

Fig. 6.19Fig. 6.19Fig. 6.19Fig. 6.19 The Towers of Hanoi for the case with four disks.

Page 62: 06 - Methods

Chapter 6 Methods 327

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

[***Notes To Reviewers***]Questions:

• Is "coercion of terms" an actual phrase in C#?

• We are unsure if this sentence is true for C#:

The type of each value in a mixed-type expression is promoted to the “highest” type inthe expression (actually, a temporary version of each value is created and used for theexpression—the original values remain unchanged).

Comments:

• Please mark your comments in place on a paper copy of the chapter.

• Please return only marked pages to Deitel & Associates, Inc.

• Please do not send us e-mails with detailed, line-by-line comments; mark these directly on the pa-per pages.

• Please feel free to send any lengthy additional comments by e-mail to [email protected].

• Please run all the code examples.

• Please check that we are using the correct programming idioms.

• Please check that there are no inconsistencies, errors or omissions in the chapter discussions.

• The manuscript is being copyedited by a professional copy editor in parallel with your reviews.That person will probably find most typos, spelling errors, grammatical errors, etc.

• Please do not rewrite the manuscript. We are concerned mostly with technical correctness and cor-rect use of idiom. We will not make significant adjustments to our writing style on a global scale.Please send us a short e-mail if you would like to make such a suggestion.

• Please be constructive. This book will be published soon. We all want to publish the best possiblebook.

• If you find something that is incorrect, please show us how to correct it.

• Please read all of the back matter including the exercises and any solutions we provide.

• Please review the index we provide with each chapter to be sure we have covered the topics youfeel are important.

Page 63: 06 - Methods

Index 1

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

Symbols. (dot operator) 262

AA scoping example. 294Abs method in class Math 263absolute value 263ActionEvent parameter 323algorithm 303Allowed promotions for primitive

data types. 272application’s form 300area of a circle 326argument 261, 262argument to a method call 267attribute 267automatic duration 293automatic initialization of a

variable 293automatic variables must be

initialized 293

Bbase case(s) 296, 302, 303Base Class Library or BCL 260block 268block is exited 293block scope 293blocks nested 293bool promotions 272bool variables initialized to

false 293braces ({ and }) 267break statement 293Button class 292byte promotions 272

CCalculating factorials with a

recursive method. 298call-by-reference 273call-by-value 273called method 261caller 261calling method 261casino 276, 286cast operator 272Ceil method in class Math 263Celsius equivalent of a Fahrenheit

temperature 323chance 276char promotions 272class 260

class scope 293closing right brace (}) 321coercion of arguments 271coersion of arguments 272coin tossing 276, 318comma-separated list 268comma-separated list of

arguments 261Commonly used Math class

methods. 263Compiler error messages

generated from overloaded methods. 307

complexity theory 303computer-assisted instruction

(CAI) 324computers in education 324concatenate 267constant variable 320consume memory 304continue statement 293control structures in iteration 304control structures in recursion 304converge on a base case 297converting an integral value to a

floating-point value 272copy of an argument 273Cos method in class Math 263cosine 263counter-controlled repetition 304craps 286craps program 326craps table 276CrapsGame.cs 286

Ddecimal promotions 272declaration 267Demonstrating ref and out

parameters. 274dice game 286digits reversed 323divide-and-conquer approach

260, 264dot (.) operator 262Double class 291double promotions 272Double.Format method 262Double.FromString method

271duration 293

Eelement of chance 276

equal likelihood 277event 281event handling 281Examples

A scoping example. 294Allowed promotions for

primitive data types. 272Calculating factorials with a

recursive method. 298Commonly used Math class

methods. 263Compiler error messages

generated from overloaded methods. 307CrapsGame.cs 286Demonstrating ref and out

parameters. 274FactorialTest.cs 298FibonacciTest.cs 300Hierarchical boss method/

worker method relationship. 262MaximumValue.cs 270MethodOverload.cs 306MethodOverload2.cs

307Program to simulate the game

of craps. 286Programmer-defined Maxi-mum method. 270RandomInt.cs 277Recursive evaluation of 5!. 298

Recursively generating Fibonacci numbers. 300RefOutTest.cs 274RollDie.cs 277RollDie2.cs 281Rolling dice in a windows

application. 277Scoping.cs 294Set of recursive calls to

method fibonacci. 303Shifted random integers. 277Simulating rolling 12 six-sided

dice. 281Using overloaded methods. 306

exhausting memory 299Exp method in class Math 263exponential “explosion” of calls

304exponential method 263exponentiation 263extending a class 292

Page 64: 06 - Methods

2 Index

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

Ffactorial 297factorial method 297FactorialTest.cs 298Fahrenheit equivalent of a Celsius

temperature 323Fibonacci method 302Fibonacci numbers 303Fibonacci series 300Fibonacci series defined

recursively 300FibonacciTest.cs 300fillRect method of the Graphics

class 322final 320float promotions 272Floor method in class Math 263Form class 269Format method in class Double

262FromString method 262FromString method in class

Double 271

Ggambling casino 276game playing 276game-playing program 276getSource() method 323golden mean 300golden ratio 300greatest common divisor (GCD)

319, 325GroupBox class 292“guess the number” game 324

H“hiding” of implementation details

261hierarchical boss method/worker

method relationship 261Hierarchical boss method/worker

method relationship. 262hierarchical structure 261hypotenuse of a right triangle 317

Iidentifier’s duration 293identifier’s scope 293infinite loop 299infinite recursion 299, 304inheritance 292init method 300

InitializeComponent method 300

inner block 294instance variables of a class 293int promotions 272Int32.FromString method

262interface 281interface ActionListener 320invoke 262iteration 304iterative 299

JJava APIs 259

LLabel class 292lifetime of an identifier 293likelihood 277local variable 264, 268, 293,

296local variables of a method 294Log method in class Math 263logarithm 263long promotions 272

Mmake your point 286mangled or decorated names 305Math class methods 261Math class methods 263math library method 326Math.Abs method 263Math.Ceil method 263Math.Cos method 263Math.E 263Math.Exp method 263Math.floor 315Math.Floor method 263Math.Log method 263Math.Max method 263Math.max method 271Math.Min method 263Math.PI 263Math.Pow method 263Math.random 322Math.Sin method 263Math.Sqrt method 262, 263,

270Math.Tan method 263Max method in class Math 263MaximumValue.cs 270

message dialog 280MessageBox.Show method

262method 260method attribute 267method body 268method call 261method call operator 267method factorial 298method fillRect 322method hypotenuse 317method integerPower 317method modifier 267method overloading 305method power 325method scope 293MethodOverload.cs 306MethodOverload2.cs 307Min method in class Math 263mixed-type expression 272, 320,

327modifier 267modularizing a program with

methods 264module 260modules in C# 260monolithic program 305

Nnamed constant 320natural logarithm 263nested block 293.NET Framework 260.NET Framework Library 260Next method in class Random

276nonrecursive method call 304null 293

Oobject promotions 272one-armed bandit 276opening left brace ({) 321operator precedence 302out parameter 274outer block 294overhead of recursion 304overloaded method 305overloading 305

Pparameter 264, 267parameter list 268

Page 65: 06 - Methods

Index 3

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 7/24/01

pass-by-reference 273pass-by-value 273perfect number 323PictureBox class 292player’s point 286Pow method in class Math 263power 263, 323precedence 302prime 323primitive (or built-in) data type

272, 293primitive data types are initialized

to null 293principle of least privilege 294probability 276Program to simulate the game of

craps. 286programmer-defined maximum

method 270Programmer-defined Maximum

method. 270programmer-defined method 261promotion rules 271

Rradians 263radius of a circle 326Random 291Random class 276, 291RandomInt.cs 277ratio of successive Fibonacci

numbers 300read-only variable 320recursion overhead 304recursion step 297, 302recursion vs. iteration 304recursive call 297, 302, 303Recursive evaluation 298recursive evaluation 298Recursive evaluation of 5!. 298recursive method 296, 299recursive method factorial 298recursive method power 325recursive program 303recursively generating Fibonacci

numbers 303Recursively generating Fibonacci

numbers. 300ref parameter 274RefOutTest.cs 274"reinventing the wheel" 261repetition structure for iteration

304return 261return keyword 297

return statement 267, 268, 269

return-value-type 267RollDie.cs 277RollDie2.cs 281Rolling dice in a windows

application. 277round 263round a number to a specific

decimal place 321rounding 321rounding a value to the nearest

integer 321rounding errors 272rules of operator precedence 302

Ssbyte promotions 272scaling 277scaling factor 277, 286scope 293scope (block) 293scope (class) 293scope of an identifier 293Scoping.cs 294selection structure for recursion

304Set of recursive calls to method

fibonacci. 303shift 277Shifted random integers. 277shifting value 286short promotions 272Show method in class Message-

Box 262side effect 303signature 305, 307simulate coin tossing 318Simulating rolling 12 six-sided

dice. 281simulation 276Sin method in class Math 263sine 263small method 269software reusability 264spiral 300Sqrt method 262Sqrt method in class Math 263,

270square root 263stack 318statement 267static duration 293string promotions 272System namespace 262, 291

System.WinForms namespace 292

TTan method in class Math 263tangent 263terminating right brace (}) of a

block 294termination test 304ToInt32 method 262, 264Towers of Hanoi 318trigonometric cosine 263trigonometric sine 263trigonometric tangent 263

Uuint promotions 272ulong promotions 272uppercase letters in the names of

final variables 320user interface event 300ushort promotions 272Using overloaded methods. 306

Vvalue to the nearest integer 321video game 276Visualizing Recursion 325void return-value-type 268