Directory UMM :wiley:Public:college:compsci:miller:

xvi

CONTENTS

Contents

PREFACE
Special Features : : : : : : : : : :
Organization : : : : : : : : : : : :
Using This Book As A Textbook : :
Other Uses Of The Text : : : : : :
The Joy Of C Web Page : : : : : :
Contacting The Authors : : : : : :
Changes From The Previous Edition
Acknowledgments : : : : : : : : :

: : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : :

: : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : :

Part I A GENTLE INTRODUCTION TO C
1 GETTING STARTED WITH C
1.1 AN INTRODUCTION TO C : : : : : : : : : : : : : : : :
1.2 A FIRST C PROGRAM : : : : : : : : : : : : : : : : : :
The main Program : : : : : : : : : : : : : : : : : : : :
The printf Statement : : : : : : : : : : : : : : : : : :
1.3 COMPILING AND RUNNING C PROGRAMS : : : : : :
1.4 IMPROVING OUR INITIAL PROGRAM—COMMENTS
1.5 FURTHER IMPROVING OUR INITIAL PROGRAM : :
Function Prototypes and Include Files : : : : : : : : : : :
Return Values : : : : : : : : : : : : : : : : : : : : : : :
1.6 A SECOND C PROGRAM : : : : : : : : : : : : : : : :
Variable Declarations : : : : : : : : : : : : : : : : : : :
Assignment Statements : : : : : : : : : : : : : : : : : : :
Formatted Output with printf : : : : : : : : : : : : :
1.7 IMPROVING OUR SECOND PROGRAM : : : : : : : :

Defining Constants : : : : : : : : : : : : : : : : : : : : :
Using Field Widths with printf : : : : : : : : : : : : :
A Word To The Wise : : : : : : : : : : : : : : : : : : : :

v
vi
viii
x
xi
xii
xii
xii
xiv

1
: : : : : :
: : : : : :
: : : : : :
: : : : : :
: : : : : :

: : : : : :
: : : : : :
: : : : : :
: : : : : :
: : : : : :
: : : : : :
: : : : : :
: : : : : :
: : : : : :
: : : : : :
: : : : : :
: : : : : :

3
3
4
4
5
6
8

9
10
10
11
12
14
15
16
16
18
19

xvii

xviii

CONTENTS

2 GETTING COMFORTABLE WITH C
2.1 A PROGRAM TO COMPUTE SIMPLE INTEREST : : : : : : :

Using Some Familiar Features : : : : : : : : : : : : : : : : : : :
The while Loop : : : : : : : : : : : : : : : : : : : : : : : : :
2.2 DEALING WITH COMPILE ERRORS : : : : : : : : : : : : : :
2.3 A MORE COMPACT INTEREST COMPUTING PROGRAM : :
2.4 EXTENDING OUR INTEREST PROGRAM TO READ VALUES
Using scanf : : : : : : : : : : : : : : : : : : : : : : : : : : :
Repeatedly Reading Input : : : : : : : : : : : : : : : : : : : : :
2.5 A PROGRAM TO PROCESS SCORES : : : : : : : : : : : : : :
Another Input Reading Loop : : : : : : : : : : : : : : : : : : : :
The if Statement : : : : : : : : : : : : : : : : : : : : : : : : :
2.6 HANDLING INPUT ERRORS : : : : : : : : : : : : : : : : : :
2.7 THE ASSIGNMENT OPERATOR : : : : : : : : : : : : : : : : :
3 AN INTRODUCTION TO FUNCTIONS
3.1 WRITING OUR OWN FUNCTIONS : : : : : : : : :
Creating Functions : : : : : : : : : : : : : : : : : : :
Calling Functions : : : : : : : : : : : : : : : : : : :
Return Values : : : : : : : : : : : : : : : : : : : : :
Providing Function Prototypes : : : : : : : : : : : : :
Functions Without Return Values : : : : : : : : : : : :
Ignoring Function Return Values : : : : : : : : : : : :

Functions Without Parameters : : : : : : : : : : : : :
3.2 SEPARATE COMPILATION : : : : : : : : : : : : :
Recompiling When Fixing Mistakes : : : : : : : : : :
Reusing Object Modules : : : : : : : : : : : : : : : :
Support For Testing Functions : : : : : : : : : : : : :
3.3 SOME ADDITIONAL FEATURES OF FUNCTIONS :

: :
: :
: :
: :
: :
: :
: :
: :
: :
: :
: :
: :
: :


: : : : : : : :
: : : : : : : :
: : : : : : : :
: : : : : : : :
: : : : : : : :
: : : : : : : :
: : : : : : : :
: : : : : : : :
: : : : : : : :
: : : : : : : :
: : : : : : : :
: : : : : : : :
: : : : : : : :

Part II THE BASICS
4 NUMBERS
4.1 IDENTIFIERS AND NAMING CONVENTIONS
4.2 INTEGERS : : : : : : : : : : : : : : : : : : :
Integer Constants : : : : : : : : : : : : : : : :

Reading and Writing Integers : : : : : : : : : :
4.3 REALS : : : : : : : : : : : : : : : : : : : : : :
4.4 ARITHMETIC OPERATORS : : : : : : : : : :
Signed Integer Arithmetic : : : : : : : : : : : :
Unsigned Integer Arithmetic : : : : : : : : : : :
Floating Point Arithmetic : : : : : : : : : : : :
Arithmetic Functions : : : : : : : : : : : : : : :
4.5 TYPE CONVERSIONS : : : : : : : : : : : : :
Assignment Conversions : : : : : : : : : : : : :

23
23
24
25
27
30
32
33
34
36

37
37
41
45
51
51
53
55
56
56
58
60
60
61
65
66
68
71

81

: : : : : : : : : : :
: : : : : : : : : : :
: : : : : : : : : : :
: : : : : : : : : : :
: : : : : : : : : : :
: : : : : : : : : : :
: : : : : : : : : : :
: : : : : : : : : : :
: : : : : : : : : : :
: : : : : : : : : : :
: : : : : : : : : : :
: : : : : : : : : : :

83
83
84
85
87
91
92

93
96
96
97
97
97

4.6

Arithmetic Conversions : : : : : : : : : : : : : : : :
Casts : : : : : : : : : : : : : : : : : : : : : : : : : :
CASE STUDY—A BASE CONVERSION PROGRAM

CONTENTS

xix

: : : : : : : :

102
102
107

: : : : : : : :
: : : : : : : :

5 CHARACTERS
5.1 REPRESENTING AND STORING CHARACTERS : : : :
Character Constants : : : : : : : : : : : : : : : : : : : : :
Formatted Reading and Writing of Characters : : : : : : : :
5.2 CHARACTERS VERSUS INTEGERS : : : : : : : : : : :
5.3 CHARACTER INPUT AND OUTPUT : : : : : : : : : : :
5.4 CHARACTER TESTING FUNCTIONS : : : : : : : : : : :
5.5 CONVERTING CHARACTERS INTO NUMBERS : : : : :
5.6 CASE STUDY—A MORE GENERAL BASE CONVERTER
6 OPERATORS
6.1 OPERATORS, OPERANDS, AND PRECEDENCE
6.2 THE RELATIONAL OPERATORS : : : : : : : :
6.3 THE LOGICAL OPERATORS : : : : : : : : : :
6.4 BITWISE OPERATORS : : : : : : : : : : : : : :
Bit Shifts : : : : : : : : : : : : : : : : : : : : : :
Bitwise Logical Operators : : : : : : : : : : : : :
Getting and Setting Bits : : : : : : : : : : : : : :
Using Exclusive OR : : : : : : : : : : : : : : : :
Other Uses of Bitwise Operators : : : : : : : : : :
6.5 ASSIGNMENT OPERATORS : : : : : : : : : : :
Shorthand Assignment Operators : : : : : : : : :
Postfix and Prefix Assignment : : : : : : : : : : :
6.6 OTHER OPERATORS : : : : : : : : : : : : : : :
The Comma Operator : : : : : : : : : : : : : : :
The sizeof Operator : : : : : : : : : : : : : :
The Conditional Operator : : : : : : : : : : : : :
6.7 CASE STUDY—DATA COMPRESSION : : : : :
7 STATEMENTS
7.1 EXPRESSION STATEMENTS : : : : : :
7.2 COMPOUND STATEMENTS : : : : : : :
7.3 SIMPLE DECISIONS—THE IF : : : : : :
7.4 MULTIWAY DECISIONS—THE ELSE-IF
7.5 MULTIWAY DECISIONS—THE SWITCH
7.6 LOOPS : : : : : : : : : : : : : : : : : : :
The do-while Statement : : : : : : : : :
The for Statement : : : : : : : : : : : : :
7.7 THE NULL STATEMENT : : : : : : : : :
7.8 JUMP STATEMENTS : : : : : : : : : : :
The break Statement : : : : : : : : : : :
The continue Statement : : : : : : : :

: : : : :
: : : : :
: : : : :
: : : : :
: : : : :
: : : : :
: : : : :
: : : : :

: : : : : : : : : :
: : : : : : : : : :
: : : : : : : : : :
: : : : : : : : : :
: : : : : : : : : :
: : : : : : : : : :
: : : : : : : : : :
: : : : : : : : : :
: : : : : : : : : :
: : : : : : : : : :
: : : : : : : : : :
: : : : : : : : : :
: : : : : : : : : :
: : : : : : : : : :
: : : : : : : : : :
: : : : : : : : : :
: : : : : : : : : :

: : : : : : : : : : : : : :
: : : : : : : : : : : : : :
: : : : : : : : : : : : : :
: : : : : : : : : : : : : :
: : : : : : : : : : : : : :
: : : : : : : : : : : : : :
: : : : : : : : : : : : : :
: : : : : : : : : : : : : :
: : : : : : : : : : : : : :
: : : : : : : : : : : : : :
: : : : : : : : : : : : : :
: : : : : : : : : : : : : :

113
113
114
115
115
117
120
124
128
139
139
141
145
151
151
152
156
159
162
162
163
165
167
168
170
171
172
179
179
180
181
184
186
189
189
191
195
198
198
199

xx

CONTENTS

7.9

The goto Statement : : : : : : :
CASE STUDY—OCTAL DUMP

: : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : :

8 ARRAYS
8.1 USING ARRAYS—A PROGRAM TO REVERSE ITS INPUT
Preventing Illegal Array Accesses : : : : : : : : : : : : : : :
Using For Loops To Process Arrays : : : : : : : : : : : : : :
8.2 PASSING ARRAYS AS PARAMETERS : : : : : : : : : : :
A Function to Read Values into an Array : : : : : : : : : : : :
Arrays and Function Prototypes : : : : : : : : : : : : : : : :
Arrays and the sizeof Operator : : : : : : : : : : : : : :
8.3 SOME EXAMPLE PROGRAMS USING ARRAYS : : : : : :
Searching an Array with Sequential Search : : : : : : : : : :
Sorting an Array with Insertion Sort : : : : : : : : : : : : : :
8.4 CASE STUDY—A HISTOGRAM PRODUCER : : : : : : : :
9 PROGRAM STRUCTURE
9.1 LOCAL VARIABLES : : : : : : : : : : : :
Concise Variable Declarations : : : : : : : :
Initializing Local Variables : : : : : : : : : :
Declaring Variables within Blocks : : : : : :
9.2 GLOBAL VARIABLES : : : : : : : : : : :
9.3 STORAGE CLASSES : : : : : : : : : : : :
The Storage Class auto : : : : : : : : : :
The Storage Class register : : : : : : :
The Storage Class static : : : : : : : : :
The Storage Class extern : : : : : : : : :
9.4 TYPE QUALIFIERS : : : : : : : : : : : : :
9.5 USER-DEFINED TYPES : : : : : : : : : :
9.6 HEADER FILES : : : : : : : : : : : : : : :
9.7 PRIVATE VARIABLES AND FUNCTIONS
Implementing Queues : : : : : : : : : : : :
Implementing Our Bus Stop Simulator : : : :
9.8 CASE STUDY—ABSTRACT DATA TYPES
Implementing Sets : : : : : : : : : : : : : :
The Set Type And Its Operations : : : : : : :
Using Sets : : : : : : : : : : : : : : : : : :

: : : :
: : : :
: : : :
: : : :
: : : :
: : : :
: : : :
: : : :
: : : :
: : : :
: : : :

: : : : : : : : : : : : :
: : : : : : : : : : : : :
: : : : : : : : : : : : :
: : : : : : : : : : : : :
: : : : : : : : : : : : :
: : : : : : : : : : : : :
: : : : : : : : : : : : :
: : : : : : : : : : : : :
: : : : : : : : : : : : :
: : : : : : : : : : : : :
: : : : : : : : : : : : :
: : : : : : : : : : : : :
: : : : : : : : : : : : :
: : : : : : : : : : : : :
: : : : : : : : : : : : :
: : : : : : : : : : : : :
: : : : : : : : : : : : :
: : : : : : : : : : : : :
: : : : : : : : : : : : :
: : : : : : : : : : : : :

199
201
207
207
209
212
213
214
216
216
217
217
218
223
231
231
231
232
234
236
239
239
240
241
243
249
251
252
255
256
259
262
262
262
264

Part III ADVANCED DATA TYPES

271

10 POINTERS
10.1 POINTERS : : : : : : : : : : :
Declaring and Obtaining Pointers
Dereferencing Pointer Variables :
The Generic Pointer Type : : : :

273
273
273
274
274

: : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : :

CONTENTS

The Null Pointer : : : : : : : : : : : : : : : : : : : : : : : :
10.2 USING POINTERS TO SIMULATE CALL BY REFERENCE
The swap Function : : : : : : : : : : : : : : : : : : : : : :
Some Common Mistakes : : : : : : : : : : : : : : : : : : : :
10.3 TRAVERSING ARRAYS USING POINTERS : : : : : : : : :
Pointer Arithmetic : : : : : : : : : : : : : : : : : : : : : : :
Pointer Comparison : : : : : : : : : : : : : : : : : : : : : :
Concise Pointer Loops : : : : : : : : : : : : : : : : : : : : :
Pointers and Other Types of Arrays : : : : : : : : : : : : : :
10.4 ARRAY PARAMETERS AND POINTERS : : : : : : : : : :
10.5 POINTERS AS FUNCTION RETURN VALUES : : : : : : :
10.6 CONSTANTS AND POINTERS : : : : : : : : : : : : : : : :
10.7 GENERIC POINTERS AND POINTER CONVERSIONS : :
10.8 DYNAMICALLY ALLOCATING ARRAYS : : : : : : : : :
Allocating Storage with malloc : : : : : : : : : : : : : : :
Deallocating Storage with free : : : : : : : : : : : : : : :
An Example Of Dynamic Allocation : : : : : : : : : : : : : :
Some Common Mistakes : : : : : : : : : : : : : : : : : : : :
10.9 CASE STUDY—DYNAMICALLY ALLOCATED SETS : : :
11 STRINGS
11.1 STRING CONSTANTS : : : : : : : : : : : : : : : : : : : :
11.2 STRING VARIABLES : : : : : : : : : : : : : : : : : : : : :
11.3 BUILDING STRINGS FROM THE INPUT : : : : : : : : : :
11.4 STRING FUNCTIONS FROM THE STANDARD LIBRARY :
Using the Standard String Functions : : : : : : : : : : : : : :
Implementing the Standard String Functions : : : : : : : : : :
Additional String Functions : : : : : : : : : : : : : : : : : :
11.5 USING POINTERS TO TRAVERSE STRINGS : : : : : : : :
11.6 CASE STUDY—ELIMINATING DUPLICATE LINES : : : :
12 CONSTRUCTED TYPES
12.1 STRUCTURES : : : : : : : : : : : : : : : : :
Defining Structure Types : : : : : : : : : : : : :
Declaring Structure Variables : : : : : : : : : :
Accessing Structure Fields : : : : : : : : : : : :
Initializing Structures at Compile Time : : : : : :
Structures and Functions : : : : : : : : : : : : :
Structures and Operators : : : : : : : : : : : : :
Arrays of Structures : : : : : : : : : : : : : : :
12.2 BITFIELDS : : : : : : : : : : : : : : : : : : :
12.3 UNIONS : : : : : : : : : : : : : : : : : : : : :
12.4 ENUMERATED TYPES : : : : : : : : : : : : :
12.5 CASE STUDY—A DATA BASE APPLICATION
Storing the Data Base : : : : : : : : : : : : : :
The Data Base Program : : : : : : : : : : : : :

: : : :
: : : :
: : : :
: : : :
: : : :
: : : :
: : : :
: : : :
: : : :
: : : :
: : : :
: : : :
: : : :
: : : :
: : : :
: : : :
: : : :
: : : :
: : : :

: : : :
: : : :
: : : :
: : : :
: : : :
: : : :
: : : :
: : : :
: : : :

: : : : : : : : : : :
: : : : : : : : : : :
: : : : : : : : : : :
: : : : : : : : : : :
: : : : : : : : : : :
: : : : : : : : : : :
: : : : : : : : : : :
: : : : : : : : : : :
: : : : : : : : : : :
: : : : : : : : : : :
: : : : : : : : : : :
: : : : : : : : : : :
: : : : : : : : : : :
: : : : : : : : : : :

xxi

276
277
277
278
282
285
287
288
289
291
295
297
298
301
302
303
304
305
306
311
311
312
314
316
317
322
323
325
329
335
335
335
336
337
337
338
340
341
346
349
351
353
355
356

xxii

CONTENTS

13 ARRAYS OF ARRAYS
13.1 TWO-DIMENSIONAL ARRAYS : : : : : : : : : :
Initializing Two-Dimensional Arrays : : : : : : : : :
Storing Two-Dimensional Arrays : : : : : : : : : : :
13.2 POINTERS AND TWO-DIMENSIONAL ARRAYS
Traversing Columns : : : : : : : : : : : : : : : : :
Traversing Rows : : : : : : : : : : : : : : : : : : :
Accessing Rows : : : : : : : : : : : : : : : : : : :
13.3 MULTIDIMENSIONAL ARRAYS : : : : : : : : :
N-Dimensional Arrays and Parameters : : : : : : :
N-Dimensional Arrays and Pointers : : : : : : : : :
Initializing N-Dimensional Arrays : : : : : : : : : :
13.4 CASE STUDY—THE GAME OF LIFE : : : : : : :
An Array-Subscripting Version : : : : : : : : : : : :
A New Version Using Pointers : : : : : : : : : : : :
14 ARRAYS OF POINTERS
14.1 ARRAYS OF POINTERS—RAGGED ARRAYS
Accessing Individual Items : : : : : : : : : : : :
Dynamic String Allocation : : : : : : : : : : : :
14.2 POINTERS AND ARRAYS OF POINTERS : : :
14.3 COMMAND-LINE ARGUMENTS : : : : : : :
A Program To Echo Its Arguments : : : : : : : :
Command-Line Options : : : : : : : : : : : : :
14.4 CASE STUDY—SORTING STRINGS : : : : :

Part IV

: : : : : : : : :
: : : : : : : : :
: : : : : : : : :
: : : : : : : : :
: : : : : : : : :
: : : : : : : : :
: : : : : : : : :
: : : : : : : : :
: : : : : : : : :
: : : : : : : : :
: : : : : : : : :
: : : : : : : : :
: : : : : : : : :
: : : : : : : : :

: : : : : : : : : : :
: : : : : : : : : : :
: : : : : : : : : : :
: : : : : : : : : : :
: : : : : : : : : : :
: : : : : : : : : : :
: : : : : : : : : : :
: : : : : : : : : : :

ADVANCED PROGRAM STRUCTURE

15 THE PREPROCESSOR
15.1 PREPROCESSOR DIRECTIVES : : : : : : : : : : : : : :
15.2 SIMPLE MACRO SUBSTITUTION : : : : : : : : : : : :
15.3 MACRO SUBSTITUTION WITH PARAMETERS : : : : :
Using Macros in Macro Definitions : : : : : : : : : : : : :
Some Useful Macros : : : : : : : : : : : : : : : : : : : : :
Potential Problems : : : : : : : : : : : : : : : : : : : : : :
Macro Operators : : : : : : : : : : : : : : : : : : : : : : :
Undefining a Name : : : : : : : : : : : : : : : : : : : : : :
15.4 FILE INCLUSION : : : : : : : : : : : : : : : : : : : : : :
15.5 CONDITIONAL COMPILATION : : : : : : : : : : : : : :
Other Testing Directives : : : : : : : : : : : : : : : : : : :
Predefined Names : : : : : : : : : : : : : : : : : : : : : :
15.6 OTHER PREPROCESSOR DIRECTIVES : : : : : : : : :
15.7 CASE STUDY—IMPLEMENTING SETS WITH MACROS

365
365
367
370
370
371
377
378
380
381
383
384
386
386
391
397
397
398
402
405
410
410
412
414

423
: : : : :
: : : : :
: : : : :
: : : : :
: : : : :
: : : : :
: : : : :
: : : : :
: : : : :
: : : : :
: : : : :
: : : : :
: : : : :
: : : : :

425
425
425
430
434
434
438
440
441
441
445
449
449
450
452

CONTENTS

16 FUNCTIONS REVISITED
16.1 PASSING VARIABLE NUMBERS OF ARGUMENTS
Dealing with Differing Argument Types : : : : : : : :
Built-in Variable Argument Functions : : : : : : : : :
16.2 POINTERS TO FUNCTIONS : : : : : : : : : : : : :
16.3 OLD-STYLE DECLARATIONS AND DEFINITIONS
Type Checking Problems : : : : : : : : : : : : : : : :
Automatic Conversions : : : : : : : : : : : : : : : : :
Prototypes versus Old-Style Declarations : : : : : : :
16.4 CASE STUDY—BINARY SEARCH : : : : : : : : :
17 GENERIC FUNCTIONS
17.1 GENERIC LIBRARY FUNCTIONS : : : : : : : : : :
The bsearch Library Function : : : : : : : : : : :
The qsort Library Function : : : : : : : : : : : : :
17.2 WRITING GENERIC FUNCTIONS : : : : : : : : : :
Implementing a Generic Sequential Search : : : : : : :
Implementing a Generic Insertion Sort : : : : : : : : :
17.3 MAKING GENERIC FUNCTIONS EASIER TO USE
17.4 CASE STUDY—IMPLEMENTING BSEARCH : : : :

: : : : : : : :
: : : : : : : :
: : : : : : : :
: : : : : : : :
: : : : : : : :
: : : : : : : :
: : : : : : : :
: : : : : : : :
: : : : : : : :

: : : : : : : :
: : : : : : : :
: : : : : : : :
: : : : : : : :
: : : : : : : :
: : : : : : : :
: : : : : : : :
: : : : : : : :

18 COMPLEX DECLARATIONS
18.1 SOME NEW COMPLEX TYPES : : : : : : : : : : : : :
Arrays of Pointers to Functions : : : : : : : : : : : : : :
Functions That Return Pointers to Functions : : : : : : : :
18.2 CONSTRUCTING TYPE DECLARATIONS : : : : : : :
18.3 UNDERSTANDING COMPLEX TYPE DECLARATIONS
18.4 TYPE SPECIFICATIONS : : : : : : : : : : : : : : : : :
18.5 CASE STUDY—ENGLISH TO C : : : : : : : : : : : : :

: : : : : :
: : : : : :
: : : : : :
: : : : : :
: : : : : :
: : : : : :
: : : : : :

Part V C AND THE REAL WORLD
19 EXTERNAL FILES
19.1 ACCESSING EXTERNAL FILES : : : : : : : : : : : :
Character File I/O : : : : : : : : : : : : : : : : : : : :
Formatted File I/O : : : : : : : : : : : : : : : : : : : :
Line-Oriented File I/O : : : : : : : : : : : : : : : : : :
19.2 THE STANDARD FILES : : : : : : : : : : : : : : : :
19.3 RANDOM FILE ACCESS : : : : : : : : : : : : : : : :
19.4 BLOCK INPUT AND OUTPUT : : : : : : : : : : : : :
19.5 FILE UPDATING : : : : : : : : : : : : : : : : : : : :
19.6 CASE STUDY—AN ELECTRONIC ADDRESS BOOK

xxiii

457
457
460
462
464
470
475
476
476
477
487
487
487
492
495
496
499
503
506
511
511
511
513
515
520
522
523

531
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :

533
533
535
537
538
540
542
545
548
550

xxiv

CONTENTS

20 LISTS AND TREES
20.1 LINKED LISTS : : : : : : : : : : : : : : : : : : : : :
Representing Linked Lists : : : : : : : : : : : : : : : :
Common Linked List Operations : : : : : : : : : : : : :
Creating an Empty List : : : : : : : : : : : : : : : : : :
Traversing an Existing List : : : : : : : : : : : : : : : :
Inserting in a Sorted Linked List : : : : : : : : : : : : :
Destroying a Linked List : : : : : : : : : : : : : : : : :
Sorting Strings Using Linked Lists : : : : : : : : : : : :
Updating a Linked List : : : : : : : : : : : : : : : : : :
20.2 STACKS AND QUEUES—SPECIAL PURPOSE LISTS
Stacks : : : : : : : : : : : : : : : : : : : : : : : : : :
Queues : : : : : : : : : : : : : : : : : : : : : : : : : :
20.3 BINARY SEARCH TREES : : : : : : : : : : : : : : :
Binary Search Tree Operations : : : : : : : : : : : : : :
Building a Binary Search Tree : : : : : : : : : : : : : :
Traversing a Binary Search Tree : : : : : : : : : : : : :
A Tree Sort Program : : : : : : : : : : : : : : : : : : :
20.4 CASE STUDY—A CROSS-REFERENCE PROGRAM :
21 PORTABILITY
21.1 PRINCIPLES OF PORTABILITY : : : : : : : : : : : :
21.2 PORTING ACROSS ANSI-C COMPILERS : : : : : : :
21.3 PORTABILITY ACROSS OPERATING SYSTEMS : :
21.4 MACHINE DEPENDENCIES : : : : : : : : : : : : : :
Data Type Sizes : : : : : : : : : : : : : : : : : : : : :
Character Set Differences : : : : : : : : : : : : : : : :
Sign-Related Problems : : : : : : : : : : : : : : : : : :
Byte Ordering : : : : : : : : : : : : : : : : : : : : : :
Byte Alignment Problems : : : : : : : : : : : : : : : : :
Pointer Problems : : : : : : : : : : : : : : : : : : : : :
Evaluation Order : : : : : : : : : : : : : : : : : : : : :
Libraries and Machines : : : : : : : : : : : : : : : : :
21.5 PORTING TO NON-ANSI COMPILERS : : : : : : : :
Dealing with Function Prototypes : : : : : : : : : : : :
Generic Pointers : : : : : : : : : : : : : : : : : : : : :
Missing Header Files : : : : : : : : : : : : : : : : : :
21.6 CASE STUDY—PORTABLE I/O DEVICE HANDLING
Immediate Input : : : : : : : : : : : : : : : : : : : : :
Cursor Control : : : : : : : : : : : : : : : : : : : : : :

: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :

: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :

Part VI Moving From C To C++
22 C++ BASICS
22.1 COMPILING C PROGRAMS WITH C++ COMPILERS

559
559
560
562
563
563
565
567
567
569
573
573
573
577
578
578
580
582
583
591
591
592
594
596
596
597
599
601
602
603
604
605
605
607
608
609
611
613
615

623
: : : : : : :

625
625

CONTENTS

22.2

22.3

22.4
22.5
22.6

Function Prototypes : : : : : : : : : : : : : : : : : : : : : : : :
Pointer Usage : : : : : : : : : : : : : : : : : : : : : : : : : : :
Naming Problems : : : : : : : : : : : : : : : : : : : : : : : : :
SIMPLE BUT USEFUL C++ EXTENSIONS TO C : : : : : : : :
C++ Comments : : : : : : : : : : : : : : : : : : : : : : : : : :
An Improved const : : : : : : : : : : : : : : : : : : : : : : : :
Variable Declarations : : : : : : : : : : : : : : : : : : : : : : :
Structure Tags As Type Names : : : : : : : : : : : : : : : : : : :
A Boolean Type : : : : : : : : : : : : : : : : : : : : : : : : : :
IMPROVEMENTS TO FUNCTIONS : : : : : : : : : : : : : : :
Reference Parameters : : : : : : : : : : : : : : : : : : : : : : :
Inline Functions : : : : : : : : : : : : : : : : : : : : : : : : : :
Default Function Parameters : : : : : : : : : : : : : : : : : : :
Function Overloading : : : : : : : : : : : : : : : : : : : : : : :
Operator Overloading : : : : : : : : : : : : : : : : : : : : : : :
INPUT AND OUTPUT OPERATORS : : : : : : : : : : : : : : :
Overloading I/O Operators : : : : : : : : : : : : : : : : : : : :
STORAGE ALLOCATION AND DEALLOCATION : : : : : : :
CASE STUDY—A FIRST IMPLEMENTATION OF SETS IN C++
Implementing BitVectors : : : : : : : : : : : : : : : : : : : : : :
Using BitVectors To Implement Sets : : : : : : : : : : : : : : : :

: :
: :
: :
: :
: :
: :
: :
: :
: :
: :
: :
: :
: :
: :
: :
: :
: :
: :
: :
: :
: :

xxv

625
626
627
627
627
628
628
630
631
631
631
634
635
635
638
639
642
644
646
646
649

23 ENCAPSULATION WITH CLASSES
655
23.1 INTRODUCTION TO ENCAPSULATION : : : : : : : : : : : : : : 655
23.2 THE BASICS OF CLASSES : : : : : : : : : : : : : : : : : : : : : : 656
Declaring A Class : : : : : : : : : : : : : : : : : : : : : : : : : : : 656
Using A Class : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 658
Defining Class Operations : : : : : : : : : : : : : : : : : : : : : : : 659
Constructors : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 661
Some More Detail On Private And Public : : : : : : : : : : : : : : : 661
23.3 CONSTRUCTORS, DESTRUCTORS, ASSIGNMENT, AND FRIENDS663
Constructors That Take Parameters : : : : : : : : : : : : : : : : : : 663
Copy Constructors : : : : : : : : : : : : : : : : : : : : : : : : : : : 664
Destructors : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 668
Assignment Operators : : : : : : : : : : : : : : : : : : : : : : : : : 668
Friend Functions : : : : : : : : : : : : : : : : : : : : : : : : : : : : 670
23.4 LAYERING : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 672
Member Initialization Lists : : : : : : : : : : : : : : : : : : : : : : : 673
Destructors, Copy Constructors, and Assignment : : : : : : : : : : : 675
23.5 USING BUILT-IN CLASSES—ADDITIONAL I/O OPERATORS : : 677
Character-At-A-Time I/O : : : : : : : : : : : : : : : : : : : : : : : : 677
Line-At-A-Time Input and Output : : : : : : : : : : : : : : : : : : : 679
23.6 CONSTANT OBJECTS : : : : : : : : : : : : : : : : : : : : : : : : 680
23.7 CASE STUDY—A LAYERED IMPLEMENTATION OF SETS : : : : 683

xxvi

CONTENTS

24 INHERITANCE
24.1 A SIMPLE EXAMPLE OF INHERITANCE : : : : : : : : : : : : :
24.2 DEFINING INHERITED CLASSES : : : : : : : : : : : : : : : : :
Defining A Base Class : : : : : : : : : : : : : : : : : : : : : : : :
Deriving A New Class : : : : : : : : : : : : : : : : : : : : : : : :
Defining Derived Class Constructors : : : : : : : : : : : : : : : : :
Defining Derived Class Operations : : : : : : : : : : : : : : : : :
More Details On Deriving Classes : : : : : : : : : : : : : : : : : :
Using Our Class Hierarchy : : : : : : : : : : : : : : : : : : : : :
24.3 POLYMORPHISM AND DYNAMIC BINDING : : : : : : : : : :
24.4 ABSTRACT BASE CLASSES : : : : : : : : : : : : : : : : : : :
24.5 THE INPUT/OUTPUT HIERARCHY : : : : : : : : : : : : : : : :
24.6 CASE STUDY—A SIMPLE TEXT-BASED DRAWING LIBRARY
A LIBRARY DETAILS
A.1 THE STANDARD HEADER FILES
A.2 ERROR HANDLING : : : : : : :
A.3 THE MATH LIBRARY : : : : : :
A.4 THE STRING LIBRARY : : : : :
A.5 THE STANDARD C LIBRARY : :
String Conversion : : : : : : : : :
Random Number Generation : : : :
Environment Communication : : :
Integer Arithmetic : : : : : : : : :
Multibyte Characters : : : : : : : :
A.6 THE STANDARD I/O LIBRARY :
Removing and Renaming Files : : :
Temporary Files : : : : : : : : : :
Error Detection : : : : : : : : : :
Input/Output Redirection : : : : : :
Moving the File Pointer : : : : : :
Putting Characters Back : : : : : :
Controlling Buffering : : : : : : :
Formatted Output : : : : : : : : :
Formatted Input : : : : : : : : : :
A.7 LOCALES : : : : : : : : : : : : :
A.8 SIGNAL HANDLING : : : : : : :
A.9 NONLOCAL GOTOS : : : : : : :
A.10 TIME FUNCTIONS : : : : : : : :
B CHARACTER SETS
B.1 THE ASCII CHARACTER SET : :
B.2 THE EBCDIC CHARACTER SET
INDEX

:
:
:
:
:
:
:
:
:
:
:
:

: : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : :

: : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : :

693
693
694
694
698
698
701
701
705
705
709
714
717
725
725
725
727
728
729
731
732
732
734
735
736
736
737
737
738
738
738
739
739
743
746
749
752
753
761
761
762
573

Part I
A GENTLE INTRODUCTION
TO C
The first three chapters are a tutorial introduction to basic features of the
C language.

 Chapter 1 shows how to produce output, declare variables, and perform calculations, as well as how to compile and link C programs.
 Chapter 2 shows how to write loops, make simple decisions, and
read input.
 Chapter 3 presents user-defined functions, showing how they are
defined and called.

1

1

GETTING
STARTED
WITH C
This chapter is a gentle introduction to C. We begin with a pair of simple programs: one prints a welcoming message, the other calculates the
actual cost of purchasing a set of items. We describe these programs in
great detail and provide several variants of each. Along the way we introduce the basics of C program organization, the process of compilation and
linking, and several fundamental language features: the printf function
for performing formatted output, variable declaration and assignment, and
the arithmetic operators.

1.1

AN INTRODUCTION TO C
C is a general purpose, high-level programming language.
It is general purpose because there are an incredible variety of C-based application programs running on a wide-variety of platforms. These applications include
PC-oriented programs—word processors, drawing programs, spreadsheets, databases,
personal organizers, and financial accounting packages. They include applications that
require much faster, more expensive hardware and perform tasks such as complex simulations and transaction processing. And they include applications that run on specially
designed, special purpose computers and perform tasks such as real-time digital signal
processing
C is high-level because a single C language instruction may correspond to many
lower-level machine instructions, and because a C program can run on a variety of
different types of computers, regardless of the specific instructions they provide.
But there are lots of general purpose, high-level programming languages. Why is C
so popular?
Part of the reason is efficiency. Like any high-level language, C requires the use of
a compiler to translate C instructions into the machine instructions that a computer can
actually execute. C, however, was specifically designed to help compilers generate an
efficient machine language program. It also provides language features that help programmers make their programs more efficient. The result is that the machine language
programs that result from compiling C programs tend to execute as quickly as equivalent
3

4

GETTING STARTED WITH C

main()
{
printf("Welcome to the Joy of C!\n");
}
Figure 1.1 (welcome.c) A program to print a welcome message.

machine language programs written by hand. This may not seem too exciting, but before
C came along, the only way to produce programs that executed quickly enough was
often to hand-code them in machine language. These programs, however, took forever
to write and after all that work would still run on only a single type of computer. Now,
that’s rarely done, as C programs run quickly, can be written in much less time, and are
portable to many different types of computers.
Efficiency, however, isn’t the whole story. In fact, as computers have gotten faster,
efficiency has become less of a priority. What’s stayed very important is the amount of
time and effort it takes to write computer programs—the faster we can write a program,
the better. C helps here in that it is an expressive language—it is possible to say a lot
with very little. In particular, C provides a variety of language constructs that allow
us to succinctly describe the actions we want our program to perform. Although you
may at first struggle to understand the language’s syntax, once you master it, you will
appreciate the convenience this terseness gives us.
Finally, there’s one last reason C is popular. It’s a stepping stone to a language called
C++, which extends C to support object-oriented programming. C++ provides a number
of features that go far beyond C in terms of helping us write programs. However, we
pay a price: all of those features make C++ incredibly complex and, as a result, it can
be a very difficult language to learn. By first learning C and writing lots of C programs,
we can much more easily master C++.

1.2

A FIRST C PROGRAM
Figure 1.1 contains a very simple C program. When compiled and run, it prints the
message:
Welcome to the Joy of C!

Let’s dive right into this program to see exactly how it works.
The main Program
A C program is a collection of one or more functions.1 A function is a named collection
of statements, where each statement is a programming language-specific instruction.
1 C’s functions are analogous to functions in Pascal or FORTRAN. However, they can also play the role
of Pascal’s procedures and FORTRAN and BASIC’s subroutines. That is, unlike many other languages, C
provides only a single mechanism for grouping statements.

1.2 A FIRST C PROGRAM

5

When we provide the statements that make up the function, we are said to be defining
the function.
Our example program defines a single function named main, that consists of a
single printf.
main()
{
printf("Welcome to the Joy of C!\n");
}

Function definitions have two parts: a header and a body. At a minimum, the header
provides the function’s name, followed by a pair of parentheses, as in main’s header.
main()

The function’s body is a collection of statements. We enclose these statements in braces
({ and }) to group them with the function header. In this case, main’s body consists of
only a single statement, the printf.
When we define a function, we specify what should happen when a function is
executed. To actually execute the statements within a function, we have to call the
function. That is, to cause the printf statement to execute, we need to call the main
function that contains it. Fortunately, we don’t have to do anything special to call main.
When a C program starts up, the first thing it does is call main, so every program must
have a main.
The printf Statement
Now, we’ve arrived at the heart of our program: the printf that does all the work.
printf("Welcome to the Joy of C!\n");

It turns out that printf is itself a function, and that this statement is calling printf.
In particular, printf is a predefined output function. Predefined means that it has
been written and compiled for you and is linked together with your program after it
compiles. C does all input and output through a set of predefined functions that together
compose the standard input/output (I/O) library.
We call a function by following its name with a list of parameters, which we enclose
in parentheses. Parameters provide a function with information it needs to do its job.
In this case, printf needs to know which characters to write onto the output. We tell
printf what to write by providing it with a single string parameter (a list of characters
between double quotation marks), and it writes those characters to the standard output.
The standard output is usually the terminal (or computer monitor or window) from which
you invoked the program.2
There are a couple of details we’ve ignored. One is the semicolon following our
printf. In C, whenever a statement consists solely of a call to function, as does our
printf, we need to end it with a single semicolon. The other is the \n at the end of
2 Many operating systems actually let us change where the standard output goes, a process called output
redirection. To do so, however, we are required to do something special before we run the program. We’ll
look at this topic in more detail in later chapters.

6

GETTING STARTED WITH C

Library Routines

Text
Editor

Source
File

welcome.c

Compiler

Object
Module

Linker

welcome.o
Runnable
Program

welcome
Figure 1.2 The process of constructing, compiling, and executing a C program.

the formatting string. The backslash indicates a special character. \n is the newline
character; writing a \n causes further output to start on the next line. Without it, output
continues on the same line. In our example, we write the newline so that when our
program finishes, the cursor is sitting on the line following our welcome message.

1.3

COMPILING AND RUNNING C PROGRAMS
The previous section presented the source code for a single C program. But how do
we actually arrive at an executable program, one that when run, produces our earlier
output? We have to go through several steps, shown in Figure 1.2:
1. Enter the program into a source file, usually with an interactive text editor.
2. Provide this program to the compiler, which takes it and produces an object
module.
3. Give this object module to the linker, which produces an executable (or runnable)
program.
The object module contains compiled code, along with references to any functions,
such as printf, that the code uses but doesn’t define. These references are called
externals. Before a program can be executed, the compiled versions of these external
functions must be linked together with the object module. That’s the job of the linker.
It looks for definitions of these externals in a standard location that contains a library
of precompiled standard functions, and links them together with the object module to
produce a runnable program.

1.3

COMPILING AND RUNNING C PROGRAMS

7

Box 1.1: The Details Of Compiling C Programs
Although the process of turning C source into executable code sounds simple enough,
the details vary widely from system to system. But despite these differences, all C programming environments fall into two general categories: command-line and integrated.
Traditional C development environments are command-line oriented: they force us
to use separate commands to edit, compile, link, and run our programs. Often, however,
there’s a single command that combines compiling and linking. The workstations we
use, for example, provide the popular (and free!) GNU C compiler (gcc), which lets us
use
gcc -ansi welcome.c -o welcome

to form an executable from the program in Figure 1.1.
This command looks complex. In reality, however, it’s quite straightforward. The
-ansi tells the GNU compiler to compile welcome.c with ANSI-standard C (as opposed
to pre-ANSI C, and without any GNU-specific extensions). The -o welcome tells it to
put the resulting executable program in a file named welcome (as opposed to following
the UNIX tradition and creating an executable named a.out).
These command-line compilers are easy to learn how to use, provide fast compilation, and let us use our favorite editor to enter our programs. But they have several
major drawbacks: incremental program development is time-consuming, and correcting
errors is a potentially painful process. Before we can compile our program, we usually
have to save our file and leave the editor. If our program contains errors, the compiler
provides us with a list of error messages, which we need to record somewhere. To make
changes, we have to reenter the editor, reload our file, and work our way through it,
trying to find and correct all of our mistakes.
More modern C development environments, such as Turbo C++ under MS-Windows
or CodeCenter on UNIX, integrate the editor, compiler, and linker under a single easy-touse interface. They let us compile and execute our programs with a single keystroke—
without leaving the editor. But more importantly, we can also more easily correct our
errors. If the compiler detects any errors, it places us in the editor the location where
the first error occurred, with a message on the screen that describes our mistake. After
fixing this error, a single keystroke takes us to the location of the next error, and another
keystroke to the error after that, and so on.
These integrated environments make learning C a much less painful process, and we
highly recommend them. And because these environments are usually menu-driven,
learning how to use them is extremely simple. In Borland’s Turbo C++ for windows,
for example, we simply start the development environment with a click on the Turbo
C++ icon, enter the program, and choose the Run entry on the Debug Menu to compile,
link, and execute our programs. However, it’s important not to let this convenience lead
you into a “trial-and-error” method of programming, where you write or change code
without really understanding what’s going on in the hope that eventually point-and-click
will lead you to a working solution.

8

GETTING STARTED WITH C

/*
* A program to print a welcoming message.
*/
main()
{
printf("Welcome to the Joy of C!\n");
}
Figure 1.3 (welcome2.c) A version of our welcoming program with a comment describing what it does.

1.4

IMPROVING OUR INITIAL PROGRAM—COMMENTS
Figure 1.3 is an improved version of our initial program. The big difference is that now,
like most C programs, it starts with a comment that describes what it does.
/*
* A program that prints a welcoming message.
*/

A comment begins with a /* and ends with a */ and can go anywhere blank spaces
can occur—at the end of a line, at the beginning, or even in the middle. For readability,
however, we usually place comments only at the end of lines or on lines by themselves,
as we’ve done here. When we have comments that extend over multiple lines (like the
one above), we usually place a * at the beginning of each intermediate line. This isn’t
necessary, but we like doing so because it visually ties together all of the individual lines
making up the comment.
What does the compiler do with our comments? It simply ignores them. That’s
because comments are directed at the program’s reader, not the compiler. In general,
we use comments to answer questions that are likely to arise about the program, such
as what it does or how it works. Although at first comments may seem to be a luxury
rather than a necessity, they’re not. It can be difficult to understand another person’s
program unless they’ve been kind enough to comment it liberally. In fact, it can even
be difficult to understand your own programs after you’ve put them aside for awhile,
unless you were careful to sprinkle helpful comments throughout your code. Don’t be
afraid to shower a program with comments!

Start each program with a comment that describes what it does.

1.5 FURTHER IMPROVING OUR INITIAL PROGRAM

9

welcome.c:6: warning: return-type defaults to ‘int’
welcome.c: In function ‘main’:
welcome.c:7: warning: implicit declaration of function ‘printf’
welcome.c:8: warning: control reaches end of non-void function
Figure 1.4 Some compiler warnings that result from compiling our initial C program.

/*
* An improved version of our program to print a welcoming message.
*
* Revisions:
*
1) Added includes for function prototypes and EXIT_SUCCESS constant.
*
2) Added return value to main’s header.
*
3) Added return statement to main’s body.
*/
#include
#include
int main()
{
printf("Welcome to the Joy of C!\n");
return EXIT_SUCCESS;
}
Figure 1.5
message.

1.5

(welcome3.c) A further improved version of our initial program to print a welcoming

FURTHER IMPROVING OUR INITIAL PROGRAM
Despite our adding a comment, our initial C program actually has several sloppy coding
practices. Although the program executes and appears to work correctly, many compilers
will warn us about possible flaws and many experienced C programmers will shake their
heads sadly when they examine our code. Figure 1.4, for example, shows the warnings
we get when we compile it with the gcc compiler we described earlier.3
Figure 1.5 contains an improved version of our initial example that makes these
compiler warnings go away. What did we have to fix and how did we fix it?
3 Specifically, we compiled the program with the -Wall option on, which forces the compiler to warn us
about most potential programming problems it encounters. Many other compilers would check for these flaws
without the need for special options.

10

GETTING STARTED WITH C

Function Prototypes and Include Files
One problem is that we originally failed to provide a function prototype for printf.
Among other things, a function prototype describes the types of parameters the function
expects. printf’s prototype, for example, indicates that its first parameter must be a
string of characters.
Why do we need to provide this information? One reason is so that the compiler can
make sure we call the function with the correct parameters. If we accidentally provide
printf with a number as its first parameter, rather than a string, or if we simply forget
to provide that parameter, We want the compiler to point out the error.
Every C programming environment provides a collection of header files that contain prototypes for their predefined functions. The file stdio.h, for example, contains
prototypes for all of the input and output functions, including printf. To use these
prototypes, we need to include this file, which we do with the line:
#include

Lines beginning with a # are special. These lines are handled by the preprocessor,
a special part of the compiler that processes C programs before the “real” compiler sees
them. When we invoke the compiler on a source file, it automatically passes that source
file through the preprocessor, and then works with the result. The line above instructs
the preprocessor to include the contents of the file named stdio.h in the program it
passes to the compiler (the angle brackets around the name tell the preprocessor this is
a special system header file). The compiler sees only the contents of the included file
and not the #include itself. Including stdio.h provides the necessary prototype for
printf.

When you use a predefined function, be sure to include the appropriate
header file.

Return Values
The second problem is that we ignored main’s return value. When a function finishes
executing, it can return (or give back) a value to its caller. main is expected to return
a value indicating whether or not the program failed. But who is main’s caller? And
what value should main return?
main’s caller is whatever program invoked it, which is normally the operating
system command interpreter. Fortunately, most command interpreters ignore main’s
return value. But not all of them. Some print an error message based on this return
value; this means our sloppiness could lead to an error message being written when it
shouldn’t. It’s also possible that our C programs will be run from command scripts:
programs that are written in a special language and that use other programs as their
basic building blocks. These programs often test main’s return value to determine what
action to take next.
By convention, C programs are supposed to return EXIT SUCCESS when they
succeed and EXIT FAILURE when they fail. EXIT SUCCESS and EXIT FAILURE

1.6 A SECOND C PROGRAM

11

are special symbols defined in another header file, stdlib.h, so we need to include
this file as well. It turns out that EXIT SUCCESS is usually defined to be 0, while
EXIT FAILURE is defined as some other small, positive integer value, often 1.
We don’t expect our welcoming program to fail, so we would like main to always
return EXIT SUCCESS to its caller. We do so with the new statement
return EXIT_SUCCESS;

at the end of main, following the printf. The return statement terminates the
function containing it and returns the specified value to that function’s caller. Here, it
does what we want: terminates main and returns EXIT SUCCESS to its caller.
Always return a value from main indicating whether the program
succeeded or failed.
There’s one other detail we have to worry about here. Whenever a function returns
a value (like main above), we need to tell the compiler what type of value the function
returns. In this case, main is returning an integral value (as opposed to a real number
or a character), which we indicate by preceding main with int.
int main()

Don’t worry if at this point you find yourself a little bit overwhelmed with all these
details. The rest of the book spends plenty of time discussing types and return values.
For now, simply remember to include the appropriate header files, use the modified first
line of main, and add the statement returning EXIT SUCCESS. If you do all that, you’ll
be writing C programs that look just like the pro’s.

1.6

A SECOND C PROGRAM
Let’s take a look at a more realistic C program. Figure 1.6 computes the actual cost of a
set of items, given a list price per item, a percentage discount, and a sales tax rate. Here
is its output when we used it to compute the actual cost of buying 23 compact disks,
given that each CD is $13.95, we get an 18% discount for buying more than 20, and the
state sales tax is 7.5%:
List price per item: 13.950000
List price of 23 items: 320.850000
Price after 18.000000% discount: 263.097000
Sales tax at 7.500000%: 19.732275
Total cost: 282.829275

This program begins the same way our earlier programs did: with a comment
describing what it does and #includes for stdio.h and stdlib.h. But our main program
is not nearly as simple as before: it now includes variable declarations, assignment
statements, and a more complex form of printf.

12

GETTING STARTED WITH C

/*
* Compute the actual cost of buying 23 items at $13.95.
* 18% discount rate and a 7.5% sales tax.
*/
#include
#include
int main()
{
int
items;
double list_price;
double discount_rate;
double sales_tax_rate;
double total_price;
double discount_price;
double sales_tax;
double final_cost;

/*
/*
/*
/*
/*
/*
/*
/*

We assume an

# of items bought */
list price of item */
discount percentage */
sales tax percentage */
total price of all items */
discount price of all items */
amount of sales tax */
cost including sales tax */

items = 23;
list_price = 13.95;
discount_rate = .18;
sales_tax_rate = .075;
total_price = items * list_price;
discount_price = total_price - total_price * discount_rate;
sales_tax = discount_price * sales_tax_rate;
final_cost