copyright © 1998-2015 curt hill the if revisited if part 4 style and testing
TRANSCRIPT
Copyright © 1998-2015 Curt Hill
The IF Revisited
If part 4Style and Testing
Copyright © 1998-2015 Curt Hill
Now what?• There are several more issues that
need consideration• Nesting• Testing• If problems
Copyright © 1998-2015 Curt Hill
Nesting
• Any statement may be the THEN or ELSE statement of an if
• It is most often a compound statement
• The interesting one is an if in an if• The usual problem is how the elses
match the ifs
Copyright © 1998-2015 Curt Hill
Which else?
• The else may only match one of these
• Which one is it?• The answer is 3!
if(a>b) // 1 if(b>c) // 2 if(c>d)// 3 x = y;else x = z;
Copyright © 1998-2015 Curt Hill
Matching Elses
• The general rule is that an else matches the closest, previous, unmatched if
• The language ignores white space and also the layout on the page– Thus indenting has no relevance to
the compiler– It may make the program more (or
less) readable
Copyright © 1998-2015 Curt Hill
A Matched Else
• How is an if matched?• An else is encountered for it• It is enclosed within a compound
statement• An unrelated statement follows
Copyright © 1998-2015 Curt Hill
Three examplesif(a>b) // 1 if(b>c){ // 2 if(c>d)// 3 x = y; } else // matches 2 x = z;
if(a>b) // 1 if(b>c) // 2 if(c>d)// 3 x = y; else x = 2*y; else // matches 2 x = z;
if(a>b) // 1 x = y; y = x*z; else // error x = z;
Copyright © 1998-2015 Curt Hill
Testing
• Ifs complicate our testing• With only sequential flow we test it
once and it is covered• With multiple paths one test is
generally inadequate• Testing strategies then come into
view
Copyright © 1998-2015 Curt Hill
Every Statement• The first strategy is to make sure
that in our testing every statement is tested once
• We generate test data accordingly• We have enough test data if each if has both its then and else exercised once
• This usually means several runs
Copyright © 1998-2015 Curt Hill
Every statement
if(a>b) { // 1 b = a++ * 2; c /= 2; }else // 2 c = a * b / 2;
Two tests are needed.One forces a > b and the other a <= b
1 2
Copyright © 1998-2015 Curt Hill
A path is a unique way through the code
1 2
3 4
There are four paths
1, 3
2, 3
1, 4
2, 4
Copyright © 1998-2015 Curt Hill
Test Data Again• In the above, every statement testing
only needs two runs– The paths {1,3} and {2,4} executes every
statement
• However, there may be interactions between 1 and 4 that are not exercised
• Thus every path testing is always as good or better than every statement– In programs without decisions or loops one
set does both
Copyright © 1998-2015 Curt Hill
How ifs increase paths
• An if added at the end of a sequence doubles the number of paths
• An if nested within an if adds one path to the existing number
• The generalities do not always capture the actual practice
• Reconsider the quadratic formula evaluation
Copyright © 1998-2015 Curt Hill
Two different approaches
if(discrim < 0) …else if(discrim == 0){ … } else { … }
if(discrim < 0){ …}if(discrim == 0){ …}if(discrim > 0){ …}
Copyright © 1998-2015 Curt Hill
Commentary on above
• The nested if version is to be preferred
• If any of the conditions are true then no further ones will be checked– Typically check the most likely one first
rather than the straight order I used
• However, provided that discrim is not changed in the ifs both have three paths
Copyright © 1998-2015 Curt Hill
Largest of three variables• Here are two ways to display the largest
of three variables, a, b and c
if(a>b) if(a>c) cout << a; else cout << c;else if(b>c) cout << b; else cout << c;
double big;
big = a;if(big<b) big =b;if(big<c) big = c;
cout << big;
Which do you like better? Why?
Copyright © 1998-2015 Curt Hill
Comparison• The first one has two comparisons
and one write• The second one has two
comparisons, one to three assignments, one write and needs one temporary variable
• Both have four paths• Most professional programmers
like the second one• Easier to categorize where you are
Copyright © 1998-2015 Curt Hill
Paths and Complexity
• More paths cause more complexity• Complexity promotes errors• As programmers we work hard to
subdivide the problem to manage the complexity
• The magic number is 7 ± 2• TMI and cockpit stories
Error Checking
• If an error is found do one of two things– Do no other processing– Correct and continue
• At least two ways to do the former• The latter cannot be done in
general way– For any particular program there may
be a good correction
Copyright © 1998-2015 Curt Hill
Do Nothing Further• Again two ways
– Place rest of method in an else– Use the return statement
• Big else:if(ed->GetValue().length()<1) // complainelse { // rest of method in this
Copyright © 1998-2015 Curt Hill
Problems with this• If there are lots of separate checks then
the ifs and else get nested rather deeply– Deep nesting causes problems with
complexity
• Use the return statement:if(ed->GetValue().length()< 1){ ed->SetValue(“Empty field.”); return; }
• No else is needed
Copyright © 1998-2015 Curt Hill
Return Statement• Two forms:• In a void method, such as an event
handler:return ;
• In a method that returns a value:return expr;– This form will be considered during
function definition presentations
• Return exits the method and optionally returns a value– No else is needed following
Copyright © 1998-2015 Curt Hill
Correction• If there is an obvious correction use
that• Empty fields imply zero:if(edit1->GetValue().length()<1){ edit1->SetValue(“0”); }d = edit1->GetValue().ToInt();
• However, there is usually no easy fix• We will examine this again later
Copyright © 1998-2015 Curt Hill
Separating Ranges• Often we want to classify a value
by range• For instance a descriptive word for
the age of person:infant is less than 1 yearpreschool is less than 5 yearsetc
• This is usually done with a series of ifs– There is a right and wrong way
Copyright © 1998-2015 Curt Hill
Wrong Way• Not nested:if(age < 1) s = “infant”;if(age>=1 && age < 5) s = “preschool”;if(age>=5 && age < 12) …
• This works but there is lots of redundancy
• If s was set to “preschool” do we want to do another test
Copyright © 1998-2015 Curt Hill
Right Way• Nested with simple conditions:if(age < 1) s = “infant”;else if(age < 5) s = “preschool”;else if(age < 12) …
• Also works, but the first one to find it eliminates any further tests
Copyright © 1998-2015 Curt Hill
Not so right Way• Nested with ANDed conditions:if(age < 1) s = “infant”;else if(age>=1 && age<5) s = “preschool”;else if(age>=5 && age < 12) …
• Also works, but the age>=1 can never be false because of the nesting
Copyright © 1998-2015 Curt Hill