454683
454683
454683
Programming in C#
Online module to accompany Invitation to Computer Science, 7th Edition, ISBN-10:
1305075773; ISBN-13: 9781305075771 (Cengage Learning, 2016).
1. Introduction to C#
1.1 A Simple C# Program
1.2 Creating and Running a C# Program
2. Virtual Data Storage
3. Statement Types
3.1 Input/Output Statements
3.2 The Assignment Statement
3.3 Control Statements
4. Another Example
5. Managing Complexity
5.1 Divide and Conquer
5.2 Using Functions
5.3 Writing Functions
6. Object-Oriented Programming
6.1 What Is It?
6.2 C# and OOP
6.3 One More Example
6.4 What Have We Gained?
7. Graphical Programming
7.1 Graphics Hardware
7.2 Graphics Software
8. Conclusion
EXERCISES
ANSWERS TO PRACTICE PROBLEMS
1
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 2
1 Introduction to C#
Hundreds of high-level programming languages have been developed;
a fraction of these have become viable, commercially successful languages.
There are a half-dozen or so languages that can illustrate some of the concepts
of a high-level programming language, but this module uses C# for this purpose.
The C# language was developed by Microsoft along with the .NET environment.
C# is the programming language, and .NET is the runtime support environment.
Our intent here is not to make you an expert programmerany more than
our purpose in Chapter 4 was to make you an expert circuit designer. Indeed,
there is much about the language that we will not even discuss. You will,
however, get a sense of what programming in a high-level language is like, and
perhaps you will see why some people think it is one of the most fascinating
of human endeavors.
FIGURE 1
A Simple C# Program //Computes and outputs travel time
//for a given speed and distance
//Written by J. Q. Programmer, 6/15/16
using System;
namespace InvitationCSharp
{
class TravelPlanner
{
static void Main(string[] args)
{
int speed; //rate of travel
double distance; //miles to travel
double time; //time needed for this travel
2 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 3
FIGURE 1
A Simple C# Program Console.Write(Enter your distance in miles: );
(continued) distance = Convert.ToDouble(Console.ReadLine());
Someone running this program (the user) could have the following
dialogue with the program, where boldface indicates what the user types:
FIGURE 2
The Overall Form of a Typical prologue comment [optional]
C# Program using directive
namespace
{
class
{
functions [optional]
Main function
{
declarations [optional]
Main function body
}
}
}
1 Introduction to C# 3
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 4
FIGURE 3
The Program of Figure 1 1. //Computes and outputs travel time
(line numbers added for 2. //for a given speed and distance
reference) 3. //Written by J. Q. Programmer, 6/15/16
4.
5. using System;
6.
7. namespace InvitationCSharp
8. {
9. class TravelPlanner
10. {
11. static void Main(string[] args)
12. {
13. int speed; //rate of travel
14. double distance; //miles to travel
15. double time; //time needed for this travel
16.
17. Console.Write(Enter your speed in mph: );
18. speed = Convert.ToInt32(Console.ReadLine());
19. Console.Write(Enter your distance in miles: );
20. distance = Convert.ToDouble(Console.ReadLine());
21.
22. time = distance / speed;
23.
24. Console.Write(At + speed + mph, );
25. Console.WriteLine(it will take );
26. Console.Write(time + hours to travel );
27. Console.WriteLine(distance + miles.);
28. }
29. }
30. }
give information to the human readers of the code. Every high-level language
has some facility for including comments, because understanding code that
someone else has written (or understanding your own code after a period of
time has passed) is very difficult without the notes and explanations that
comments provide. Comments are one way to document a computer program to
make it more understandable. The comments in the program of Figure 3
describe what the program does plus tell who wrote the program and when.
These three comment lines together make up the programs prologue
comment (the introductory comment that comes first). According to the
general form of Figure 2, the prologue comment is optional, but providing it is
always a good idea. Its almost like the headline in a newspaper, giving the big
picture up front.
Blank lines in C# programs are ignored and are used, like comments, to
make the program more readable by human beings. In our example program,
weve used blank lines (lines 4, 6, 16, 21, 23) to separate sections of the
program, visually indicating groups of statements that are related.
Line 5 is a using directive to the compiler that refers to the System
library. The eventual effect is that the linker includes object code from this
library. The core C# language does not provide a way to get data into a
4 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 5
is the header for the Main function. It is not necessary to understand this
somewhat obscure code; just remember that every C# program must have a
1 Introduction to C# 5
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 6
Main function, and that all Main functions start out exactly this way. The
curly braces at lines 12 and 28 enclose the Main function body, which is the
heart of the sample program. Lines 1315 are declarations that name and
describe the items of data that are used within the Main function. Descriptive
namesspeed, distance, and timeare used for these quantities to help
document their purpose in the program, and comments provide further clarifi-
cation. Line 13 describes an integer quantity (type int) called speed. Lines 14
and 15 declare distance and time as real number quantities (type double).
A real number quantity is one containing a decimal point, such as 28.3, 102.0,
or -17.5. Declarations are also optional in the sense that if a program does not
use any data, no declarations are needed, but again, it would be unusual to
find such a trivial program.
Statements with Write or WriteLine write messages to the user; statements
with ReadLine get the strings the user entered for speed and distance. The
prefix Console indicates that the user will enter input at the computer key-
board and will view the output on the computers screen. The difference
between Write and WriteLine is that WriteLine forces any subsequent output to
begin on a new line, whereas after a Write statement, more can be written
later on the same line. The Convert functions change the input strings, which
are strings of characters, into numerical integer or double values, respectively,
and store them in speed and distance. Line 22 computes the time required to
travel this distance at this speed. Finally, lines 2427 print the output to the
users screen. The values of speed, time, and distance are inserted in appropri-
ate places among the strings of text shown in double quotes. When the Write
and WriteLine functions encounter a numeric quantity, e.g., speed, they con-
vert the numeric value to a string. That string is then concatenated to (joined
to) the previous string that was output. The sign is the C# concatenation
operatorit joins two strings together.
You may have noticed that most of the statements in this program end
with a semicolon. A semicolon must appear at the end of every executable C#
instruction, which means everywhere except at the end of a comment, a
namespace declaration, a class header, or a function header such as
The semicolon requirement is a bit of a pain in the neck, but the C# compiler
generates one or more error messages if you omit the semicolon, so after the
first few hundred times this happens, you tend to remember to put it in.
C#, along with every other programming language, has very specific rules
of syntaxthe correct form for each component of the language. Having a
semicolon at the end of every executable statement is a C# syntax rule. Any vio-
lation of the syntax rules generates an error message from the compiler because
the compiler does not recognize or know how to translate the offending code.
In the case of a missing semicolon, the compiler cannot tell where the instruc-
tion ends. The syntax rules for a programming language are often defined by a
formal grammar, much as correct English syntax is defined by rules of grammar.
C# is a free-format language, which means that it does not matter where
things are placed on a line. For example, we could have written
time =
distance /
speed;
6 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 7
TravelPlanner.cs
As the second step, the program must be compiled using a C# compiler for
your computer, and the resulting object code linked with any C# library object
code. In our example, the program in the file TravelPlanner.cs would be
compiled, resulting in a file called
TravelPlanner.exe
The third step loads and executes the program file, in this case TravelPlanner.exe.
Depending on your system, you may have to type operating system commands
for the last two steps.
Another approach is to do all of your work in an Integrated Development
Environment, or IDE. The IDE lets the programmer perform a number of tasks
within the shell of a single application program, rather than having to use a
separate program for each task. A modern programming IDE provides a text
editor, a file manager, a compiler, a linker and loader, and tools for debugging,
all within this one piece of software. The IDE usually has a GUI (graphical user
interface) with menu choices for the different tasks. This can significantly
speed up program development.
C# COMPILERS
The C# examples in this module were written and executed in Microsoft Visual
C# 2013, part of Microsoft Visual Studio 2013. This is an IDE with a GUI interface
that supports many programming languages. Visual Studio Express 2013 for Win-
dows Desktop, which supports Visual C# as well as other languages, is freely down-
loadable from Microsoft at
www.microsoft.com/express/product/default.aspx
and runs on Windows 7 or Windows 8 operating systems. Its use requires the
Microsoft .NET Framework. If the .NET Framework is not already on your Windows
system, you will be alerted at installation, and you can go to
www.microsoft.com/downloads
and look under Developer Tools to download it.
1 Introduction to C# 7
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 8
CAPITALIZATION OF IDENTIFIERS
There are two standard capitalization patterns for identifiers, particularly multiple
word identifiers:
camel case: First word begins with a lowercase letter, additional words begin
with uppercase letters (finalTotal)
Pascal case: All words begin with an uppercase letter (FinalTotal)
The code in this chapter uses the following convention for creating identifiers
(examples included):
Simple variables camel case: speed, time, finalTotal
Function names camel case: myFunction, getInput
Class names Pascal case: MyClass
Object names camel case: myObject
The underscore character is not used. Occasionally, however, well use single
capital letters for identifiers in quick code fragments.
8 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 9
program can therefore have more descriptive names, such as subTotal, tax, and
finalTotal. The use of descriptive identifiers is one of the greatest aids to
human understanding of a program. Identifiers can be almost arbitrarily long,
so be sure to use a meaningful identifier such as finalTotal instead of
something like A; the improved readability is well worth the extra typing
time. C# is a case-sensitive language, which means that uppercase letters are
distinguished from lowercase letters. Thus, FinalTotal, Finaltotal, and
finalTotal are three different identifiers.
Data that a program uses can come in two varieties. Some quantities are
fixed throughout the duration of the program, and their values are known
ahead of time. These quantities are called constants. An example of a con-
stant is the integer value 2. Another is an approximation to p, say 3.1416.
The integer 2 is a constant that we dont have to name by an identifier, nor do
we have to build the value 2 in memory manually by the equivalent of a .DATA
pseudo-op. We can just use the symbol 2 in any program statement. When
2 is first encountered in a program statement, the binary representation of
the integer 2 is automatically generated and stored in a memory location.
Likewise, we can use 3.1416 for the real number value 3.1416, but if we are
really using this number as an approximation to p, it is more informative to
use the identifier pi.
Some quantities used in a program have values that change as the
program executes, or values that are not known ahead of time but must be
obtained from the computer user (or from a data file previously prepared
by the user) as the program runs. These quantities are called variables.
For example, in a program doing computations with circles (where we
might use the constant pi), we might need to obtain from the user or a
data file the radius of the circle. This variable can be given the identifier
radius.
Identifiers for variables serve the same purpose in program statements as
pronouns do in ordinary English statements. The English statement He will
be home today has specific meaning only when we plug in the value for
which He stands. Similarly, a program statement such as
time = distance/speed;
becomes an actual computation only when numeric values have been stored in
the memory locations referenced by the distance and speed identifiers.
We know that all data are represented internally in binary form. In
Chapter 4 we noted that any one sequence of binary digits can be interpreted
as a whole number, a negative number, a real number (one containing a
decimal point, such as -17.5 or 28.342), or as a letter of the alphabet. C#
requires the following information about each variable in the program:
The data type determines how many bytes will be needed to store the
variablethat is, how many memory cells are to be considered as one
memory location referenced by one identifierand also how the string of
bits in that memory location is to be interpreted. C# provides several
Where do the variable declarations go? Although the only requirement is that
a variable must be declared before it can be used, all variable declarations are
usually collected together at the top of the Main function, as in our sample
program. This gives the reader of the code quick information about the data
that the program will be using.
What about the constant pi? We want to assign the fixed value 3.1416 to
the pi identifier. Constant declarations are just like variable declarations, with
the addition of the keyword const and the assignment of the fixed value to
the constant identifier.
Some programmers use all uppercase letters to denote constant identifiers, but
the compiler identifies a constant quantity only by the presence of const in
the declaration. Once a quantity has been declared as a constant, any attempt
later in the program to change its value generates an error message from the
compiler.
In addition to variables of a primitive data type that hold only one unit
of information, it is possible to declare a whole collection of related vari-
ables at one time. This allows storage to be set aside as needed to contain
each of the values in this collection. For example, suppose we want to record
the number of hits on a Web site for each month of the year. The value for
each month is a single integer. We want a collection of 12 such integers,
ordered in a particular way. An array groups together a collection of
FIGURE 4
Some of the C# Primitive int An integer quantity
Data Types double A real number
char A character (a single keyboard character, such as a)
10 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 11
memory locations, all storing data of the same type. The following statement
declares an array:
The left side of the equals sign says that hits is an array of integers;
the right side of the equals sign actually generates (new) memory locations
for 12 integer quantities. The 12 individual array elements are numbered
from hits[0] to hits[11]. (Notice that a C# array counts from 0 up to 11,
instead of from 1 up to 12.) Thus, we use hits[0] to refer to the first entry
in hits, which represents the number of visits to the Web site during the
first month of the year, January. Continuing this numbering scheme,
hits[2] refers to the number of visits during March, and hits[11] to the
number of visits during December. In this way we use one declaration to
set up 12 separate (but related) integer storage locations. Figure 5
illustrates this array.
Here is an example of the power of a high-level language. In assembly
language we can name only individual memory locationsthat is, individual
items of databut in C# we can also assign a name to an entire collection of
related data items. An array thus enables us to talk about an entire table of
values, or the individual elements making up that table. If we are writing C#
programs to implement the data cleanup algorithms of Chapter 3, we can use
an array of integers to store the 10 data items.
FIGURE 5 hits
A 12-Element Array hits
PRACTICE PROBLEMS
1. Which of the following are legitimate C# identifiers?
martinBradley C3P_OH Amy3 3Right const
2. Write a declaration statement for a C# program that uses one
integer quantity called number.
3. Write a C# statement that declares a type double constant called
taxRate that has the value 5.5.
4. Using the hits array of Figure 5, how do you reference the number
of hits on the Web page for August?
3 Statement Types
Now that we can reserve memory for data items by simply naming what we
want to store and describing its data type, we will examine additional kinds of
programming instructions (statements) that C# provides. These statements
enable us to manipulate the data items and do something useful with them.
The instructions in C#, or indeed in any high-level language, are designed as
components for algorithmic problem solving, rather than as one-to-one trans-
lations of the underlying machine language instruction set of the computer.
Thus they allow the programmer to work at a higher level of abstraction. In
this section we examine three types of high-level programming language
statements. They are consistent with the pseudocode operations we described
in Chapter 2 (see Figure 2.9).
Input/output statements make up one type of statement. An input
statement collects a value from the user for a variable within the program. In
our TravelPlanner program, we need input statements to get the specific
values of the speed and distance that are to be used in the computation. An
output statement writes a message or the value of a program variable to the
users screen. Once the TravelPlanner program computes the time required to
travel the given distance at the given speed, the output statement displays
that value on the screen, along with other information about what that value
means.
Another type of statement is the assignment statement, which assigns a
value to a program variable. This is similar to what an input statement does,
except that the value is not collected directly from the user, but is computed
by the program. In pseudocode we called this a computation operation.
Control statements, the third type of statement, affect the order in
which instructions are executed. A program executes one instruction or pro-
gram statement at a time. Without directions to the contrary, instructions are
executed sequentially, from first to last in the program. (In Chapter 2 we
called this a straight-line algorithm.) Imagine beside each program statement
a light bulb that lights up while that statement is being executed; you would
see a ripple of lights from the top to the bottom of the program. Sometimes,
however, we want to interrupt this sequential progression and jump around
in the program (which is accomplished by the instructions JUMP, JUMPGT, and
so on, in assembly language). The progression of lights, which may no longer
be sequential, illustrates the flow of control in the programthat is, the
path through the program that is traced by following the currently executing
statement. Control statements direct this flow of control.
C# can do this task using a function named ReadLine. The input statement is
speed = Convert.ToInt32(Console.ReadLine());
12 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 13
Because all variables must be declared before they can be used, the declaration
statement that says speed is to be a variable (of data type int) precedes this
input statement.
Lets say that we have written the entire TravelPlanner program and it is
now executing. When the preceding input statement is encountered, the pro-
gram stops and waits for the user to enter a value for speed (by typing it at
the keyboard, followed by pressing the ENTER key). For example, the user
could type
58 ENTER
distance = Convert.ToDouble(Console.ReadLine());
Note that this time the conversion of the string of characters gathered by
ReadLine is to type double. Here it would be acceptable to enter an integer
value, say 657, instead of 657.0. The conversion process knows that it can
make a double value from a string of numeric characters that does not contain
a decimal point.
After the two input statements, the value of the time can be computed
and stored in the memory location referenced by time. A pseudocode opera-
tion for producing output would be something like
Console.Write(time);
Console.Write(string); or Console.WriteLine(string);
3 Statement Types 13
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 14
Console.WriteLine();
This just prints a blank line, which is useful for formatting the output to make
it easier to read. The string can also be a literal string (enclosed in double
quotes). Literal strings are printed out exactly as is. For example,
prints
to write out the value of time. Notice the spaces at the beginning and end of
the literal string, within the quotation marks so that they are part of the text.
Without these spaces, running the TravelPlanner program with our original
data of 58 mph and 657.5 miles, the output would be printed as
11.3362068965517
is fairly ridiculous. It does not make sense to display the result to 13 decimal
digits. The appearance of numerical output can be controlled, rather than
leaving it up to the system to decide, by including a format specifier in the
output statement. If only two digits to the right of the decimal point are to be
displayed for time, the output statement would take the following form:
Console.Write(time.ToString(0.00)
+ hours to travel );
Here the conversion to string is forced in the variable identifier list by using
the ToString function, rather than waiting for the Write function to do it by
default. The value 0.00 is the format specifier. It forces two digits to the
right of the decimal point (rounding if the value has more than two decimal
digits), and one or more digits to the left of the decimal point (even though
there is only one zero in the format specifier to the left of the decimal
point). Using this statement, the output would be rounded to two decimal
places:
14 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 15
An alternative statement
Console.Write(time.ToString(#.##)
+ hours to travel );
would produce the same result. The difference between the 0 and the # is that
the # specifier will suppress leading and trailing zeros, while the 0 specifier
will fill the indicated number of columns, using leading and trailing zeros if
necessary. Both will use more columns to the left of the decimal point if the
integer part is too large to fit in the indicated column space. For example:
The ability to specify the number of decimal digits in the output is particu-
larly handy for dealing with dollar-and-cent values, where we always expect
to see two digits behind the decimal point.
A real number written in the form 11.34 is said to be in fixed-point
format, but with the appropriate format specifier, the output can be written
in scientific notation. The fixed-point format
11.34
1.134E + 01
which means 1.134 101. (The E means times 10 to the power of. . ..)
The output statement to produce this would be
Console.Write(time.ToString(0.000E+00)
+ hours to travel );
where the E in the format specifier indicates scientific notation, and the 00
after the plus sign forces two digits in the exponent.
Lets back up a bit and note that we also need to print some text
information before the input statement, to alert the user that the program
expects some input. A statement such as
3 Statement Types 15
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 16
acts as a user prompt. Without a prompt, the user may be unaware that the
program is waiting for some input; instead, it may simply seem to the user
that the program is hung up.
Assembling all of these bits and pieces, we can see that
is a series of prompt, input, prompt, input statements to get the data, and
then
writes out the computed value of time along with the associated input values
in an informative message. In the middle, we need a program statement to
compute the value of time. We can do this with a single assignment
statement; the assignment statement is explained in the next section.
Finally, whereas a single C# statement can be spread over multiple
lines, a line break cannot occur in the middle of a literal string. The
solution is to make two smaller substrings and join them together by
concatenation, as in
PRACTICE PROBLEMS
1. Write two statements that prompt the user to enter an integer
value and store that value in a (previously declared) variable called
quantity.
2. A program has computed a value of 37 for the variable height. Write
an output statement that prints this variable using six columns,
with successive output to appear on the next line.
3. What appears on the screen after execution of the following state-
ments?
Console.Write(This is);
Console.WriteLine(goodbye);
16 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 17
variable expression;
The expression on the right is evaluated, and the result is then written into
the memory location named on the left. For example, suppose that A, B, and C
have all been declared as integer variables in some program. The assignment
statements
B = 2;
C = 5;
result in B taking on the value 2 and C taking on the value 5. After execution of
A = B + C;
A has the value that is the sum of the current values of B and C. Assignment
is a destructive operation, so whatever As previous value was, it is gone. Note
that this one assignment statement says to add the values of B and C and
assign the result to A. This one high-level language statement is equivalent to
three assembly language statements needed to do this same task (LOAD B,
ADD C, STORE A). A high-level language program thus packs more power per
line than an assembly language program. To state it another way, whereas a
single assembly language instruction is equivalent to a single machine
language instruction, a single C# instruction is usually equivalent to many
assembly language instructions or machine language instructions, which
allows us to think at a higher level of problem solving.
3 Statement Types 17
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 18
all result in the value 3.5. However, if the two values being divided are both inte-
gers, the result is an integer value; if the division doesnt come out even, the
integer value is obtained by truncating the answer to an integer quotient. Thus,
7/2
3
2q7
6
1
7 % 2
results in the value 1. If the values are stored in type int variables, the same
thing happens. For example,
int numerator;
int denominator;
numerator = 7;
18 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 19
denominator = 2;
Console.Write(The result of + numerator);
Console.Write(/ + denominator);
Console.WriteLine( is + numerator / denominator);
letter = m;
PRACTICE PROBLEMS
1. newNumber and next are integer variables in a C# program. Write a
statement to assign the value of newNumber to next.
2. What is the value of average after the following statements are
executed? (total and number are type int, and average is type double.)
total = 277;
number = 5;
average = total/number;
3 Statement Types 19
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 20
The assignment
letter = 4;
is also acceptable; the single quotes around the 4 mean that it is being treated
as just another character on the keyboard, not as the integer 4.
Sequential flow of control, the default, is what occurs if the program does not
contain any instances of the other two control structures. In the TravelPlanner
program, for example, instructions are executed sequentially, beginning with
the input statements, next the computation, and finally the output statements.
FIGURE 6
Sequential Flow of Control
S1
S2
Sk
20 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 21
If the current values of A, B, and C are 2, 5, and 7, respectively, then the first
condition is false (A does not have the value zero), the second condition is
true (5 is less than 2 plus 7), and the third condition is true (A and B do not
have equal values). Comparisons need not be numeric. They can also be done
between variables of type char, where the ordering is the usual alphabetic
ordering. If initial is a value of type char with a current value of D, then
initial == F
initial < P
is true because D precedes P in the alphabet (or, more precisely, because the
binary code for D is numerically less than the binary code for P). Note that the
comparisons are case sensitive, so F is not equal to f, but F is less than f.
Figure 7 shows the comparison operations available in C#. Note the use
of the two equality signs to test whether two expressions have the same
value. The single equality sign is used in an assignment statement, the dou-
ble equality sign in a comparison.
Boolean conditions can be built up using the Boolean operators AND, OR, and
NOT. Truth tables for these operators were given in Chapter 4 (Figures 4.124.14).
The only new thing is the symbols that C# uses for these operators, shown in
Figure 8.
A conditional statement relies on the value of a Boolean condition (true
or false) to decide which programming statement to execute next. If the con-
dition is true, one statement is executed next, but if the condition is false, a
different statement is executed next. Control is therefore no longer in a
straight-line (sequential) flow, but hops to one place or to another. Figure 9
illustrates this situation. If the condition is true, the statement S1 is exe-
cuted (and statement S2 is not); if the condition is false, the statement S2 is
3 Statement Types 21
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 22
FIGURE 7
C# Comparison Operators COMPARISON SYMBOL EXAMPLE EXAMPLE RESULT
the same value as == 2 == 5 false
less than < 2<5 true
less than or equal to <= 5 <= 5 true
greater than > 2>5 false
greater than or equal to >= 2 >= 5 false
not the same value as != 2 != 5 true
FIGURE 8
C# Boolean Operators OPERATOR SYMBOL EXAMPLE EXAMPLE RESULT
AND && (2 < 5) && (2 > 7) false
OR || (2 < 5) || (2 > 7) true
NOT ! !(2 == 5) true
executed (and statement S1 is not). In either case, the flow of control then
continues on to statement S3. We saw this same scenario when we discussed
pseudocode conditional statements in Chapter 2 (Figure 2.4).
The C# instruction that carries out conditional flow of control is called an
if-else statement. It has the form shown below (note that the words if and
else are lowercase and that the Boolean condition must be in parentheses).
if (Boolean condition)
S1;
else
S2;
FIGURE 9
Conditional Flow of Control
(if-else)
T F
Condition
S1 S2
S3
22 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 23
if (B < (A + C))
A = 2*A;
else
A = 3*A;
Suppose that when this statement is reached, the values of A, B, and C are 2,
5, and 7, respectively. As we noted before, the condition B (A C ) is then
true, so the statement
A = 2*A;
A = 3*A;
FIGURE 10
If-else with Empty else
T F
Condition
S1
S3
3 Statement Types 23
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 24
if (Boolean condition)
S1;
We could write
if (B < (A + C))
A = 2*A;
This has the effect of doubling the value of A if the condition is true and of
doing nothing if the condition is false.
It is possible to combine statements into a group by putting them within
the curly braces { and }. The group is then treated as a single statement,
called a compound statement. A compound statement can be used anywhere
a single statement is allowed. For example,
{
Console.WriteLine(This is the first statement.);
Console.WriteLine(This is the second statement.);
Console.WriteLine(This is the third statement.);
}
24 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 25
FIGURE 11
The TravelPlanner Program with //Computes and outputs travel time
a Conditional Statement //for a given speed and distance
//Written by J. Q. Programmer, 6/10/16
using System;
namespace InvitationCSharp
{
class TravelPlanner
{
static void Main(string[] args)
{
int speed; //rate of travel
double distance; //miles to travel
double time; //time needed for this travel
int hours; //time for travel in hours
int minutes; //leftover time in minutes
char choice; //choice of output as
//decimal hours
//or hours and minutes
if (choice == D)
{
time = distance / speed;
Console.Write(At + speed + mph, );
Console.WriteLine(it will take );
Console.Write(time + hours to travel );
Console.WriteLine(distance + miles.);
}
else
{
time = distance / speed;
hours = (int)time;
minutes = (int)((time hours) * 60);
Console.Write(At + speed + mph, );
Console.WriteLine(it will take );
Console.WriteLine(hours + hours and +
minutes + minutes to travel +
distance + miles.);
}
}
}
}
3 Statement Types 25
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 26
To compute hours and minutes (the else clause of the if-else statement),
time is computed in the usual way, which results in a decimal value. The
whole number part of that decimal is the number of hours needed for the trip.
We can get this number by type casting the decimal number to an integer.
This is accomplished by
hours = (int)time;
which drops all digits behind the decimal point and stores the resulting
integer value in hours. Based on earlier discussions of converting to integer,
the following line of code would seem appropriate:
hours = Convert.ToInt32(time);
This line of code does not give the desired result because the Convert.ToInt32
function actually rounds the type double value. (For the example below, it
takes in 9.5 and produces 10.)
To find the fractional part of the hour that we dropped, we subtract hours
from time. We multiply this by 60 to turn it into some number of minutes, but
this is still a decimal number. We do another type cast to truncate this to an
integer value for minutes:
For example, if the user enters data of 50 mph and 475 miles and requests
output in hours and minutes, the table below shows the computed values.
Quantity Value
speed 50
distance 475
time = distance/speed 9.5
hours = int(time) 9
time hours 0.5
(time hours) *60 30.0
minutes = int((time hours)*60) 30
The two statement groups in an if-else statement are identified by the enclos-
ing curly braces, but in Figure 11 we also indented them to make them easier
26 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 27
FIGURE 12
while Loop
F
Condition
S1
S2
3 Statement Types 27
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 28
n1 = Convert.ToInt32(Console.ReadLine());
sum = sum + n1;
n2 = Convert.ToInt32(Console.ReadLine());
sum = sum + n2;
and so on. There are two problems with this approach. The first is that we may
not know ahead of time how many numbers the user wants to add. If we
declare variables n1, n2, . . . , n25, and the user wants to add 26 numbers, the
program wont do the job. The second problem is that this approach requires
too much effort. Suppose that we know the user wants to add 2000 numbers.
We could declare 2000 variables (n1, . . . , n2000), and we could write the
above input-and-add statements 2000 times, but it wouldnt be fun. Nor is it
necessarywe are doing a very repetitive task here, and we should be able to
use a loop mechanism to simplify the job. (We faced a similar situation in the
first pass at a sequential search algorithm, Figure 2.11; our solution there was
also to use iteration.)
Even if we use a loop mechanism, we are still adding a succession of
values to sum. Unless we are sure that the value of sum is zero to begin
with, we cannot be sure that the answer isnt nonsense. Remember that the
identifier sum is simply an indirect way to designate a memory location in
the computer. That memory location contains a pattern of bits, perhaps left
over from whatever was stored there when some previous program was run.
We cannot assume that just because this program hasnt used sum, its value
is zero. (In contrast, the assembly language statement SUM: .DATA 0
reserves a memory location, assigns it the identifier SUM, and fills it with
the value zero.) If we want the beginning value of sum to be zero, we
must use an assignment statement. Using assignment statements to set the
values of certain variables before they are used by the program is called
initialization of variables.
Now on to the loop mechanism. First, lets note that once a number has
been read in and added to sum, the program doesnt need to know the value of
the number any longer. We can declare just one integer variable called number
and use it repeatedly to hold the first numerical value, then the second, and
so on. The general idea is
Now we have to figure out what the condition there are more numbers to
add really means. Because we are adding nonnegative integers, we could ask
28 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 29
the user to enter one extra integer that is not part of the legitimate data but
is instead a signal that there are no more data. Such a value is called a
sentinel value. For this problem, any negative number would be a good
sentinel value. Because the numbers to be added are all nonnegative, the
appearance of a negative number signals the end of the legitimate data. We
dont want to process the sentinel value (because it is not a legitimate data
item); we only want to use it to terminate the looping process. This might
suggest the following code:
Heres the problem. How can we test whether number is greater than or equal
to 0 if we havent read the value of number yet? We need to do a preliminary
input for the first value of number outside of the loop and then test that value
in the loop condition. If it is nonnegative, we want to add it to sum and then
read the next value and test it. Whenever the value of number is negative
(including the first value), we want to do nothing with itthat is, we want to
avoid executing the loop body. The following statements do this; weve also
added instructions to the user.
The value of number gets changed within the loop body by reading in a new
value. The new value is tested, and if it is nonnegative, the loop body
executes again, adding the data value to sum and reading in a new value for
number. The loop terminates when a negative value is read in. Remember
the requirement that something within the loop body must be able to affect
the truth value of the condition. In this case, it is reading in a new value
for number that has the potential to change the value of the condition from
true to false. Without this requirement, the condition, once true, would
remain true forever, and the loop body would be endlessly executed. This
results in what is called an infinite loop. A program that contains an
infinite loop will execute forever (or until the programmer gets tired of
waiting and interrupts the program, or until the program exceeds some
preset time limit).
3 Statement Types 29
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 30
The problem weve solved here, adding nonnegative integers until a negative
sentinel value occurs, is the same one solved using assembly language in
Chapter 6. The preceding C# code is almost identical to the pseudocode version
of the algorithm shown in Figure 6.7. Thanks to the power of the language,
the C# code embodies the algorithm directly, at a high level of thinking,
whereas in assembly language this same algorithm had to be translated into
the lengthy and awkward code of Figure 6.8.
To process data for a number of different trips in the TravelPlanner
program, we could use a while loop. During each pass through the loop,
the program computes the time for a given speed and distance. The body
of the loop is therefore exactly like our previous code. All we are adding
here is the framework that provides looping. To terminate the loop, we
could use a sentinel value, as we did for the program above. A negative
value for speed, for example, is not a valid value and could serve as a sen-
tinel value. Instead of that, lets allow the user to control loop termination
by having the program ask the user whether he or she wishes to continue.
Well need a variable to hold the users response to this question. Of
course, the user could answer N at the first query, the loop body would
never be executed at all, and the program would terminate. Figure 13
shows the complete program.
FIGURE 13
The TravelPlanner Program //Computes and outputs travel time
with Looping //for a given speed and distance
//Written by J. Q. Programmer, 6/20/16
using System;
namespace InvitationCSharp
{
class TravelPlanner
{
static void Main(string[] args)
{
int speed; //rate of travel
double distance; //miles to travel
double time; //time needed for this travel
int hours; //time for travel in hours
30 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 31
FIGURE 13
The TravelPlanner Program with int minutes; //leftover time in minutes
Looping (continued) char choice; //choice of output as
//decimal hours
//or hours and minutes
char more; //users choice to do
//another trip
if (choice == D)
{
time = distance / speed;
Console.Write(At + speed + mph, );
Console.WriteLine(it will take );
Console.Write(time + hours to travel );
Console.WriteLine(distance + miles.);
}
else
{
time = distance / speed;
hours = (int)time;
minutes = (int)((time hours) * 60);
Console.Write(At + speed + mph, );
Console.WriteLine(it will take );
Console.WriteLine(hours + hours and +
minutes + minutes to travel +
distance + miles.);
}
Console.WriteLine();
Console.Write(Do you want to plan a trip? +
(Y or N): );
more = Convert.ToChar(Console.ReadLine());
} //end of while loop
}
}
}
3 Statement Types 31
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 32
PRACTICE PROBLEMS
Assume all variables have previously been declared.
1. What is the output from the following section of code?
number1 = 15;
number2 = 7;
if (number1 >= number2)
Console.WriteLine(2*number1);
else
Console.WriteLine(2*number2);
2. What is the output from the following section of code?
scores = 1;
while (scores < 20)
{
scores = scores + 2;
Console.WriteLine(scores);
}
3. What is the output from the following section of code?
quotaThisMonth = 7;
quotaLastMonth = quotaThisMonth + 1;
if ((quotaThisMonth > quotaLastMonth)||
(quotaLastMonth >= 8))
{
Console.WriteLine(Yes);
quotaLastMonth = quotaLastMonth + 1;
}
else
{
Console.WriteLine(No);
quotaThisMonth = quotaThisMonth + 1;
}
4. How many times is the WriteLine statement executed in the follow-
ing section of code?
left = 10;
right = 20;
while (left <= right)
{
Console.WriteLine(left);
left = left + 2;
}
5. Write a C# statement that outputs Equal if the integer values of
night and day are the same, but otherwise does nothing.
32 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 33
4 Another Example
Lets briefly review the types of C# programming statements weve learned. We
can do input and outputreading values from the user into memory, writing
values out of memory for the user to see, being sure to use meaningful vari-
able identifiers to reference memory locations. We can assign values to vari-
ables within the program. And we can direct the flow of control by using
conditional statements or looping. Although many other statement types are
available in C#, you can do almost everything using only the modest collection
of statements we have described. The power lies in how these statements are
combined and nested within groups to produce ever more complex courses of
action.
For example, suppose we write a program to assist SportsWorld, a com-
pany that installs circular swimming pools. In order to estimate their costs for
swimming pool covers or for fencing to surround the pool, SportsWorld needs
to know the area or circumference of a pool, given its radius. A pseudocode
version of the program is shown in Figure 14.
We should be able to translate this pseudocode fairly directly into the
body of the Main function. Other things we need to add to complete the pro-
gram are:
Figure 15 gives the complete program. Figure 16 shows what actually appears
on the screen when this program is executed with some sample data.
FIGURE 14
A Pseudocode Version of the Get value for users choice about continuing
SportsWorld Program While user wants to continue, do the following steps
Get value for pool radius
Get value for choice of task
If task choice is circumference
Compute pool circumference
Print output
Else (task choice is area)
Compute pool area
Print output
Get value for users choice about continuing
Stop
4 Another Example 33
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 34
FIGURE 15
The SportsWorld Program //This program helps SportsWorld estimate costs
//for pool covers and pool fencing by computing
//the area or circumference of a circle
//with a given radius.
//Any number of circles can be processed.
//Written by M. Phelps, 10/05/16
using System;
namespace SportsWorld
{
class Program
{
static void Main(string[] args)
{
const double pi = 3.1416; //value of pi
double radius; //radius of a pool given
double circumference; //circumference of a pool
//computed
double area; //area of a pool
//computed
char taskToDo; //holds user choice to
//compute circumference
//or area
char more; //controls loop for
//processing more pools
34 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 35
FIGURE 15
The SportsWorld Program is + area.ToString(##.##));
(continued) }
Console.WriteLine();
Console.Write(Do you want to process more pools? +
(Y or N): );
more = Convert.ToChar(Console.ReadLine());
} //end of while loop
//finish up
Console.WriteLine(Program will now terminate.);
}
}
}
FIGURE 16
A Sample Session Using the Do you want to process a pool? (Y or N): Y
Program of Figure 15
Enter the value of the radius of a pool: 2.7
Enter your choice of task.
C to compute circumference, A to compute area: C
The circumference for a pool of radius 2.70 is 16.96
PRACTICE PROBLEMS
1. Write a complete C# program to read in an integer number and write
out the square of that number.
2. Write a complete C# program that asks for the price of an item and
the quantity purchased, and writes out the total cost.
3. Write a complete C# program that asks for a number. If the number is
less than 5, it is written out, but if it is greater than or equal to 5,
twice that number is written out.
4. Write a complete C# program that asks the user for a positive integer
n and then writes out all the numbers from 1 up to and including n.
4 Another Example 35
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 36
Zooming Through
the Universe solar system, the galaxy, and beyond, and view the relative
positions of planets and other heavenly bodies in the past,
C# is the programming language behind Worldwide Tele- present, and future. Then from far-flung views of the uni-
scope, an application built by Microsoft Research. Worldwide verse, its possible to zoom in on planet Earth right down to
Telescope uses a catalogue of astronomical images and data the individual building level. Users can also choose different
from many ground-based and space-based observatories light wavelengths through which to view the universe and
around the world to let users virtually view the night sky. explore hidden structures in the galaxies. Guided tours
Users can choose which telescope to look through, includ- with experts are available. Worldwide Telescope is available
ing the Hubble Space Telescope. They can zoom through the for free download at www.worldwidetelescope.org.
5 Managing Complexity
The programs we have written have been relatively simple. More complex
problems require more complex programs to solve them. Although it is fairly
easy to understand what is happening in the 40 or so lines of the SportsWorld
program, imagine trying to understand a program that is 50,000 lines long.
Imagine trying to write such a program! It is not possible to understandall
at onceeverything that goes on in a 50,000-line program.
36 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 37
FIGURE 17
Structure Charts Task T Task T
A B C D A B C D
A1 A2 A3
5 Managing Complexity 37
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 38
FIGURE 18
Structure Chart for the
SportsWorld Task SportsWorld
Do Do
Get input
circumference area
which takes the place of the Do the input subtask line in Figure 19. (The
meaning of ref will be explained later.) When this statement is reached,
FIGURE 19
A High-Level Modular View of Get value for users choice about continuing
the SportsWorld Program While the user wants to continue
Do the input subtask
If (Task = C) then
do the circumference subtask
else
do the area subtask
Get value for users choice about continuing
38 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 39
doCircumference(radius);
doArea(radius);
5 Managing Complexity 39
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 40
FIGURE 20
The Main Function in a static void Main(string[] args)
Modularized Version of the {
SportsWorld Program double radius = 0; //radius of a pool given
char taskToDo = ; //holds user choice to
//compute circumference
//or area
char more; //controls loop for
//processing more pools
A return indicator
The function identifier
A parameter list
FIGURE 21
The Outline for a C++ Function function header
{
local declarations [optional]
function body
}
40 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 41
5 Managing Complexity 41
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 42
right order, have been given the correct data types, and are both marked for
passing by reference. Also remember that, although the arguments are named
radius and taskToDo because those are the variable identifiers declared in the
Main function, the parameters could have different identifiers, and it is the
parameter identifiers that are used within the body of the function.
double radius = 0;
char taskToDo = ;
at the beginning of the Main function above. These combine declaration with
initialization of the variables.
The body of the getInput function comes from the corresponding part of
Figure 15. If we hadnt already written this code, we could have done a
pseudocode plan first. The complete function appears in Figure 22, where a com-
ment has been added to document the purpose of the function.
The doCircumference function needs to know the value of radius but does
not change that value. Therefore, radius is passed by value. Why is the distinc-
tion between arguments passed by value and those passed by reference impor-
tant? If functions are to effect any changes at all, then clearly reference
parameters are necessary, but why not just make everything a reference para-
meter? Suppose that in this example radius is made a reference parameter. If an
instruction within doCircumference were to inadvertently change the value of
radius, then that new value would be returned to the Main function, and any
subsequent calculations using this value (there are none in this example) would
be in error. Making radius a value parameter prevents this. How could one
possibly write a program statement that changes the value of a variable inad-
vertently? In something as short and simple as our example, this probably
would not happen, but in a more complicated program, it might. Distinguishing
FIGURE 22
The getInput Function static void getInput(ref double radius, ref char taskToDo)
//gets radius and choice of task from the user
{
Console.WriteLine();
Console.Write(Enter the value of the radius of a +
pool: );
radius = Convert.ToDouble(Console.ReadLine());
42 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 43
FIGURE 23
The doCircumference Function static void doCircumference(double radius)
//computes and writes out the circumference of
//a circle with given radius
{
double circumference; //circumference of a pool
//computed
circumference = 2 * pi * radius;
Console.WriteLine(The circumference for a pool +
of radius + radius.ToString(##.##) +
is + circumference.ToString(##.##));
}
also follows the form for any function header. In other words, the Main
function truly is a C# function.
Because it seems to have been a lot of effort to arrive at this complete,
modularized version of our SportsWorld program (which, after all, does the same
thing as the program in Figure 15), lets review why this effort is worthwhile.
The modularized version of the program is compartmentalized in two
ways. First, it is compartmentalized with respect to task. The major task is
accomplished by a series of subtasks, and the work for each subtask takes
place within a separate function. This leaves the Main function free of details
and consisting primarily of invoking the appropriate function at the appropri-
ate point. As an analogy, think of the president of a company calling on vari-
ous assistants to carry out tasks as needed. The president does not need to
know how a task is done, only the name of the person responsible for carrying
it out. Second, the program is compartmentalized with respect to data, in the
sense that the data values known to the various functions are controlled by
parameter lists and by the use of value parameters instead of reference para-
meters where appropriate. In our analogy, the president gives each assistant
the information he or she needs to do the assigned task, and expects relevant
information to be returnedbut not all assistants know all information.
This compartmentalization is useful in many ways. It is useful when we plan
the solution to a problem, because it allows us to use a divide-and-conquer
approach. We can think about the problem in terms of subtasks. This makes it
easier for us to understand how to achieve a solution to a large and complex
problem. It is also useful when we code the solution to a problem, because it
allows us to concentrate on writing one section of the code at a time. We can
write a function and then fit it into the program, so that the program gradually
expands rather than having to be written all at once. Developing a large software
project is a team effort, and different parts of the team can be writing different
functions at the same time. It is useful when we test the program, because we
5 Managing Complexity 43
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 44
FIGURE 24
The Complete Modularized //This program helps SportsWorld estimate costs
SportsWorld Program //for pool covers and pool fencing by computing
//the area or circumference of a circle
//with a given radius.
//Any number of circles can be processed.
//Written by M. Phelps, 10/23/16
using System;
namespace SportsWorld
{
class Program
{
const double pi = 3.1416; //value of pi
44 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 45
FIGURE 24
The Complete Modularized char taskToDo= ; //holds user choice to
SportsWorld Program //compute circumference
(continued) //or area
char more; //controls loop for
//processing more pools
can test one new function at a time as the program grows, and any errors are
localized to the function being added. (The Main function can be tested early by
writing appropriate headers but empty bodies for the remaining functions.)
Compartmentalization is useful when we modify the program, because changes
tend to be within certain subtasks and hence within certain functions in the
code. And finally it is useful for anyone (including the programmer) who wants
to read the resulting program. The overall idea of how the program works, with-
out the details, can be gleaned from reading the Main function; if and when the
details become important, the appropriate code for the other functions can be
consulted. In other words, modularizing a program is useful for its
Planning
Coding
Testing
Modifying
Reading
5 Managing Complexity 45
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 46
out. We can write a different doCircumference function that only computes the
value of the circumference and then returns that value to the Main function,
which writes it out. A function that returns a single value to the section of
the program that invoked it is a nonvoid function. Instead of using the word
void as the return indicator in the function header, a non void function uses
the data type of the single returned value. In addition, a nonvoid function
must contain a return statement, which consists of the keyword return
followed by an expression for the value to be returned. (This explains why we
have always written the Main function as a void function; it is never invoked
anywhere else in the program and does not return a value.)
The code for this new doCircumference function would be simply
Console.Write(doCircumference(radius));
invokes the doCircumference function by giving its name and argument, and
this invocation actually becomes the value returned by the doCircumference
function, which is then written out.
Figure 25 shows a third version of the SportsWorld program using
nonvoid doCircumference and doArea functions. There are no variables
FIGURE 25
The SportsWorld Program Using //This program helps SportsWorld estimate costs
Nonvoid Functions //for pool covers and pool fencing by computing
//the area or circumference of a circle
//with a given radius.
//Any number of circles can be processed.
//Written by M. Phelps, 10/23/16
using System;
namespace SportsWorld
{
class Program
{
const double pi = 3.1416; //value of pi
46 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 47
FIGURE 25
The SportsWorld Program Using Console.WriteLine(Enter your choice of task.);
Nonvoid Functions Console.Write(C to compute circumference, +
(continued) A to compute area: );
taskToDo = Convert.ToChar(Console.ReadLine());
}
5 Managing Complexity 47
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 48
FIGURE 26
Some C# Terminology TERM MEANING TERM MEANING
Local Declared and known only within Global Declared outside any function
variable a function constant and known everywhere
anywhere for the circumference and the area of the circle. The doCircumfer-
ence and doArea functions use the usual formulas for their computations,
but instead of using local variables for circumference and area, weve com-
pressed the code into a single return statement. These functions are now
invoked within an output statement, so the values get printed out without
being stored anywhere.
Figure 26 summarizes several sets of terms introduced in this section.
PRACTICE PROBLEMS
1. What is the output of the following C# program fragment?
static void doIt(ref int number)
{
number = number + 4;
}
static void Main(string[] args)
{
int number;
number = 7;
doIt(ref number);
Console.WriteLine(number);
}
2. What is the output of the following C# program fragment?
static void doIt(int number)
{
number = number + 4;
}
static void Main(string[] args)
48 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 49
PRACTICE PROBLEMS
{
int number;
number = 7;
doIt(number);
Console.WriteLine(number);
}
3. Write a C# function that performs an input task for the Main func-
tion, collecting two integer values one and two from the user.
4. Suppose a nonvoid function called tax gets a value subTotal from
the Main function, multiplies it by a global constant tax rate called
rate, and returns the resulting tax value. All quantities are type
double.
a. Write the function header.
b. Write the return statement in the function body.
c. Write the statement in the Main function that writes out the tax.
6 Object-Oriented Programming
6 Object-Oriented Programming 49
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 50
A class also has one or more subtasks associated with it, and all objects
from that class can perform those subtasks. In carrying out a subtask, each
object can be thought of as providing some service. A savings account, for
example, can compute compound interest due on the balance. When an
object-oriented program is executed, the program generates requests for ser-
vices that go to the various objects. The objects respond by performing the
requested servicethat is, carrying out the subtask. Thus a program that is
using the savings account class might request a particular savings account
object to perform the service of computing interest due on the account bal-
ance. An object always knows its own data values and may use them in
performing the requested service.
Some of this sounds familiar. We know about subtasks (functions) associ-
ated with a class. The new idea is that instead of directly asking a class to
carry out a subtask, we ask an object of that class to carry out a subtask. The
even bigger new idea is that such objects have data values for the class prop-
erties. Instead of storing data in variables that are available to the whole
program and then passing them as arguments to subtasks, the program can
simply ask an object to use its own data when it carries out a subtask.
There are three terms often associated with object-oriented programming,
as illustrated in Figure 27. The first term is encapsulation. Each class has its
own program module to perform each of its subtasks. Any user of the class
(which might be some other program) can ask an object of that class to invoke
the appropriate module and thereby perform the subtask service. The class user
needs to know what services objects of the class can provide and how to request
an object to perform any such service. The details of the module code belong to
the class itself, and this code may be modified in any manner, as long as the way
the user interacts with the class remains unchanged. (In the savings account
example, the details of the algorithm used to compute interest due belong only
to the class, and need not be known by any user of the class. If the bank wants
to change how it computes interest, only the code for the interest module in the
savings account class needs to be modified; any programs that use the services
of the savings account class can remain unchanged.) Furthermore, the class
properties represent data values that will exist as part of each object of the
class. A class therefore consists of two components, its subtask modules and its
properties, and both components are encapsulatedbundledwith the class.
A second term associated with object-oriented programming is
inheritance. Once a class A of objects is defined, a class B of objects can be
defined as a subclass of A. Every object of class B is also an object of class
FIGURE 27
Three Key Elements of OOP
Inheritance
Polymorphism Encapsulation
50 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 51
6 Object-Oriented Programming 51
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 52
can see that the structure for the TravelPlanner program is dominated by the
definition of the TravelPlanner class, which contains only the Main function:
9. class TravelPlanner
10.{
//Main function
29.}
What are the properties common to any object of this class? (In this
case, the radius and the value of pi.)
What are the services that any object of the class should be able to
perform? (In this case, compute its circumference and compute its
area, although as we will see shortly, we will need other services as
well.)
FIGURE 28
An Object-Oriented //This program helps SportsWorld estimate costs
SportsWorld Program //for pool covers and pool fencing by computing
//the area or circumference of a circle
//with a given radius.
//Any number of circles can be processed.
//Uses class Circle
//Written by M. Phelps, 10/23/16
using System;
namespace SportsWorld
{
class Circle
52 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 53
FIGURE 28
An Object-Oriented {
SportsWorld Program private const double pi = 3.1416;
(continued) private double radius;
class Program
{
static void getInput(ref double newRadius, ref char taskToDo)
//gets radius and choice of task from the user
{
Console.WriteLine();
Console.Write(Enter the value of the radius of a +
pool: );
newRadius = Convert.ToDouble(Console.ReadLine());
6 Object-Oriented Programming 53
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 54
FIGURE 28
An Object-Oriented Console.Write(Do you want to process a pool? (Y or N): );
SportsWorld Program more = Convert.ToChar(Console.ReadLine());
(continued)
while (more == Y) //more circles to process
{
getInput(ref newRadius, ref taskToDo);
swimmingPool.setRadius(newRadius);
The question is, if these are two separate and distinct classes, how do
they talk to each other? The answer is, if a class wants to make use of
another class, it must instantiate (declare) an object from that class. Look
at this line of code from Main:
This instantiates an object from the Circle class and calls it swimmingPool.
Now, Main can ask the swimmingPool object to invoke methods from its class.
Consider the statement
54 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 55
This statement asks the swimmingPool object first to invoke the getRadius
function, and later to invoke the doCircumference function, both member
functions of the Circle class of which swimmingPool is an instance.
Although we glossed over this point earlier, in the two modularized
versions of the SportsWorld program the doCircumference and doArea functions
were declared as static functions, as in
and
int number;
6 Object-Oriented Programming 55
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 56
but includes the syntax to create a new instance of Circle. Why isnt there
a need for new in the line of code just above? Variables of simple types,
e.g., integers, are instantiated for you by the runtime system. (Recall,
new did appear in the declaration for an array given earlierarrays are
not simple types.)
After
the object swimmingPool exists, and the Main function can ask swimmingPool
to perform the various services of which instances of the Circle class are
capable.
The syntax to request an object to invoke a member function is to give
the name of the object, followed by a dot, followed by the name of the
member function, followed by any arguments the function may need.
object-identifier.function-identifier(argument list)
The object that invokes a method is the calling object. Therefore the
expression
swimmingPool.doCircumference()
in the Main function uses swimmingPool as the calling object to invoke the
doCircumference method of the Circle class. No arguments are needed because
this method has no parameters, but the empty parentheses must be present.
Looking at the code for the member functions in Figure 28, we see that
the setRadius member function uses an assignment statement to change the
value of radius to whatever quantity is passed to the parameter value. The
getRadius function body is a single return statement. The doCircumference and
doArea functions again consist of single statements that compute and return
the proper value.
There is no declaration in the Main function for a variable called radius.
There is a declaration for newRadius, and newRadius receives the value
entered by the user for the radius of the circle. Therefore, isnt newRadius
serving the same purpose as radius did in the old program? Nothis is rather
subtle, so pay close attention: While newRadius holds the number the user
wants for the circle radius, it is not itself the radius of swimmingPool. The
radius of swimmingPool is the member variable radius, and only methods of
the class can change the member variables of an object of that class. The Cir-
cle class provides the setRadius member function for this purpose. The Main
function must ask the object swimmingPool to invoke setRadius to set the
value of its radius equal to the value contained in newRadius. The newRadius
argument corresponds to the value parameter in the setRadius function, which
then gets assigned to the member variable radius.
56 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 57
swimmingPool.setRadius(newRadius);
6 Object-Oriented Programming 57
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 58
the class can perform. The private or protected part describes the properties
that any object of the class possesses. A Circle object, as before, has a radius
property and a property for the value of pi, whereas a Rectangle object has a
width property and a height property. Any Circle object can set the value of its
radius and can compute its area. A Square object has a side property, as one
might expect, but a Square2 object doesnt seem to have any properties or, for
that matter, any way to compute its area. We will explain the difference
between the Square class and the Square2 class shortly.
FIGURE 29
A C# Program with using System;
Polymorphism and Inheritance
namespace Shapes
{
public class Circle
{
const double pi = 3.1416;
private double radius;
58 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 59
FIGURE 29
A C# Program with public double getHeight()
Polymorphism and Inheritance { //returns height
(continued) return height;
}
class Program
{
static void Main(string[] args)
{
Circle joe = new Circle();
joe.setRadius(23.5);
6 Object-Oriented Programming 59
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 60
FIGURE 29
A C# Program with Console.WriteLine(The area of a circle with
Polymorphism and Inheritance + radius + joe.getRadius() + is
(continued) + joe.doArea());
The Main function uses these classes. It creates objects from the various
classes. After each object is created, the Main function requests the object to
set its dimensions, using the values given, and to compute its area as part of
an output statement giving information about the object. For example, the
statement
joe.setRadius(23.5);
instructs the circle named joe to invoke the setRadius function of joes class,
thereby setting joes radius to 23.5. Figure 30 shows the output after the
program in Figure 29 is run.
Here we see polymorphism at work, because there are lots of doArea func-
tions; when the program executes, the correct function is used, on the basis of
the class to which the object invoking the function belongs. After all, com-
puting the area of a circle is quite different from computing the area of a rec-
tangle. The algorithms themselves are straightforward; they employ
assignment statements to set the dimensions and the usual formulas to com-
pute the area of a circle, rectangle, and square. The functions can use the
properties of the objects that invoke them without having the values of those
properties passed as arguments.
FIGURE 30
Output from the Program of The area of a circle with radius 23.5 is 1734.9486
Figure 29 The area of a rectangle with dimensions 12.4 and 18.1 is 224.44
The area of a square with side 3 is 9
The area of a square with side 4.2 is 17.64
60 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 61
FIGURE 31
A Hierarchy of Geometric Classes
Shape class
Square2
class
6 Object-Oriented Programming 61
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 62
Software reuse
A more natural worldview
62 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 63
PRACTICE PROBLEMS
1. What is the output from the following section of code if it is added
to the Main function of the C# program in Figure 29?
Square one = new Square();
one.setSide(10);
Console.WriteLine(The area of a square with
+ side + one.getSide() + is
+ one.doArea());
2. In the hierarchy of Figure 31, suppose that the Triangle class is able
to perform a doArea function. What two properties should any tri-
angle object have?
7 Graphical Programming
The programs that we have looked at so far all produce text outputoutput
composed of the characters {A . . .Z, a . . .z, 0 . . .9} along with a few punc-
tuation marks. For the first 30 to 35 years of software development, text was
virtually the only method of displaying results in human-readable form, and
in those early days it was quite common for programs to produce huge stacks
of alphanumeric output. These days an alternative form of output
graphicshas become much more widely used. With graphics, we are no
longer limited to 100 or so printable characters; instead, programmers are free
to construct whatever shapes and images they desire.
The intelligent and well-planned use of graphical output can produce some
phenomenal improvements in software. We discussed this issue in Chapter 6,
where we described the move away from the text-oriented operating systems of
the 1970s and 1980s, such as MS-DOS and VMS, to operating systems with more
powerful and user-friendly graphical user interfaces (GUIs), such as Windows 7,
Windows 8, and Mac OS X. Instead of requiring users to learn dozens of complex
text-oriented commands for such things as copying, editing, deleting, moving,
and printing files, GUIs can present users with simple and easy-to-understand
visual metaphors for these operations. In the first image on the next page, the
operating system presents the user with icons for printing, deleting, or copying a
file. In the second image on the next page, dragging a file to the printer icon prints
the file.
Not only does graphics make it easier to manage the tasks of the operating
system, it can help us visualize and make sense of massive amounts of output
produced by programs that model complex physical, social, and mathematical
systems. (We discuss modeling and visualization in Chapter 13.) Finally, there are
many applications of computers that would simply be impossible without the
7 Graphical Programming 63
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 64
64 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 65
requires 24 bits per pixel, with 8 bits used to represent the value of each of the
three colors red, green, and blue. The memory that stores the actual screen
image is called a frame buffer. A high-resolution color display might need a
frame buffer with (1560 1280) pixels 24 bits/pixel 47,923,000 bits, or
about 6 MB, of memory for a single image. (One of the problems with graphics
is that it requires many times the amount of memory needed for storing text.)
The individual pixels in the display are addressed using a two-dimensional
coordinate grid system, the pixel in the upper-left corner being (0, 0). The
overall pixel-numbering system is summarized in Figure 32. The specific values
for maxX and maxY in Figure 32 are, as mentioned earlier, system-dependent.
(Note that this coordinate system is not the usual mathematical one. Here, the
origin is in the upper-left corner, and y values are measured downward.)
The terminal hardware displays on the screen the frame buffer value of
every individual pixel. For example, if the frame buffer value on a color monitor
for position (24, 47) is RGB (0, 0, 0), the hardware sets the color of the pixel
located at column 24, row 47 to black, as shown in Figure 33. The operation
diagramed in Figure 33 must be repeated for all of the 500,000 to 2 million pix-
els on the screen. However, the setting of a pixel is not permanent; on the con-
trary, its color and intensity fade quickly. Therefore, each pixel must be
repainted often enough so that our eyes do not detect any flicker, or
change in intensity. This requires the screen to be completely updated, or
refreshed, 3050 times per second. By setting various sequences of pixels to
different colors, the user can have the screen display any desired shape or
image. This is the fundamental way in which graphical output is achieved.
FIGURE 32
Pixel-Numbering System in a
(0, 0) (1, 0) (2, 0) (maxX, 0)
Bitmapped Display
7 Graphical Programming 65
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 66
FIGURE 33 24 24
Display of Information on Hardware
the Terminal
47 (0,0,0) 47
an extensive and powerful graphics library for creating different shapes and
images. Typically, an industrial strength graphics library includes hundreds
of functions for everything from drawing simple geometric shapes like lines
and circles, to creating and selecting colors, to more complex operations such
as displaying scrolling windows, pull-down menus, and buttons. We restrict
our discussion to a modest set of functions. Although the set is unrealistically
small, it will still give you a good idea of what visual programming is like, and
enable you to produce some interesting, nontrivial images on the screen.
To create a C# graphics program in Visual Studio 2013, you must start
with a Windows Form Application Project (as opposed to a Console Application
project). Then the C# IDE will automatically create a window, called Form 1.
This window will hold a drawing canvas on which the actual graphics will
appear. There is a lot of code generated by the IDE to produce Form 1, but
again, its all done automatically by virtue of the fact that the project is a
windows form application project. Form 1 shows up in the Form1.cs[Design]
view in the C# IDE; it looks like this:
To see some of the code that has been generated, click on the < > symbol in
the Solution Explorer window of the IDE
66 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 67
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace GraphicsProgram
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
}
}
public Form1()
{
InitializeComponent();
//code to actually draw
//on the form goes here
}
The code to draw a line from point (20,20) to point (100,100) is shown
next. Some additional comments have been added, and, as shown in the
result, the text appearing on the Form1 window title bar has been
changed.
public Form1()
{ // form on which drawing will occur
InitializeComponent(); // initialize form
this.Text = "C# Graphics";
Graphics drawingCanvas = CreateGraphics();
Show();
Pen BlackPen = new Pen(Color.Black, 2);
drawingCanvas.DrawLine
(BlackPen, 20, 20, 100, 100);
}
7 Graphical Programming 67
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 68
How does this code work? The first statement invokes the Initialize-
Component() function. This function, part of the automatically generated
code, actually generates the form. The second statement changes the text
that appears in the title bar of the form window.
The next line of code in public Form1() produces the drawing canvas on
which to draw, actually just the surface of the form.
The statement
Show();
creates the tool, in this case a pen, that will paint the lines on the screen.
It also sets the pen color and the line thickness. Brushes can also be used as
drawing tools.
The final line in the code actually draws the line on the screen.
68 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 69
where (x1, y1) are the coordinates (in pixels) of the start of the line, and
(x2, y2) are the coordinates of the end of the line.
The code to draw a rectangle touching the four points (25, 60), (75, 60),
(25,100), and (75,100) is:
public Form1()
{ // form on which drawing will occur
InitializeComponent(); // initialize form
this.Text = "C# Graphics";
Graphics drawingCanvas = CreateGraphics();
Show();
Pen BlackPen = new Pen(Color.Black, 2);
drawingCanvas.DrawRectangle
(BlackPen, 25, 60, 50, 40);
}
where (x, y) are the coordinates of the upper-left corner. The result is
The DrawEllipse method is used to draw a circle. Here is the result of draw-
ing a circle with radius 125 pixels centered at the point (100, 150):
7 Graphical Programming 69
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 70
The circle (ellipse) is specified by giving the size of its bounding rectangle.
The parameters are:
where (x, y) are the coordinates of the upper-left corner of the bounding
rectangle. In the image above, this corner will have to be off the screen.
Thats not a problem. The code is shown below (note the negative value for the
x coordinate). Also note that width and height of the bounding rectangle
must be equal to get a circular shape rather than an oval.
public Form1()
{ // form on which drawing will occur
InitializeComponent(); // initialize form
this.Text = "C# Graphics";
Graphics drawingCanvas = CreateGraphics();
Show();
Pen BlackPen = new Pen(Color.Black, 2);
drawingCanvas.DrawEllipse
(BlackPen,-25, 25, 125, 125);
}
How can we get text annotations on the screen? There is a method named
DrawString that will do the job. The parameter list is
The string is the string to be output, using the font specified, drawing with
the brush specified, beginning at pixel position (x, y) for the upper-left corner
of the bounding rectangle for the text.
70 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 71
public Form1()
{ // form on which drawing will occur
InitializeComponent(); // initialize form
this.Text = "C# Graphics";
Graphics drawingCanvas = CreateGraphics();
Show();
drawingCanvas.DrawEllipse
(BlackPen,160, 160, 40, 40);
Brush redBrush = Brushes.Red;
Font f = new Font(Arial, 10);
drawingCanvas.DrawString
(Stop, f, redBrush, 160, 170);
}
Now that forms and graphics are available, we seem close to producing
elements of a typical GUI. Can we draw a button that acts like a button on a
real GUI formthat is, can we write code to sense a mouse click on that but-
ton and respond with some action?
7 Graphical Programming 71
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 72
public Form1()
{ // form on which drawing will occur
InitializeComponent(); // initialize form
this.Text = "C# Graphics";
Graphics drawingCanvas = CreateGraphics();
Show();
Pen BlackPen = new Pen(Color.Black, 2);
drawingCanvas.DrawRectangle
(BlackPen, 100, 100, 50, 100);
Brush redBrush = Brushes.Red;
Font f = new Font(Arial, 10);
drawingCanvas.DrawString
(Stop, f, redBrush,105, 140);
}
72 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 73
Next we fill in the body of the event handler to check whether the cursor was
in the rectangle when the mouseclick event occurred and to display a corre-
sponding message.
Integer variables x and y receive the coordinates of the cursor when the
event occurs, and the above code just checks whether these (x, y) values fit
within the rectangle. Here is output for the case where the user clicked the
button:
7 Graphical Programming 73
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 74
PRACTICE PROBLEMS
Write the sequence of commands to draw the following house on
the screen.
Create the house using four rectangles (for the base of the house,
the door, and the two windows), two line segments (for the roof),
and one circle (for the doorknob). Locate the house anywhere you
want on the screen.
8 Conclusion
In this module we looked at one representative high-level programming
language, C#. Of course, there is much about this language that has been left
unsaid, but we have seen how the use of a high-level language overcomes
many of the disadvantages of assembly language programming, creating a
more comfortable and useful environment for the programmer. In a high-level
language, the programmer need not manage the storage or movement of data
values in memory. The programmer can think about the problem at a higher
level, can use program instructions that are both more powerful and more
74 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 75
natural languagelike, and can write a program that is much more portable
among various hardware platforms. We also saw how modularization, through
the use of functions and parameters, allows the program to be more cleanly
structured and how object-oriented programming allows a more intuitive view
of the problem solution and provides the possibility for reuse of helpful
classes. We even had a glimpse of graphical programming.
C# is not the only high-level language. You might be interested in looking
at the other online modules for languages similar to C# (Java, Python, C++,
Ada). Still other languages take quite a different approach to problem solving.
In Chapter 10 of Invitation to Computer Science, we look at some other lan-
guages and language approaches and also address the question of why there
are so many different programming languages.
8 Conclusion 75
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 76
EXERCISES
1. Write a C# declaration for one real number quantity to be output statement that prints these two quantities along
called rate. with appropriate text information.
2. Write a C# declaration for two integer quantities called 10. The integer quantities A, B, C, and D currently have the
orderOne and orderTwo. values 13, 4, 621, and 18, respectively. Write the exact
3. Write a C# declaration for a constant quantity called output generated by the following statement, using b to
evaporationRate, which is to have the value 6.15. denote a blank space.
5. You want to write a C# program to compute the average 11. Write C# formatting and output statements to generate
of three quiz grades for a single student. Decide what the following output, assuming that density is a type
variables your program needs, and write the necessary double variable with the value 63.78.
declarations. The current density is 63.8,
6. Given the declaration to within one decimal place.
int[] list = new int[10]; 12. What is the output after the following sequence of state-
ments is executed? (Assume that the integer variables A
how do you refer to the eighth number in the array? and B have been declared.)
7. An array declaration such as A = 12;
int[,] table = new int[5,3]; B = 20;
B = B + 1;
represents a two-dimensional table of values with 5 rows
A = A + B;
and 3 columns. Rows and columns are numbered in C#
Console.WriteLine(2*A);
starting at 0, not at 1. Given this declaration, how do
you refer to the marked cell below? 13. Write the body of a C# Main function that gets the length
and width of a rectangle from the user and computes and
writes out the area. Assume that the variables have all
been declared.
14. a. In the SportsWorld program of Figure 15, the user
must respond with C to choose the circumference
task. In such a situation, it is preferable to accept
either uppercase or lowercase letters. Rewrite the
condition in the program to allow this.
b. In the SportsWorld program, rewrite the condition for
continuation of the program to allow either an upper-
case or a lowercase response.
15. Write a C# Main function that gets a single character
from the user and writes out a congratulatory message if
the character is a vowel (a, e, i, o, or u), but otherwise
writes out a You lose, better luck next time message.
16. Insert the missing line of code so that the following adds
the integers from 1 to 10, inclusive.
value = 0;
top = 10;
score = 1;
8. Write C# statements to prompt for and collect values for while (score <= top)
the time in hours and minutes (two integer quantities). {
9. An output statement may contain more than one variable value = value + score;
identifier. Say a program computes two integer quantities - - - - //the missing line
inventoryNumber and numberOrdered. Write a single }
76 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:55 PM Page 77
EXERCISES
17. What is the output after the following Main function is 24. a. Write a C# program that reads in 10 integer quiz
executed? grades and computes the average grade. (Hint:
static void Main(string[] args) Remember the peculiarity of integer division.)
{ b. Write a C# program that asks the user for the number
int low, high; of quiz grades, reads them in, and computes the
low = 1; average grade.
high = 20; 25. Write a (void) C# function that receives two integer
while (low < high) arguments and writes out their sum and their product.
{
Console.WriteLine(low + + 26. Write a (void) C# function that receives an integer
high); argument representing the number of DVDs rented so far
low = low + 1; this month and a real number argument representing the
high = high 1; sales amount for DVDs sold so far this month. The
} function asks the user for the number of DVDs rented
} today and the sales amount for DVDs sold today, and
then returns the updated figures to the Main function.
18. Write a C# Main function that outputs the even integers
from 2 through 30, one per line. Use a while loop. 27. Write a (nonvoid) C# function that receives three integer
arguments and returns the maximum of the three values.
19. In a while loop, the Boolean condition that tests for loop
continuation is done at the top of the loop, before each 28. Write a (nonvoid) C# function that receives miles driven
iteration of the loop body. As a consequence, the loop as a type double argument and gallons of gas used as a
body might not be executed at all. Our pseudocode type int argument, and returns miles per gallon.
language of Chapter 2 contains a do-while loop construc- 29. Write a C# program that uses an input function to get the
tion in which a test for loop termination occurs at the miles driven (type double) and the gallons of gas used
bottom of the loop rather than at the top, so that the (type int), then writes out the miles per gallon, using the
loop body always executes at least once. C# contains a function from Exercise 28.
do-while statement that tests for loop continuation at
the bottom of the loop. The form of the statement is 30. Write a C# program to balance a checkbook. The program
needs to get the initial balance, the amounts of deposits,
do and the amounts of checks. Allow the user to process as
S1; many transactions as desired; use separate functions to
while (Boolean condition); handle deposits and checks.
where, as usual, S1 can be a compound statement. Write 31. Write a C# program to compute the cost of carpeting
a C# Main function to add up a number of nonnegative three rooms. Make the carpet cost a constant of $8.95
integers that the user supplies and to write out the total. per square yard. Use four separate functions to collect
Use a negative value as a sentinel, and assume that the the dimensions of a room in feet, convert feet into yards,
first value is nonnegative. Use a do-while statement. compute the area, and compute the cost per room. The
20. Write a C# program that asks for a duration of time in Main function should use a loop to process each of the
hours and minutes, and writes out the duration only in three rooms, then add the three costs, and write out the
minutes. total cost. (Hint: The function to convert feet into yards
21. Write a C# program that asks for the users age in years. must be used twice for each room, with two different
If the user is under 35, then quote an insurance rate of arguments. Hence, it does not make sense to try to give
$2.23 per $100 for life insurance; otherwise, quote a rate the parameter the same name as the argument.)
of $4.32. 32. a. Write a C# doPerimeter function for the Rectangle class
22. Write a C# program that reads integer values until a 0 of Figure 29.
value is encountered and then writes out the sum of the b. Write C# code that creates a new Rectangle object
positive values read and the sum of the negative values called yuri, then writes out information about this
read. object and its perimeter using the doPerimeter
function from part (a).
23. Write a C# program that reads in a series of positive
integers and writes out the product of all the integers 33. Draw a class hierarchy diagram similar to Figure 31 for
less than 25 and the sum of all the integers greater than the following classes: Student, UndergraduateStudent,
or equal to 25. Use 0 as a sentinel value. GraduateStudent, Sophomore, Senior, PhDStudent.
Exercises 77
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:56 PM Page 78
EXERCISES
34. Imagine that you are writing a program using an object- 41. Write a program that inputs the coordinates of three mouse
oriented programming language. Your program will be clicks from the user and then draws a triangle in the output
used to maintain records for a real estate office. Decide window using those three points. Here are some hints:
on one class in your program and a service that objects Unlike the mouseclick event handler shown in the text, this
of that class might provide. event handler will do some actual drawing on the canvas.
35. Determine the resolution of the screen on your computer This means that the graphics canvas and the pen need to
(ask your instructor or the local computer center how to be visible to the event handler, so they need to be declared
do this). Using this information, determine how many in the Form partial class that contains both the Form1 code
bytes of memory are required for the frame buffer to and the event handler code. There must also be a counter
store: variable to keep track of which of the three mouseclicks
has just been made, as well as variables to hold the three
a. A black-and-white image (1 bit per pixel)
sets of coordinates. The values for these variables have to
b. A grayscale image (8 bits per pixel) persist through all three invocations of the event handler,
c. A color image (24 bits per pixel) so their declarations will also go in the Form1 partial class.
36. Using the DrawLine command described in Section 7.2, Here is the code for the start of the program.
draw an isosceles triangle with the following configuration: public partial class Form1 : Form
{
(100, 30) Graphics drawingCanvas;
Pen BlackPen;
int counter = 0;
int x1, y1, x2, y2, x3, y3;
public Form1()
{
(50, 100) (150, 100)
// form on which drawing
37. Discuss what problem the display hardware might // will occur
encounter while attempting to execute the following // initialize form
operations, and explain how this problem could be InitializeComponent();
solved. this.Text = "C# Graphics";
DrawLine(blackPen, 1, 1, 4, 5); drawingCanvas =
38. Draw a square with sides 100 pixels in length. Then CreateGraphics();
inscribe a circle of radius 50 inside the square. Position Show();
the square and the inscribed circle in the middle of the BlackPen = new Pen
screen. (Color.Black, 2);
39. Create the following three labeled rectangular buttons in } //end Public Form 1
the output window. Here is the start of the MouseClick event handler:
private void Form1_MouseClick
(object sender,
Start Stop Pause
MouseEventArgs e)
{
counter = counter + 1;
Have the space between the Start and Stop buttons be the if (counter == 1)
same as the space between the Stop and Pause buttons. {
40. Create the following image of a teeter-totter: x1 = e.X;
y1 = e.Y;
}
There will need to be two more if statements to capture the
x, y values for the second and third clicks. The drawing code
for the triangle will be in the body of the third if statement.
78 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:56 PM Page 79
class Problem
{
static void Main(string[] args)
{
int number, square;
Console.Write(Enter a number: );
number = Convert.ToInt32(Console.ReadLine());
square = number * number;
Console.WriteLine(The square is + square);
}
}
}
2.
//program to compute cost based on price per item
//and quantity purchased
using System;
namespace PracticeProblem
{
class Problem
{
static void Main(string[] args)
{
int quantity;
double price, totalCost;
Console.Write(Enter the price: );
price = Convert.ToDouble(Console.ReadLine());
Console.Write(Enter the quantity: );
quantity = Convert.ToInt32(Console.ReadLine());
totalCost = price * quantity;
Console.WriteLine(The total cost is +
totalCost.ToString(####.00));
}
}
}
3.
//program to test a number relative to 5
//and write out the number or its double
using System;
namespace PracticeProblem
{
class Problem
{
static void Main(string[] args)
{
int number;
Console.Write(Enter the number: );
number = Convert.ToInt32(Console.ReadLine());
if (number < 5)
{
Console.WriteLine(The number is + number);
}
80 Programming in C#
2016 Course Technology, a part of Cengage Learning.
C8814_chapter_c.qxd 1/23/15 7:56 PM Page 81
else
{
Console.WriteLine(Twice the number is +
number * 2);
}
}
}
}
4.
//program to collect a number, then write all
//the values from 1 to that number
using System;
namespace PracticeProblem
{
class Problem
{
static void Main(string[] args)
{
int number;
int i;
Console.Write(Enter a positive integer: );
number = Convert.ToInt32(Console.ReadLine());
i = 1;
while(i <= number)
{
Console.WriteLine(The number is + i);
i = i + 1;
}
}
}
}
Section 5.3 1. 11
2. 7
3.
static void getInput(ref int one, ref int two)
{
Console.Write(Input the value for One: );
one = Convert.ToInt32(Console.ReadLine());
Console.Write(Input the value for Two: );
two = Convert.ToInt32(Console.ReadLine());
}
4.
a. static double tax(double subTotal)
b. return subTotal * rate;
c. Console.WriteLine(Total: +
tax(subTotal).ToString(0.00));
Section 6.4 1. The area of a square with side 10 is 100
2. height and base
82 Programming in C#
2016 Course Technology, a part of Cengage Learning.