The body of a while statement can be either a single statement or a block: one or more statements 
enclosed in braces. The same is true for all statements that control the program flow, namely, if, do, for
and switch. Programs typically indent lines to show the statements that form part of the control statement. 
However, the indentation is only a visual clue for the human program reader; if no braces are given, the 
control will affect only the single statement that follows the respective control statement, regardless of the 
indentation. As an example, the following code does not do what is suggested by its indentation.
[16]
[16]
netbsdsrc/usr.sbin/timed/timed/timed.c:564–56 8
for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
if (ntp->status == MASTER)
rmnetmachs(ntp);
ntp->status = NOMASTER;
}
The line ntp->status = NOMASTER; will be executed for every iteration of the for loop and not just when the if condition is true.
Exercise 2.9 Discover how the editor you are using can identify matching braces and parentheses. If it cannot, consider switching to
another editor.
Exercise 2.10 The source code of expand contains some superfluous braces. Identify them. Examine all control structures that do not use 
braces and mark the statements that will get executed.
Exercise 2.11 Verify that the indentation of expand matches the control flow. Do the same for programs in your environment.
Exercise 2.12 The Perl language mandates the use of braces for all its control structures. Comment on how this affects the readability of
Perl programs.
[ Team LiB ]
Pdf image text extractor - Select, copy, paste PDF images in C#.net, ASP.NET, MVC, Ajax, WinForms, WPF
Support PDF Image Extraction from a Page, a Region on a Page, and PDF Document
extract pdf pages to jpg; extract images pdf
Pdf image text extractor - VB.NET PDF Image Extract Library: Select, copy, paste PDF images in vb.net, ASP.NET, MVC, Ajax, WinForms, WPF
Support PDF Image Extraction from a Page, a Region on a Page, and PDF Document
extract images from pdf acrobat; extract images from pdf online
[ Team LiB ]
2.4 
switch
Statements
The normal return values of getopt are handled by a switch statement. You will find switch statements 
used when a number of discrete integer or character values are being processed. The code to handle 
each value is preceded by a case label. When the value of the expression in the switch statement 
matches the value of one of the case labels, the program will start to execute statements from that point 
onward. If none of the label values match the expression value and a default label exists, control will 
transfer to that point; otherwise, no code within the switch block will get executed. Note that additional 
labels encountered after transferring execution control to a label will not terminate the execution of 
statements within the switch block; to stop processing code within the switch block and continue with 
statements outside it, a break statement must be executed. You will often see this feature used to group 
case labels together, merging common code elements. In our case when getopt returns 't', the statements 
that handle -t are executed, with break causing a transfer of execution control immediately after the 
closing brace of the switch block (Figure 2.3:4
). In addition, we can see that the code for the default switch
label and the error return value ´?´ is common since the two corresponding labels are grouped together.
When the code for a given case or default label does not end with a statement that transfers control out of 
the switch block (such as break, return, or continue), the program will continue to execute the statements 
following the next label. When examining code, look out for this error. In rare cases the programmer 
might actually want this behavior. To alert maintainers to that fact, it is common to mark these places 
with a comment, such as FALLTHROUGH, as in the following example.
[17]
[17]
netbsdsrc/bin/ls/ls.c:173–17 8
case 'a':
fts_options |= FTS–SEEDOT ;
/* FALLTHROUGH */
case 'A':
f_listdot = 1;
break;
The code above comes from the option processing of the Unix ls  command, which lists files in a directory. The option -A  will include in the 
list files starting with a dot (which are, by convention, hidden), while the option -a modifies this behavior by adding to the list the two 
directory entries. Programs that automatically verify source code against common errors, such as the Unix lint command, can use the 
FALLTHROUGH comment to suppress spurious warnings.
switch statement lacking a default label will silently ignore unexpected values. Even when one knows 
that only a fixed set of values will be processed by a switch statement, it is good defensive programming 
practice to include a default label. Such a default label can catch programming errors that yield 
unexpected values and alert the program maintainer, as in the following example.
[18]
[18]
netbsdsrc/usr.bin/at/at.c:535–56 1
switch (program) {
case ATQ:
[...]
VB.NET TIFF: TIFF Text Extractor SDK; Extract Text Content from
Standalone VB.NET TIFF text extractor SDK that extracts can easily integrate this TIFF text extraction control SDK into VB.NET image application by
pdf image extractor c#; extract image from pdf c#
VB.NET TIFF: TIFF to Text (TXT) Converter SDK; Convert TIFF to
developers to interpret and decode TIFF image file convert all TIFF page into one text file to provide powerful & profession imaging controls, PDF document, tiff
pdf image text extractor; extract pictures from pdf
case BATCH:
writefile(time(NULL), 'b');
break;
default:
panic("Internal error");
break;
}
In our case the switch statement can handle two getopt return values.
't' is returned to handle the -t option. Optind will point to the argument of -t. The processing is handled by calling the function 
getstops with the tab specification as its argument.
1.
'?' is returned when an unknown option or another error is found by getopt. In that case the usage function will print program 
usage information and exit the program.
2.
switch statement is also used as part of the program's character-processing loop (Figure 2.3:7
). Each character is examined and some 
characters (the tab, the newline, and the backspace) receive special processing.
Exercise 2.13 The code body of switch statements in the source code collection is formatted differently from the other statements. 
Express the formatting rule used, and explain its rationale.
Exercise 2.14 Examine the handling of unexpected values in switch statements in the programs you read. Propose changes to detect 
errors. Discuss how these changes will affect the robustness of programs in a production environment.
Exercise 2.15 Is there a tool or a compiler option in your environment for detecting missing break statements in switch code? Use it, and 
examine the results on some sample programs.
[ Team LiB ]
VB.NET PowerPoint: Extract & Collect PPT Slide(s) Using VB Sample
demo code using RasterEdge VB.NET PowerPoint extractor library toolkit. provide powerful & profession imaging controls, PDF document, image to pdf files and
extract vector image from pdf; extract photos from pdf
VB.NET Word: Extract Word Pages, DOCX Page Extraction SDK
this VB.NET Word page extractor add-on can be also used to merge / split Word file, add / delete Word page, sort Word page order or insert image into Word page
some pdf image extract; extract color image from pdf in c#
[ Team LiB ]
2.5 
for
Loops
To complete our understanding of how expand processes its command-line options, we now need to examine the getstops function. 
Although the role of its single cp argument is not obvious from its name, it becomes apparent when we examine howgetstops  is used. 
getstops is passed the argument of the -t option, which is a list of tab stops, for example, 4, 8, 16, 24. The strategies outlined for 
determining the roles of functions (Section 2.2
) can also be employed for their arguments. Thus a pattern for reading code slowly 
emerges. Code reading involves many alternative strategies: bottom-up and top-down examination, the use of heuristics, and review of 
comments and external documentation should all be tried as the problem dictates.
After setting nstops to 0, getstops enters a for loop. Typically a for loop is specified by an expression to be evaluated before the loop 
starts, an expression to be evaluated before each iteration to determine if the loop body will be entered, and an expression to be 
evaluated after the execution of the loop body. for loops are often used to execute a body of code a specific number of times.
[19]
[19]
cocoon/src/java/org/apache/cocoon/util/StringUtils.java:85
for (i = 0; i < len; i++) {
Loops of this type appear very frequently in programs; learn to read them as "execute the body of code 
len times." On the other hand, any deviation from this style, such as an initial value other than 0 or a 
comparison operator other than <, should alert you to carefully reason about the loop's behavior. 
Consider the number of times the loop body is executed in the following examples.
Loop extrknt + 1 times:
[20]
[20]
netbsdsrc/usr.bin/fsplit/fsplit.c:173
for (i = 0; i <= extrknt; i++)
Loop month - 1 times:
[21]
[21]
netbsdsrc/usr.bin/cal/cal.c:332
for (i = 1; i < month; i++)
Loop nargs times:
[22]
[22]
netbsdsrc/usr.bin/apply/apply.c:130
for (i = 1; i <= nargs; i++)
Note that the last expression need not be an increment operator. The following line will loop 256 times, decrementing code in the 
process:
[23]
[23]
netbsdsrc/usr.bin/compress/zopen.c:510
for (code = 255; code >= 0; code--) {
C# Word: How to Extract Text from C# Word in .NET Project
is the complete Visual C# sample code for extracting text from a to provide powerful & profession imaging controls, PDF document, image to pdf files and
extract pictures pdf; extract pdf images
In addition, you will find for statements used to loop over result sets returned by library functions. The 
following loop is performed for all files in the directory dir.
[24]
[24]
netbsdsrc/usr.bin/ftp/complete.c:193–19 8
if ((dd = opendir(dir)) == NULL)
return (CC_ERROR);
for (dp = readdir(dd); dp != NULL; dp = readdir(dd)) {
The call to opendir returns a value that can be passed to readdir to sequentially access each directory entry of dir. When there are no 
more entries in the directory, readdir will return NULL and the loop will terminate.
The three parts of the for specification are expressions and not statements. Therefore, if more than one 
operation needs to be performed when the loop begins or at the end of each iteration, the expressions 
cannot be grouped together using braces. You will, however, often find expressions grouped together 
using the expression-sequencing comma (,) operator.
[25]
[25]
netbsdsrc/usr.bin/vi/vi/vs smap.c:389
for (cnt = 1, t = p; cnt <= cnt
orig; ++t, ++cnt) {
The value of two expressions joined with the comma operator is just the value of the second expression. In our case the expressions are 
evaluated only for their side effects: before the loop starts, cnt will be set to 1 and t to p, and after every loop iteration t and cnt will be 
incremented by one.
Any expression of a for statement can be omitted. When the second expression is missing, it is taken as true. Many programs use a 
statement of the form for (;;) to perform an "infinite" loop. Very seldom are such loops really infinite. The following example—taken out o f
init, the program that continuously loops, controlling all Unix processes—is an exception n .
[26]
[26]
netbsdsrc/sbin/init/init.c:540–54 5
Figure 2.5 Expanding tab stops (supplementary functions).
static void
getstops(char *cp)
{
int i;
nstops = 0;
for (;;) {
i = 0;
while (*cp >= '0' && *cp <= '9')
i = i * 10 + *cp++ - '0';
if (i <= 0 || i > 256) {
bad:
fprintf(stderr, "Bad tab stop spec\n");
exit(1);
}
if (nstops > 0 && i <= tabstops[nstops-1])
goto bad;
tabstops[nstops++] = i;
if (*cp == 0)
break;
if (*cp != ',' && *cp != ' ')
goto bad;
cp++;
}
}
static void
usage(void)
{
(void)fprintf (stderr, "usage: expand [-t tablist] [file ...]\n");
exit(1);
}
Parse tab stop specification
Convert string to number
Complain about unreasonable specifications
Verify ascending order
Break out of the loop
Verify valid delimiters
break will transfer control here
Print program usage and exit
for (;;) {
s = (state_t) (*s)();
quiet = 0;
}
In most cases an "infinite" loop is a way to express a loop whose exit condition(s) cannot be specified at 
its beginning or its end. These loops are typically exited either by a return statement that exits the 
function, a break statement that exits the loop body, or a call toexit  or a similar function that exits the 
entire program. C++, C#, and Java programs can also exit such loops through an exception (see Section 
5.2
).
A quick look through the code of the loop in Figure 2.5
provides us with the possible exit routes.
A bad stop specification will cause the program to terminate with an error message (Figure 2.5:3
).
The end of the tab specification string will break out of the loop.
Exercise 2.16 The for statement in the C language family is very flexible. Examine the source code provided to create a list of ten 
different uses.
Exercise 2.17 Express the examples in this section using while instead of for. Which of the two forms do you find more readable?
Exercise 2.18 Devise a style guideline specifying when while loops should be used in preference to for loops. Verify the guideline against 
representative examples from the book's CD-ROM.
[ Team LiB ]
[ Team LiB ]
2.6 
break
and 
continue
Statements
break statement will transfer the execution to the statement after the innermost loop orswitch  statement (Figure 2.5:7
). In most cases 
you will find break used to exit early out of a loop. A continue statement will continue the iteration of the innermost loop without executing 
the statements to the end of the loop. A continue statement will reevaluate the conditional expression of while and do loops. In for loops it 
will evaluate the third expression and then the conditional expression. You will find continue used where a loop body is split to process 
different cases; each case typically ends with a continue statement to cause the next loop iteration. In the program we are examining, 
continue is used after processing each different input character class (Figure 2.3:8
).
Note when you are reading Perl code that break and continue are correspondingly named last and next.
[27]
[27]
perl/lib/unicode/mktables.PL:415–42 5
while (<UD>) {
chomp;
if (s/0x[\d\w]+\s+\((.*?)\)// and $wanted eq $1) {
[...]
last;
}
}
To determine the effect of a break statement, start reading the program upward from break until you encounter the first while, fordo,or 
switch block that encloses the break statement. Locate the first statement after that loop; this will be the place where control will transfer 
when break is executed. Similarly, when examining code that contains a continue statement, start reading the program upward from 
continue until you encounter the first whilefor, or do loop that encloses the continue statement. Locate the last statement of that loop; 
immediately after it (but not outside the loop) will be the place where control will transfer when continue is executed. Note that continue
ignores switch statements and that neither break nor continue affect the operation of if statements.
There are situations where a loop is executed only for the side effects of its controlling expressions. In 
such cases continue is sometimes used as a placeholder instead of the empty statement (expressed by a 
single semicolon). The following example illustrates such a case.
[28]
[28]
netbsdsrc/usr.bin/error/pi.c:174–17 5
for (; *string && isdigit(*string); string++)
continue;
In Java programs break and continue can be followed by a label identifier. The same identifier, followed by a colon, is also used to label a 
loop statement. The labeled form of the continue statement is then used to skip an iteration of a nested loop; the label identifies the loop 
statement that the corresponding continue will skip. Thus, in the following example, the continue skip; statement will skip one iteration of 
the outermost for statement.
[29]
[29]
jt4/jasper/src/share/org/apache/jasper/compiler/JspReader.java:472–48 2
skip:
for ( [...]) {
if ( ch == limit.charAt(0)) {
for (int i = 1 ; i < limlen ; i++) {
if ( [...] )
continue skip;
}
return ret;
}
}
Similarly, the labeled form of the break statement is used to exit from nested loops; the label identifies the statement 
that the corresponding break will terminate. In some cases a labeled break or continue statements is used, even when 
there are no nested loops, to clarify the corresponding loop statement.
[30]
[30]
cocoon/src/scratchpad/src/org/apache/cocoon/treeprocessor/MapStackResolver.java:201–24 4
comp : while(prev < length) {
[...]
if (pos >= length || pos == -1) {
[...]
break comp;
}
}
Exercise 2.19 Locate ten occurrences of break and continue in the source code provided with the book. For each case indicate the point 
where execution will transfer after the corresponding statement is executed, and explain why the statement is used. Do not try to 
understand in full the logic of the code; simply provide an explanation based on the statement's use pattern.
[ Team LiB ]
[ Team LiB ]
2.7 Character and Boolean Expressions
The body of the for loop in the getstops function starts with a block of code that can appear cryptic at first sight (Figure 2.5:2
). To 
understand it we need to dissect the expressions that comprise it. The first, the condition in the while loop, is comparing *cp (the 
character cp points to) against two characters: ´0´ and ´9´. Both comparisons must be true and both of them involve *cp combined with a 
different inequality operator and another expression. Such a test can often be better understood by rewriting the comparisons to bring 
the value being compared in the middle of the expression and to arrange the other two values in ascending order. This rewriting in our 
case would yield
while ( '\'0' <= *cp && *cp <= '9')
This can then be read as a simple range membership test for a character c.
c 
9
Note that this test assumes that the digit characters are arranged sequentially in ascending order in the 
underlying character set. While this is true for the digits in all character sets we know, comparisons 
involving alphabetical characters may yield surprising results in a number of character sets and locales. 
Consider the following typical example.
[31]
[31]
netbsdsrc/games/hack/hack.objnam.c:352–25 3
if ('a' <= *s && *s <= 'z')
*s -= ( 'a' - 'A');
The code attempts to convert lowercase characters to uppercase by subtracting from each character found to be lowercase (as 
determined by the if test) the character set distance from ´a´ to ´A´. This fragment will fail to work when there are lowercase characters in 
character set positions outside the range a...z, when the character set range a...z contains non lowercase characters, and when the code 
of each lower case character is not a fixed distance away from the corresponding uppercase character. Many non-ASCII character sets 
exhibit at least one of these problems.
The next line in the block (Figure 2.5:2
) can also appear daunting. It modifies the variable i based on the values of i and *cp and two 
constants: 10 and ´0´ while at the same time incrementing cp. The variable names are not especially meaningful, and the program author 
has not used macro or constant definitions to document the constants; we have to make the best of the information available.
We can often understand the meaning of an expression by applying it on sample data. In our case we can work based on the initial value 
of i (0) and assume that cp points to a string containing a number (for example24, ) based on our knowledge of the formatting 
specifications that expand accepts. We can then create a table containing the values of all variables and expression parts as each 
expression part is evaluated. We use the notation i' and *cp' to denote the variable value after the expression has been evaluated.
Iteration
i
i*10
*cp
*cp-'0'
i'
*cp'
0
0
0
'2'
2
2
'4'
1
2
20
'4'
4
24
0
The expression*cp - '0' uses a common idiom: by subtracting the ordinal value of '0' from *cp the 
expression yields the integer value of the character digit pointed to by *cp. Based on the table we can 
Documents you may be interested
Documents you may be interested