5.12 Static External Variables Call-by-Reference The Relationship Between Arrays and Pointers Pointer Arithmetic and Element Size Arrays as Function Arguments An Example: Bubble Sort Dyn
Trang 2TT
ADDISON-WESLEY
Boston • San Francisco • New York· Toronto • jIy[ontreal
London • Munich • Paris • Madrid
Capetown • Sydney' Tokyo • Singapore • Mexico Cit:J1
Trang 3Many of the designations used by manufacturers and sellers to distinguish their products are claimed as
trademarks, Where those designatious appear in this book, and we were aware of a trademark claim, the
designations have been printed in initial capital letters or in all capitals
The author and publisher have taken care in the preparation of this book, but make no expressed or
implied warranty of any kind and assume no responsibility for errors or omissions No liability is
assumed for incidental or consequential damages in connection with or arising out of the use of the
information or programs contained herein
The publisher offers discounts on this book when ordered in quantity for special sales For more
informa-tion, please contact:
Pearson Education Corporate Sales Division
201 W 103rd Street
Indianapolis, IN 46290
(800) 428-5331
corpsales@pearsoned.com
Visit AW on the Web: www.awl.com/cseng/
Librmy of Congress Cataloging-in-Publication Data
All rights reserved No part of this publication may be reproduced, stored in a retrieval system, or
transmitted, in any form, or by any means, electronic, mechanical, photocopying, recording, or
other-wise, without the prior consent of the publisher Printed in the United States of America Published
Trang 41.3 Variables, Expressions, and Assignment
1.4 The Use of #defi ne and #i ncl ude
1.5 The Use of pri ntfO and scanfO
1.6 Flow of Control
1.7 Functions
Call-by-Value 1.8 Arrays, Strings, and Pointers
Arrays Strings Pointers 1.9 Files
Trang 5viii , Contents
1.10 Operating System Considerations
Writing and Running a C Program Interrupting a Program
Chapter 2
Typing an End-of-file Signal Redirection of the Input and the Output Summary
Exercises
lexical Elements, Operators, and the C System
2.1 Characters and lexical Elements
2.8 Operators and Punctuators
2.9 Precedence and Associativity of Operators
2.10 Increment and Decrement Operators
Exercises
The Fundamental Data Types
3.1 Declarations, Expressions, and Assignment
3.2 The Fundamental Data Types
3.3 Characters and the Data Type char
3.4 The Data Type i nt
3.5 The Integral Types short, long, and unsi gned
3.6 The Floating Types
3.7 The Use of typedef
3.8 The si zeof Operator
3.9 The Use of getcharO and putcharO
Trang 6x " Contents
5.8 Developing a Large Program
What Constitutes a Large Program?
5.12 Static External Variables
Call-by-Reference The Relationship Between Arrays and Pointers Pointer Arithmetic and Element Size
Arrays as Function Arguments
An Example: Bubble Sort Dynamic Memory Allocation With call oc 0 and mall oc 0 Offsetting the Pointer
An Example: Merge and Merge Sort Strings
String-Handling Functions in the Standard Library Multidimensional Arrays
Two-dimensional Arrays The Storage Mapping Function Formal Parameter Declarations Three-dimensional Arrays Initialization
The Use of typedef
Functions as Formal Parameters in Function Prototypes
6.17 An Example: Using Bisection to Find the Root of a Function
The Kepler Equation
6.18 Arrays of Pointers to Function
6.19 The Type Qualifiers const and vol at; 1 e
Summary Exercises
Chapter 7
Bitwise Operators and Enumeration Types
7.1 Bitwise Operators and Expressions
Bitwise Complement Two's Complement Bitwise Binary Logical Operators Left and Right Shift Operators
7.3 Software Tools: Printing an ; nt Bitwise
7.4 Packing and Unpacking
Multibyte Character Constants
7.5 Enumeration Types
7.6 An Example: The Game of Paper, Rock, Scissors
Summary Exercises
Chapter 8
The Preprocessor
8.1 The Use of #i ncl ude
8.2 The Use of #def; ne
8.3 8.4 8.5 8.6 8.7 8.8 8.9 8.10 8.11 8.12 8.13
Syntactic Sugar Macros with Arguments The Type Definitions and Macros in stddef.h
An Example: Sorting with qsortO
An Example: Macros with Arguments The Macros in stdio.h and ctype.h
Conditional Compilation The Predefined Macros The Operators # and ##
The assertO Macro The Use of #error and #pragma Line Numbers
Trang 7xii ., Contents
8.14 Corresponding Functions
8.1 5 An Example: Quicksort
Summary Exercises
Chapter 9
Structures and Unions
9.1 Structures
9.2 Accessing Members of a Structure
9.3 Operator Precedence and Associativity: A Final Look
9.4 Using Structures with Functions
9.5 Initialization of Structures
9.6 An Example: Playing Poker
9.8 Bit Fields
9.9 An Example: Accessing Bits and Bytes
9.10 The ADT Stack
Chapter 10
Summary Exercises
Structures and List Processing
10.1 Self-referential Structures
10.2 Linear Linked Lists
Storage Allocation 10.3 List Operations
10.4 Some List Processing Functions
Insertion Deletion 10.5 Stacks
10.6 An Example: Polish Notation and Stack Evaluation
10.7 Queues
10.8 Binary Trees
Binary Tree Traversal Creating Trees 10.9 General Linked Lists
Traversal The Use of callocO and Building Trees Summary
11.3 The Functions fpri ntfO, fscanfO, spri ntfO,
Chapter 12
Trang 813.6 Constructors and Destructors
13.7 Object-oriented Programming and Inheritance
Chapter 14
Moving from C to Java
14.1 Output
14.2 Variables and Types
14.3 Classes and Abstract Data Types
14.4 Overloading
14.5 Construction and Destruction of Class Types
14.6 Object-oriented Programming and Inheritance
14.7 Polymorphism and Overriding Methods
14.8 Applets
14.9 Java Exceptions
14.1 0 Benefits of Java and OOP
Summary Exercises
Appendix A
The Standard Library
A.1 Diagnostics: <assert h>
A.2 Character Handling: <ctype h>
Testing a Character Mapping a Character A.3 Errors: <errno.h>
A.4 Floating Limits: <float h>
A.S Integral Limits: <limits.h>
A.6 Localization: <locale.h>
653 A.12 Input/Output: <stdi o h>
655 Opening, Closing, and ~ondltl?nlng a File
656 Accessing the File Position Indicator
670
670 A.14 Memory and String Handling: <stn ng h>
Trang 97
B.6
B.7 B.8
Constant String literal Preprocessor
e.8 Array Pointers
e.9 Structures and Unions
Where appropriate, we discuss the differences between traditional C and ANSI e (Traditional C still remains in wide use.) Dozens of example programs are available to illustrate each important language feature, and many tables summarize key informa-tion and provide easy access for later reference Each chapter ends with a summary and exercises The summary reviews key elements presented in the chapter, and the exer-cises augment and extend the text
This book assumes a general-purpose knowledge of the C language It is intended for use in either a first or second programming course However, it can be readily used in conjunction with courses on topics such as comparative programming languages, com-putationallinguistics, data structures, database systems, fractal geometry, graphicS, numerical analysis, operating systems, programming methodology, and scientific appli-cations C is suitable for applications from each of these domains, and all features of C needed to code such applications are explained This book is appropriate for a data structures course because advanced data structuring features such as enumeration types, unions, self-referential structures, and ragged arrays are discussed For operat-ing systems courses concerned with UNIX or Windows 95/NT, the book explores the file structure and systems routines that enable the C programmer to add to existing sys-tems libraries and understand the C code underlying the operating system For applica-tions programming and scientific programming, there is discussion of how to write sample function libraries Statistics, root finding, sorting, text manipulation, file han-dling, and game playing are all represented with working code
Trang 10xviii l' Preface
New Java Section In Chapter 14, "Moving from C to Java," we discuss how the C
pro-grammer can very naturally and easily begin programming in Java, a language of
inter-est for work on the Internet The Java programming language borrows ideas from both
C and c++ and is designed to run in a machine- and system-independent manner This
makes it suitable for Internet work, such as writing applets for Web pages that get used
by browsers Because Java is an extension of C and C++, it is readily learned by the C
programmer
Complete ANSI C Language Computer profesSionals will have access to a complete
treatment of the language, including enumeration types, list processing, and the
operat-ing system interface Chapter 1, "An Overview of C," presents an overview of the
lan-guage After reading this chapter, the professional will already be able to write C code
Since the chapters are self-contained, the knowledgeable reader can skip to particular
sections as needed Chapter 11, "Input/Output and the Operating System," gives a
thor-ough introduction to the connections to the operating system This information will
benefit the professional systems programmer needing to use C to work 'vi thin an
MS-DOS or UNIX environment
Interactive Environment This book is written entirely with the modern interactive
environment in mind Experimentation is encouraged throughout Keyboard and screen
input/output is taken as the norm, and its attendant concerns are explained Thus, the
book is appropriate for users of small home and business computers as well as to users
of large interactive systems We assume that the reader will have access to an
interac-tive ANSI C system During the writing of this book, we used a number of different C
systems: various Borland and Microsoft compilers running on IBM-compatible Pentium
machines, the GNU gee compiler and native compilers running on various workstations
from DEC, SGI, and Sun, and the C compiler that runs on the Cray supercomputer in San
Diego
Working Code Our approach to describing the language is to use examples,
explana-tion, and syntax Working code is employed throughout Small but useful examples are
provided to describe important technical points Small because small is
comprehensi-ble Useful because programming is based on a hierarchy of building blocks and
ulti-mately is pragmatic The programs and functions deSCribed in the book can be used in
actual systems The authors' philosophy is that one should experiment and enjoy
Dissections We use highlighted "dissections" on many programs and functions
throughout the book Dissection is a unique pedagogical tool first developed by the
authors in 1984 to illUminate key features of working code A dissection is similar to a
structured walk-through of the code Its jntention is to explain to the reader newly
encountered programming elements and idioms found in working code
'f Preface xix
b k is constructed to be very flexible in its use Chapte: I,
Flexible Orgamzatl~~ :his 00 rts The first part explains the crucial programmmg
"An Overview of C, Is:n two ~a " / t ut material that must be understood by techniques needed for mteractIve I~~~~ ~~ s~rv~y the entire language and will be com-alL The second part ?f Chapter 1 goe f 'liar with comparable features from other prehensible to expenenced programmers amJ
d , a first programming course Caution:
s This second part can be postpone 111
language ld ost one the second part of Chapter 1
Beginning programmers shou p p d the C S stem" describes the lexical level Chapter 2, "Lexical Eleme~ts, ~perat~~~h :~e SeleCti~elY e~ployed to illustrate C lan-
of the language and sy.ntact!c ru es, ~decide to teach Backus-Naur-Form (BNF) notation guage constructs The mstructor ma\ 't 'thout any loss of continuity The book uses
as described in Chapter 2 ,or ,may onn 1 t v~e student can learn this standard form of BNF-style syntactic descnptl?n~ so :ha dd'tion language components are thoroughly programming language descnptIOn n a I, '
described by example and ordinary explanatIOn
d si ned to be a valuable reference to the C language
Reference Work ThIS book IS e ~oncisell illustrate key areas of the language The Throughout the book, many tables 1 wit~ its associated header files, is described in complete AN.S1 C s,;anda~d h~ar~, ti~~:ry." Sections in the appendix are devoted to the AppendIX A, The Stan ar eader files such as etype.h, stdio.h, and string.h Where explaining each of the stand~~d ~ to illustrate the use of a particular construct or appropriate, example code IS gIven
function :l~" B "L nguage Syntax we proVl " ' d e the complete syntax of the C language
In AppenLUll , C "ANSI C Compare to ra a 'd T d't' 1 IOna I C " we list the major dIfferences , d
~t~~~~N~I C and traditional C Finally, special care has been taken to make the m ex easy to use and suitable for a reference work
h e r s 3 through 10 cover the C language feature
The Complete ANSI C Lan9ua~e C a~~Scussed that may be omitted on first reading
by feature Many advanced ~oPI7 ar~ d For example enumeration types are without loss of comprehensIOn, I hSO, esrre be omI'tted' in a first course Machine-
tively new to t e angua, d l' atures such as word SIze consl era 'd tions and floating-point representatIOn depen ehnt e d but many of the details need not concern the beginner
are emp aSIze ,
" Processor" is devoted entirely to the
preproces-The Preprocessor Chapter 8, The rep d t 't'on of the C language Macros can be
, d t nd the power an no a 1
sor, WhIch IS use to ex e l f a function call Their use can reduce used to generat~ inli~e code that takes t~:s~n~~eaOdetailed discussion of the preproces-program executIOn tlme The chap~er ~ ANSI committee In traditional C, the prepro-sor, including ne",: features added y e iler to another In ANSI C, the functionality of cessor varies conSIderably from one comp ,
the preprocessor has been completely speCIfIed
Trang 11t
Recursion and List Processing Chapter S, "Functions," has a careful discuSSion of
recursion, which is often a mystifying topic for the beginner The Use of recursion is illustrated again in Chapter 8, "The Preprocessor," With the quicksort algOrithm and in Chapter 10, "Structures and List ProCessing," With basic list prOceSSing techniques A thorough knowledge of list processing techniques is necessary in advanced program
ming and data structure courses
Operating System Connection Chapter II, "Input/Ou tpu t and the Opera ting Sys tern,"
makes the operating system conneCtion In this chapter, we explain how to do file pro
cessing and discuss at length the various input/output functions in the standard
library We also explain how to execute a system command from Within a C program
and how to set file permissions and USe of environment variables We give explicit
examples shoWing the Use of the proftler, the librarian, and the make facility
Advanced ApPlications We discuss a number of advanced applications in Chapter 12,
"Advanced Applications." We present topics such as creating concurrent processes,
overlaying a process, interprocess communication, and Signals, along With Working
COde Also, We discuss the dYllamic allocation of vectors and matrices for eng;neers and
sdentists These advanced tOPles can be used selectively according to the needs of the
audience They could form the basis for an excellent second course in programming
practlee lbis book can be used, too, as an aUXiliary text in adVanced cOlllPuter sdence
courses that employ C as their implementation language
TabIes, Summaries, and exercises Throughout Ihe book are many tables and lists that
SUCCinctly sununanze key ideas These tables aid and test language comprehension For
example, C is very rich in operators and allows almost any useful combination of Opel'
ator mix It is eSSential to understand order of evaluation and association of each of
these operators separately and in combination These points are llIustrated in tables
throughout the text As a reference tool, the tables and code ill'e easily lOoked up
The exerdses test elementary features of the lilllguage and discuss advanced and sys
tem'dependent features Mony exercisos are oriented to problem solVing, others test
the reader's SYlltactic or Semantic understanding of C Some exerdses include a tutorial
diSCUSSion that is tangential to the text but may be of special interest to certain readers
lbe exercises offer the instructor all leVels of question, so as to allow aSSignments
sUit-able to the audience
to Debra Dolsberry, who acted as I er to create PostSCrIpt ~lles
Our spedal thanks go I responsible for using FrameMa {kS also go to Robert FIeld, this book She was large Yn of this book Our speetal than
he
chief technical reviewer suitable for the typesettt i~ View California, who acted as t d su gestions extremely P
arcPlace Systems, d Moufntht~s boole' We found his expertise a~ns "gand the "Dining
f
or the first e h 1 10 f H' 01'" picture in Chapter , g" are due to John e
"T wer 0 an d List Processm , valuable T e o Chapter 10, "Structures an h nks go to him, too
losophers" Plctur~ ~l1fornia, Riverside Our speml t ~ 'th helpful suggestions: Mur Pillis, UruverSlty 0 k other people who prOVIded ~s WI hae! Beeson, San Jose State
We also want to th~:rsity of California, Santa Cruz, 1~;~dO State University, Ft ray Baumgarten, Urn C ]"f rnia' Randolph Bentson, Co B ie Hewlett-Packard Co.: University, San Jose: a '.,0 of California, Berkeley; JOhn.;w ofuY Budd, University of lins; Jim Bloom, Umve.'" Yil of California, Santa Bru:bara, 1Ul ta Cruz; Jim Chrislock, inc.; Skona Bnttam, umv~; ~yne, University of Cabforma, szan effDonnelly, UniversIty Arizona, Tucson; Nl::d Jniversity of California, Santa ie': G1ntenbein, University of Minderaft, inc.; AI Co I F 'tz AT&T Bell Laboratones, ' L onard Garrett, Temple
Col-of IllinOis, Urbana; DIC <: rG
lor-R
e:,s St~te University; Dar State University, Corva 1 , tos California; Clifford Layton, og II University of Califor-Kelley, Cabrillo COlleg~, ~ifO;nia, Santa Cruz; Ch~~e M~~o;~uider: Geoffrey Pullum: rell Long, Uruverstty 0 Pleszkun, University of Co ora 'Santa Cruz Operation, Inc., nia, Santa Cruz; Anmew ta Cruz; Peter Rosenerantz, The sit of California, Santa University of Caltf~ruaie~:;ackard Co., Inc.; Peter sco.~' ~:::::r uJversity of Califonna, Mike Schoonover, ~w f Washington, Seattle; Tl y ,
Santa Cruz; Matt Sta~~li;{C to thank our sponsoring I~d~or to thank John Fuller for
In addition, we wou d ncouragement; and we wou <:e enthusiasm, sup~ort, a~ e roduction of this book on C
his careful attentIOn to t e p
AI Kelley g~~~~ity of California, Santa Cruz
Trang 12Chapter 0
Starting from Zero
Zero is the natural starting point in the C programming language C counts from O C uses 0 to mean false and not 0 to mean true C array subscripts have 0 as a lower bound C strings use 0 as an end-of-string sentinel C pointers use 0 to designate a null value C external and static variables are initialized to 0 by default This book explains these ideas and initiates you into the pleasures of programming in C
C is a general-purpose programming language that was originally designed by Dennis Ritchie of Bell Laboratories and implemented there on a PDP-ll in 1972 It was first used as the systems language for the UNIX operating system Ken Thompson, the devel-oper of UNIX, had been using both an assembler and a language named B to produce initial versions of UNIX in 1970 C was invented to overcome the limitations of B
B was a programming language based on BCPL, a language developed by Martin ards in 1967 as a typeless systems programming language Its basic data type was the machine word, and it made heavy use of pointers and address arithmetic This is con-trary to the spirit of structured programming, which is characterized by the use of strongly typed languages, such as the ALGOL-like languages C evolved from Band BCPL, and it incorporated typing
Rich-By the early 1980s, the original C language had evolved into what is now known as
traditional C by adding the vo; d type, enumeration types, and some other
improve-ments In the late 1980s, the American National Standards Institute (ANSI) Committee
X3]11 created draft standards for what is known as ANSI C or standard C The tee added the vo; d i< type, function prototypes, a new function definition syntax, and more functionality for the preprocessor, and in general made the language definition more precise Today ANSI C is a mature, general-purpose language that is widely avail-able on many machines and in many operating systems It is one of the chief industrial programming languages of the world, and it is commonly found in colleges and univer-sities everywhere Also, ANSI C is the foundation for C++, a programming language that incorporates object-oriented constructs This book describes the ANSI version of the C language, along with some topics in C++ and Java
Trang 13commit-2 Chapter 0 'f Starting from Zero
0.1 Why C?
C is a small language And small is beautiful in programming C has fewer keywords
than Pascal, where they are known as reserved words, yet it is arguably the more
power-fullanguage C gets its power by carefully including the right control structures and
data types and allowing their uses to be nearly unrestricted where meaningfully used
The language is readily learned as a consequence of its functional minimality
Cis th: native language of UNIX, and UNIX is a major interactive operating system on
workstatIOns, servers, and mainframes Also, C is the standard development language
for personal computers Much of MS-DOS and OS/2 is written in C Many windowing
packa~es, d.atabase programs, graphics libraries, and other large-application packages
are wntten m C
C is portable Code written on one machine can be easily moved to another C
pro-VIdes the programmer with a standard library of functions that work the same on all
machmes Also, C has a built-in preprocessor that helps the programmer isolate any
system-dependent code
C is terse C has a very powerful set of operators, and some of these operators allow
t~e programmer to access the machine at the bit level The increment operator ++ has a
dIrect a~alo~ue in machine language on many machines, making this an efficient
opera-to: I~dlrectIOn and address arithmetic can be combined within expressions to
accom-plIsh m one statement or expression what would require many statements in another
!anguag~ For many programmers this is both elegant and efficient Software
productiv-:ty studIes show that programmers produce, on average, only a small amount of
work-mg cOd.e each day A language that is terse explicitly magnifies the underlying
productIVIty of the programmer
C is modular C supports one style of routine, the external function, for which
argu-ments are passed call-by-value The nesting of functions is not allowed A limited form
of priv~cy is provide.d by using the storage class static within files These features,
along WIth tools prOVIded by the operating system, readily support user-defined
librar-ies of functions and modular programming
C ~s the baSis for c++ and Java This means that many of the constructs and
method-ologIes that are routinely used by the C programmer are also used by the c++ and Java
programmer Thus, learning C can be considered a first step in learning c++ or Java
C .i~ efficien: on most machines Because certain constructs in the language are
expllCltly machine-dependent, C can be implemented in a manner that is natural with
respe~t to the machine's architecture Because a machine can do what comes naturally,
compiled C code can be very efficient Of course, the programmer must be aware of any
code that is machine-dependent
0.2 'f ANSI C Standard 3
C is not without criticism It has a complicated syntax It has no automatic array
",V'CHUA" checldng It makes multiple use of such symbols as 1, and == For example, a common programming error is to use the operator in place of the operator == Never-theless, C is an elegant language It places no straitjacket on the programmer's access
to the machine Its imperfections are easier to live with than a perfected restrictiveness
C is appealing because of its powerful operators and its unfettered nature A C grammer strives for functional modularity and effective minimalism A C programmer welcomes experimentation and interaction Indeed, experimentation and interaction are the hallmarks of this book
pro-0.2 ANSI C Standard
The acronym ANSI stands for "American National Standards Institute." This institute is involved in setting standards for many!dnds of systems, including programming lan-guages In particular, ANSI Committee X3Jl1 is responsible for setting the standard for the programming language C In the late 1980s, the committee created draft standards for what is known as ANSI C or standard C By 1990, the committee had finished its work, and the International Organization for Standardization (ISO) approved the stan-dard for ANSI C as well Thus, ANSI C, or ANSI/ISO C, is an internationally recognized standard
The standard specifies the form of programs written in C and establishes how these programs are to be interpreted The purpose of the standard is to promote portability, reliability, maintainability, and efficient execution of C language programs on a variety
of machines Almost all C compilers now follow the ANSI C standard
0.3 From C to C++
Today, C is widely available on PCs, workstations, and mainframes throughout the world At the same time, machines and operating systems continue to evolve To expand the C language or to restrain the use of its constructs in order to conform to a particular discipline is not in the spirit of C
Although the C language itself is not being expanded, it often serves as the kernel for more advanced or more specialized languages Concurrent C extends the language by
Trang 144 Chapter 0 ,
Starting from Zero
incorpOrating concurrency primi
Small talk style objects Oth f tlves Objective C extends the language b
ta!; of ~ifferent forms 'of pa~:l1~~:.Of C are used on supercomputers to ia~~oav~~~:~
ost Important is C++ an ob'
Because it is an exten" Ject-onented language alread'
ware projects C++ slO.n ~f C, it al10ws both C and C++ code t b m widespread use
from C to C++' ") IS readIly learned by the C programmer (50 Cehused on large
0.4
From C and C++ to Java
Java was designed for w
and portabl ark on the Internet It allows th
machine T~;~og~ams that can be downloaded from the ~~rogrammer to write secure
deSigned to rune~n p:~~a~ming language borrows ideas fr~~e~~~ ~un ~n your local
defined in terms of a virtuCalme-a~d system-independent manner Its:n C++ and is
~~~s~::I~~~~diverse Sys:~~~~~:~c~i:~:~ ~~a;~:~ is inhe~'e~tly ~~:~~~s a~~
fla-ava IS often used to write applets on
~~nd~~:, ~:~,:~e;e:~~~~hicaI ~se~ int::!~~~et~~~~::.tB~sC:~~: i~riowsers Typ~cal1y,
C to Java.") earne by the C programmer (5 Ch s an extensIOn of
ee apter 14, "MOving from
An Overview of C
This chapter gives an overview of the C programming language A series of programs is presented, and the elements of each program are carefully explained Experimentation and interaction are emphasized throughout the text In this chapter, we emphasize how
to use the basic input/output functions of C Note carefully that all our C code also serves as C++ code and that all the ideas we discuss hold for C++ as well as for C Of course, the C++ programmer has available a richer set of tools and techniques out of which programs can be constructed (See Chapter 13, "Moving from C to CH.")
Except for Section 1.8, "Arrays, Strings, and Pointers," on page 36, everyone should read all the material in this chapter Any reader who has had experience with arrays, pointers, and files in some other language can read all the sections of this chapter to get a more complete overview of C Others can come back to the material when they feel they are ready Everyone should read this chapter with the understanding that tech-nical details and further explanations will come in later chapters
1.1 Programming and Preparation
Resident on the machine is a collection of special programs called the operating system
Commonly available operating systems include MS-DOS, OS/2, and UNIX An operating system manages machine resources, provides software for the user, and acts as an interface between the user and the hardware Among the many software packages pro-vided by the operating system are the C compiler and various text editors The principal text editor on the UNIX system is called vi Some systems, such as Borland C++, inte-grate the text editor and the compiler We assume that the reader is able to use some text editor to create files containing C code Such files are called source files, and they
Trang 156 Chapter 1 T An Overview of C
are compiled on most UNIX systems with the cc command, which invokes the C
com-piler Because the cc command invokes the compiler, the name of the command is also
the name of the compiler Thus, C compiler and cc compiler are used interchangeably
Roughly speaking, a compiler translates source code to object code that is executable
On UND( systems, this compiled code is automatically created in a file named a.out On
MS-DOS systems, this compiled code is automatically created in a file with the same
na~e as the c file, but with the exe extension replacing the c extension At the end of
thIS cha.pter, i~ Section 1.10, "Operating System Considerations," on page 53, we
present m detaIl the steps necessary to edit, compile, and execute a program
1.2 Program Output
Programs must communicate to be useful Our first example is a program that prints
on the screen the phrase "from sea to shining c." The complete program is
Using a text editor, we type this into a file whose name ends in c The chOice of a file
name should be mnemonic Let us suppose the program has been written in the file
sea.c To compile the program, we give the command
cc sea.c
If there are no errors in the code, the executable file a.out is created by this command
Now the command
a.out
executes the program and prints on the screen
from sea to shining C
• Dissection of the sea Program
• #include <stdio.h>
A preprocessor is built into the C compiler When the command to compile a program
is given, the code is first preprocessed and then compiled Lines that begin with a # communicate with the preprocessor This #i ncl ude line causes the preprocessor to
include a copy of the header file stdio.h at this point in the code This header file is
pro-vided by the C system The angle brackets around <stdi o h> indicate that the file is to
be found in the usual place, which is system-dependent We have included this file
because it contains information about the pri ntfO function
• int main(void) This is the first line of the function definition for mai nO (We write parentheses after the name ma into remind the reader that main 0 is a function.) The two words i nt and vo; d are keywords, also called reserved words They have special meaning to the com-piler In Section 2.4, "Keywords," on page 77, we will see that there are 32 keywords in
C, including i nt and vo; d
• int main(void) {
Every program has a function named main O Program execution always starts with this function The top line should be read as "main 0 is a function that takes no arguments and returns an i nt value." Here, the keyword i nt tells the compiler that this function returns a value of type i nt The word i nt stands for integer, but the word integer itself
cannot be used The parentheses following ma; n indicate to the compiler that mai n is a function This idea is confusing at first because what you see following main is (vo; d) , but only the parentheses 0 constitute an operator telling the compiler that ma; n is a function The keyword voi d indicates to the compiler that this function takes no argu-ments When we write about functions such as main 0 and p ri ntf 0, we usually follow the name in print with parentheses This indicates to the reader that we are discussing
a function (Many programming books follow this practice.)
{ Braces surround the body ofet function definition They are also used to group state-ments together
Trang 168 Chapter 1 'f An Overview of C
III pri ntfO
The C system contains a standard library of functions that can be used in programs
This is a function from the library that prints on the screen We included the header file
sldio.h because it provides certain information to the compiler about the function
printfO (See exercise 14, on page 63.)
III "from sea to shining (\n"
A string constant in C is a series of characters surrounded by double quotes This string
is an argument to the function pri ntfO, and it controls what gets printed The two
characters \n at the end of the string (read backs lash n) represent a single character
called newline It is a nonprinting character It advances the cursor on the screen to the
beginning of the next line
III printf("from sea to shining (\n")
This is a call to the pri ntfO function In a program, the name of a function followed
by parentheses causes the function to be called, or invoked If appropriate, the
paren-theses may contain arguments Here, when the pri ntfO function is invoked, it prints
its argument, a string constant, on the screen
III printf("from sea to shining (\n");
This is a statement Many statements in C end vvith a semicolon
III return 0;
This is a retu rn statement It causes the value zero to be returned to the operating
sys-tem, which in turn may use the value in some way, but is not required to do so (See
Sec-tion 12.7, "Returning the Status," on page 579, for further discussion.) Our use of this
return statement keeps the compiler happy If we do not use it, the compiler will
com-plain (See exercise 4, on page 60.) One of the principal rnles of programming is "keep
your compiler happy."
We can rewrite our first program as follows:
Although it is different from the first version, it will produce the same o~tput Each
time pri ntfO is called, printing begins at the position w~ere the preVIOUS call, to
pri ntfO left off If we want to print our phrase on three hnes, we can use newlme characters
#include <stdio.h>
int mainCvoid) {
pri ntf(,'from sea\n");
Trang 1710 Chapter 1 " An Overview of C
Let us write one additional variation on this program, one that will box the phrase in a
rectangle of asterisks It will show how each character, including blanks and newline
characters, is Significant, and when it is executed, it will give some sense of the screen
p r i n t f ( II ,~ * 'i<'1"h~ 'i"hh~ 'I, i, '{doh"", * ,', j, '/d, * \ nil) ;
pri ntf(" i, to shi ni ng C >"\n") ;
p ri ntf (" "'***'~id'*i"hhh~"''''*i''~*1d''~j(\n'') ;
printf("\n\n\n\n\n\n\n\n\n\n");
return 0;
Variables, ExpreSSions, and Assignment
We will write a program to convert the distance of a marathon in miles and yards to
kilometers In English units, a marathon is defined to be 26 miles and 385 yards These
numbers are integers To convert miles to kilometers, we multiply by the conversion
factor 1.609, a real number In memory, computers represent integers differently from
reals To convert yards to miles, we divide by 1760.0, and, as we shall see, it is essential
to represent this number as a real rather than as an integer
Our conversion program will use variables capable of storing integer values and real
values, In C, aU variables must be declared, or named, at the beginning of the program
A variable name, also called an identifier, consists of a sequence of letters, digits, and
underscores, but may not start with a digit Identifiers should be chosen to reflect their
use in the program In this way, they serve as documentation, making the program
more readable
1.3 " Variables, Expressions, and Assignment
In file marathon.c
Of a marathon in kilometers *1 Ii' The di stance
key-This is a declaration DeclaratIOns ~n ::a~~r:~~ language It informs the compiler that word and is one of the variables followmg t~e f~ndamefnta ty?nt and are to take on integer values Thus, the
Trang 1812 Chapter 1 'V An Overview of C
These are assignment statements The equal sign is an assignment operator The two
numbers 26 and 385 are integer constants The value 26 is assigned to the variable
mi 1 es The value 385 is assigned to the variable yards
II kilometers 1.609 * (miles + yards / 1760.0);
This is an assignment statement The value of the expression on the right side of the
equal sign is assigned to the variable ki 1 ometers The operators ''<, +, and / stand for
multiplication, addition, and division, respectively Operations inside parentheses are
performed first Because division has higher precedence than addition, the value of the
subexpression
yards / 1760.0
is calculated first (See Appendix E, "Operator Precedence and Associativity.") That
value is added to the value of the variable mi 1 es to produce a value that is then
multi-plied by 1 609 This final value is then assigned to the variable ki lometers
II printf("\nA marathon is %f kilometers.\n\n", kilometers);
This is a statement that invokes, or calls, the pri ntfO function The function
pri ntfO can have a variable number of arguments The first argument is always a
string, called the control string The control string in this example is
"\nA marathon is %f kilometers.\n\n"
It is the first argument to the function pri ntfO Inside this string is the conversion
specification, or format, %f The formats in a control string, if any, are matched with
the remaining arguments in the pri ntfO function In this case, %f is matched '\vith the
argument kilometers Its effect is to print the value of the variable kilometers as a
floating-point number and insert it into the print stream where the format %f occurs
•
Certain words, called keywords are reserved and CalIDOt be used by the programmer
as names of variables For example, i nt, float, and double are keywords A table of
keywords appears in Section 2.4, "Keywords," on page 77 Other names are knowll to
the C system and normally would not be redefined by the programmer The name
pri ntf is an example Because pri ntf is the name of a function in the standard
library, it usually is not used as the name of a variable
1.4 'V The Use of #defi ne and #i ncl ude 13
~ decimal point in a number indicates that it is a floating-point constant rather than
an mteger constant Thus, the numbers 37 and 37.0 would be treated differently in a progran: Although there are three floating types-float, double, and long doub 1 e-and varIables can be declared to be of any of these types, floating constants are auto-matically of type dou b 1 e
Expressions typi~ally are f~und on the right side of assignment operators and as arguments to functlOns The SImplest expressions are just constants such as 385 d
1760.0, which were used in the previous program The name of a variable itself anb
~owever, IS a doubl.e dlv~ded by an lnt When the expression 7.0/2 is evaluated, the value of the expresslOn 2.1S automatically converted to a doubl e, causing 7.0/2 to have the value 3.5 In the prevlOus program, suppose that the statement
kilometers 1.609 * (miles + yards / 1760.0);
changed to
= 1.609 * (miles + yards / 1760);
lea~s to a progra~ bug Because the variable yards is of type i nt and has value the mteger expresslOn
s integer division, and the result is the i nt value O This is not what is wanted Use
"0 constant 1760.0, which is of type double, corrects the bug
The Use of #defi ne and #i ncl ude
C compi~er ~as a preprocessor built into it Lines that begin '\vith a # are called
pre-~eSSIYla dIrectIVes If the lines
LIIVJIT 100
PI 3.14159
Trang 1914 Chapter 1 V An Overview of C
occur in a file that is being compiled, the preprocessor first changes all occurrences of
the identifier LIMIT to 100 and all occurrences of the identifier PI to 3.14159, except
in quoted strings and in comments The identifiers LIMIT and PI are called symbolic
constants A #defi ne line can occur anywhere in a program It affects only the lines in
the file that come after it
Normally, all #defi ne lines are placed at the beginning of the file By convention, all
identifiers that are to be changed by the preprocessor are '\tv-ritten in capital letters The
contents of quoted strings are never changed by the preprocessor For example, in the
statement
pri ntf(" PI == %f\n ", PI);
only the second PI will be changed by the above #defi ne directives to the
preproces-sor The use of symbolic constants in a program make it more readable More
impor-tantly, if a constant has been defined symbolically by means of the #defi ne facility and
used throughout a program, it is easy to change it later, if necessary For example, in
physics the letter c is often used to designate the speed of light, which is apprOximately
299792.458 lan/sec If we write
#define C 299792.458 /* speed of light in km/sec */
and then use C throughout thousands of lines of code to represent symbolically the
constant 299792.458, it will be easy to change the code when a new phYSical
experi-ment produces a better value for the speed of light All the code is updated by simply
changing the constant in the #defi ne line
In a program, a line such as
#include "my_file.h"
is a preprocessing directive that causes a copy of the file my_file.h to be included at this
point in the file when compilation occurs A #i ncl ude line can occur anywhere in a file,
though it is typically at the head of the file The quotes surrounding the name of the file
are necessary An include file, also called a header file, can contain #defi ne lines and
other #i ncl ude lines By convention, the names of header files end in .h
The C system provides a number of standard header files Some examples are stdio.h,
string.h, and math.h These files contain the declarations of functions in the standard
library, macros, structure templates, and other programming elements that are
com-monly used As we have already seen, the preprocessing directive
#include <stdio.h>
causes a copy of the standard header file stdio.h to be included in the code when
compi-lation occurs In ANSI C, whenever the functions pri ntfO or scanfO are used, the
1.4 V The Use of #defi ne and #i ncl ude 1 5
standard header file stdio.h should be included This file contains the declarations, or
more specifically, the function prototypes, of these functions (See Section 1 7, tions," on page 29, for further discussion.)
"Func-The Santa Cruz campus of the University of California overlooks the Monterey Bay on the Pacific Ocean and some of the ocean just to the northwest of the bay We like to call this part of the ocean that is visible from the campus the "Pacific Sea." To illustrate how the #i nc 1 ude facility works, we will 'write a program that prints the area of the Pacific Sea in various units of measure First, we create a header file and put in the following lines:
SO-INCH ES_PER_SQ_FOOT ACRES_PER_SO-MILE
we write the function main 0 in a c file
/* Measuring the Pacific Sea */
#include "pacificsea.h"
int main(void)
{
2337 0.3861021585424458 (5280 ,~ 5280)
144
640
const int
acres, sq_miles, sq_feet, sq_inches;
printf("\nThe Pacific Sea covers an area");
printf(" of %d square kilometers.\n", pacificsea);
sq_miles == SO-MILES_PER_SO-KILOMETER * pacific_sea;
sq_feet SO-FEET_PER_SO-MILE * sq_miles;
sq_inches == SO-INCHES_PER_SO-FOOT * sq_feet;
acres = ACRES_PER_SO-MILE -{, sq_mi 1 es;
printf("In other units of measure this is:\n\n");
printf("%22.7e acres\n", acres);
printf("%22.7e square miles\n", sq_miles);
printf("%22.7e square feet\n", sq_feet);
printf("%22.7e square inches\n\n", sq_inches);
return 0;
Trang 2016 Chapter 1 T An Overview of C
Now our program is written in two files, a h file and a c file The output of this
pro-gram is
The Pacific Sea covers an area of 2337 square kilometers
In other units of measure this is:
5.7748528e+05 acres 9.0232074e+02 square miles 2.515525ge+10 square feet 3.6223572e+12 square inches The new programming ideas are described in the following dissection table
• Dissection of the pacific_sea Program
III #include "pacific_sea.h"
This #i ncl ude line is a preprocessing directive It causes a copy of the filepacificsea.h
to be included when the program is compiled Because this file contains the line
#include <stdio.h>
the preprocessor expands the line in turn and includes a copy of the standard header
file stdio.h in the code as well We have included stdio.h because we are using pri ntfO
Five symbolic constants are defined in paci(icsea.h
This #defi ne line is a preprocessing directive It causes the preprocessor to replace all
occurrences of the identifier AREA by 2337 in the rest of the file By convention, capital
letters are used for identifiers that will be changed by the preprocessor If at some
future time a new map is made and a new figure for the area of the Pacific Sea is
com-puted, only this line needs to be changed to update the program
The floating constant 0.3861021585424458 is a conversion factor The use of a
sym-bolic name for the constant makes the program more readable
1.4 T The Use of #defi ne and #i ncl ude 17
The preprocessor changes occurrences of the first sequence of characters into the ond If a reader of this program knows that there are 5280 feet in a mile, then that reader will quickly recognize that this line of code is correct Instead of (5280 ,', 5280), we could have vVTitten 27878400; because C compilers expand constant expres-sions during compilation, run-time efficiency is not lost Although the parentheses are not necessary, it is considered good programming practice to use them For technical reasons parentheses are often needed around symbolic expressions (See Section 8.3,
sec-"Macros with Arguments," on page 368.)
l1li canst int pacific_sea = AREA; /* in sq kilometers */
When compiled, the preprocessor first changes AREA to 2337 The compiler then prets this line as a declaration of the identifier paci fi c_sea The variable is declared
inter-as type i nt and initialized to the value 2337 The keyword canst is a type qualifier that has been newly introduced by ANSI C It means that the associated variable can be ini-tialized, but cannot thereafter have its value changed (See exercise 18, on page 65.) On some systems this means that the variable may be stored in ROM (read-only memory)
These variables are defined to be of type double In ANSI C, floating types are float, doub 1 e, and long doub 1 e; long double does not exist in traditional C Each of these types is used to store real values Typically a fl oa t vyill store 6 significant digits and a doub 1 e will store 15 significant digits Along double will store at least as many signif-icant digits as a daub 1 e (See Section 3.6, "The Floating Types," on page 119.)
III printf("%22.7e acres\n", acres);
This statement causes the line
5.7748528e+05 acres
to be printed The number is vvritten in scientific notation and is interpreted to mean
5.7748528 x 105 Numbers written this way are said to be written in an e-format The conversion specification %e causes the system to print a floating expression in an e-for-mat vvith default spacing A format of the form %m.ne, where m and n are positive inte-gers, causes the system to print a floating expression in an e-format in m spaces total, with n digits to the right of the decimal paint (See Section 11.1, "The Output Function pri ntfO," on page 493.)
•
Trang 2118 Chapter 1." An Overview of C
1.5 The Use of printf() and scanf()
The function pri ntfO is used for output In an analogous fashion, the function
seanfO is used for input (The fin pri ntf and seanf stands for formatted.)
Techni-cally, these functions are not part of the C language, but rather are part of the C system
They exist in a library and are available for use wherever a C system resides Although
the object code for functions in the library is supplied by the C system, it is the
respon-sibility of the programmer to declare the functions being used ANSI C has introduced a
new and improved kind of function declaration called a function prototype This is one
of the most important changes introduced into the language by ANSI C The function
prototypes of functions in the standard library are available in the standard header
files In particular, the function prototypes for pri ntfO and seanfO are in stdio.h
Thus, this header file should be included whenever the function pri ntfO or scanfO
is used (See Section 1.7, "Functions," on page 29.)
Both pri ntfO and seanfO are passed a list of arguments that can be thought of as
controLstrtng and other_arguments
where controLstring is a string and may contain conversion specifications, or formats
A conversion specification begins with a % character and ends vvith a conversion
charac-ter For example, in the format %d the letter d is the conversion characcharac-ter As we have
already seen, this format is used to print the value of an integer expression as a decimal
integer To print the letters on the screen, we could use the statement
printf(lfabe lf );
Another way to do this is with the statement
pri ntf("%slf I "abc");
The format %s causes the argument If abc If to be printed in the format of a string Yet
another way to do this is with the statement
printf("%c%c%e lf , 'a', 'b', 'e');
Single quotes are used to designate character constants Thus, 'a' is the character
con-stant corresponding to the lowercase letter a The format %e prints the value of an
expression as a character Notice that a constant by itself is considered an expression
Conversion character
1.5 " The Use of pri ntfO and seanfO
printfO conversion characters
How the corresponding argument is printed
other arguments are addresses ConSider, for example, the statement
scanf("%d", &x);
The format %d is matched with the expression &x, causing seanfO to interpret ters in the input stream as a decimal integer and store the result at the address of x Read the expression &x as "the address of x" because & is the address operator
charac-When the keyboard is used to input values into a program, a sequence of characters
is typed, and it is this sequence of characters, called the input stream, that is received
by the program If 1337 is typed, the person typing it may think of it as a decimal ger, but the program receives it as a sequence of characters The scanfO function can
inte-be used to convert a string of decimal digits into an integer value and to store the value
at an appropriate place in memory
Trang 2220 Chapter 1 " An Overview of C
The functio~l scanfO returns an int value that is the number of successful
conver-SlO~s accomphshe~ or the system defined end-of-value The function pri ntfO returns
an 1 nt value that IS the number of characters printed or a negative value in case of an
error
scanfO conversion Conversion
character How characters in the input stream are converted
d decimal integer
f floating-point number (float)
If or LF floating-point number (double)
~he d.etails ~oncer~~g pri ntfO and scanfO are found in Section 11.1, "The Output
;unctlOn p rl ntf 0, _ on page 493, and in Section 11.2, "The Input Function scanfO,"
n page 499 Here, we only want to present enough information to get data into and out
of the mach"
me m a mImmally acceptable way The following program reads in three
chharacters and some numbers and then prints them out Notice that variables of type
c ar are used to store character values
pri~tf(':\n%s\n%s", "Input three characters, II
an lnt, a float and a double' ")
sC~nf(II:c%c%c%d~f%lf", &c1, &c2, &c3, &ti, &x, &y);
pr:ntf(II\nHere 1S the data that you typed in:\n");
Input three characters,
an int, a float, and a double: ABC 3 55 77.7 Here is the data that you typed in:
When reading in numbers, scanfO will skip white space (blanks, newlines, and tabs), but when reading in a character, white space is not skipped Thus, the program will not run correctly with the input AB C 3 55 77 l The third character read is a blank, which is a perfectly good character; but then scanfO attempts to read C as a decimal integer, which causes difficulties
1.6 Flow of Control
Statements in a program are normally executed in sequence However, most programs require alteration of the normal sequential flow of control The if and i f-e 1 se state-ments provide alternative actions, and the whi 1 e and for statements provide looping mechanisms These constructs typically require the evaluation of logical expressions, expressions that the programmer thinks of as being either true or false In C, any non-zero value is considered to represent true, and any zero value is considered to repre-sent false
The general form of an if statement is
i f (expr) statement
If expr is nonzero (true), then statement is executed; otherwise, it is skipped It is tant to recognize that an if statement, even though it contains a statement part, is itself a single statement Consider as an example the code
Trang 2322 Chapter 1 T An Overview of C
passes to the pri ntfO statement, causing 5 to be printed If, however, the value of b is
not 3, then the statement
a = 5;
is skipped and control passes directly to the pri ntfO statement, causing 1 to be
printed In C, logical expressions have either the i nt value 1 or the i nt value O
Con-sider the logical expression
b == 3
This expression has the i nt value 1 (true) if b has the value 3; otherwise, it has the i nt
value 0 (f'alse)
A group of statements surrounded by braces constitutes a compound statement
Syn-tactically, a compound statement is itSelf a statement; a compound statement can be
used anywhere that a statement can be used The next example uses a compound
state-ment in place of a simple statestate-ment to control more than one action:
if Ca == 3) {
b 5;
e = 7;
}
Here, if a has value 3, then two aSSignment statements are executed; if a does not have
value 3, then the two statements are skipped
An i f-e 1 se statement is of the form
if Cexpr)
statement]
else
statement2
It is important to recognize that the whole construct, even though it contains
state-ments, is itself a single statement If expr is nonzero (true), then statement] is executed;
otherwise statement2 is executed As an example, consider the code
Trang 24variable op= expr
where op is an operator such as +, -, 1<, or / is equivalent to
variable variable op (expr)
This is the value printed by the pri ntfO statement
The general form of a whi 1 e statement is
whil e (expr) statement
1.6 'f Flow of Control 25
where statement is either a simple statement or a compound statement When the whi 1 e statement is executed, expr is evaluated If it is nonzero (true), then statement is executed and control passes back to the beginning of the whi 1 e loop This process con-tinues until expr has value 0 (false) At this paint, control passes on to the next state-ment In C, a logical expression such as i <= 5 has i nt value 1 (true) if i is less than or equal to 5, and has i nt value 0 (false) otherwise
Another looping construct is the for statement (See Section 4.9, "The for ment," on page 167, for a more complete discussion.) It has the form
State-for (exprl; expr2; expr3) statement
If all three expressions are present, then this is equivalent to
exprl;
whi 1 e (expr2) { statement expr3;
}
Typically, exprl performs an initial assignment, expr2 performs a test, and expr3 ments a stored value Note that expr3 is the last thing done in the body of the loop The for loop is repeatedly executed as long as expr2 is nonzero (true) For example,
incre-for (i = 1; i <= 5; ++i)
sum += i;
This for loop is equivalent to the whi 1 e loop used in the last program
Our next program illustrates the use of an i f-e 1 se statement within a fo r loop Numbers are read in one after another On each line of the output we print the count and the number, along with the minimum, maximum, sum, and average of all the num-bers seen up to that point (See exercise 16, on page 65, through exercise 18, on page
65, for further discussion concerning the computation of the average.)
Trang 251, x, min, max, sum, avg);
for (i = 2; scanf("%lf", &x)
This program has been designed to read numbers from a file We can type them in from
the keyboard, but if we do this, then what appears on the screen will not be formatted
correctly To test this program, we compile it and put the executable code in
running_sum Then we create a file called data and put the following numbers in it:
Now, when we give the command
running_sum < data
the t'ollovving appears on the screen:
Average
3.000 -1.000 1.667
27
causes the input to be redirected The program running_sum takes its input from the
standard input file, which is normally connected to the keyboard The operating tem, however, has redirected the input to the file data In this context, the symbol < is
sys-thought of as a left pointing arrow (See Section 1.10, "Operating System ations," on page 53, for further discussion.)
Consider-• Dissection of the running_sum Program
III i f (scanf("%lf", &x) 1 1) {
printf("No data found byel\ntl);
exit(1);
}
Recall that scanf 0 returns as an i nt the number of successful conversions formed If scanfO is unable to make a conversion, then we print a message and exit the program The function exi to is in the standard library, and its function prototype
per-is in stdlib.h When ex itO is invoked, certain housekeeping tasks are performed and
the program is terminated This function takes a single argument of type i nt that, by convention, is zero if the programmer considers the exit to be normal, and is nonzero otherwise
Trang 2628 Chapter 1 'f An Overview of C
III printfCI%5d%9.lf%9.lf%9.lf%12.3f%12.3f\n",
1, x, min, max, sum, avg);
After the headings, this is the first line to be printed Notice that the field widths here match the field widths in the previous pri ntfO statement
III for Ci = 2; scanfCI%lf", &x) == 1; ++i) { The variable i is initially assigned the value 2 Then a test is made to see if the logical expression
scanfCI%lf", &x) == 1
is true If scanfO can read characters from the standard input stream, interpret them
as a doub 1 e (read 1 f as "long float"), and place the value at the address of x, then a cessful conversion has been made This causes scanfO to return the i nt value 1, which in turn makes the logical expression true As long as scanfO can continue to read characters and convert them, the body of the fo r loop will be executed repeatedly
suc-The variable i is incremented at the end of the body of the loop
III if Cx < min)
min = x;
else if Cx > max) max = x;
This construct is a single i f-e 1 se statement Notice that the statement part following the else is itself an if statement Each time through the loop this i f-e 1 se statement causes the values for mi n and max to be updated, if necessary
Functions should be declared before they are used Suppose, for example, that we want to use the function powO, called the power function, one of many functions in the mathematics library available for use by the programmer A function call such as powCx, y) returns the value of x raised to the y power To give an explicit example, powC2 0, 3.0) yields the value 8.0 The declaration of the function is given by
double powCdouble x, double y);
Function declarations of this type are called function prototypes An equivalent function prototype is given by
double powCdouble, double);
Identifiers such as x and y that occur in parameter type lists in function prototypes are not used by the compiler Their purpose is to provide documentation to the program-mer and other readers of the code
A function prototype tells the compiler the number and type of arguments to be passed to the function and the type of the value that is to be returned by the function ANSI C has added the concept of function prototype to the C language This is an important change In traditional C, the function declaration of powO is given by
Parameter type lists are not allowed ANSI C compilers will still accept this style, but function prototypes, because they greatly reduce the chance for errors, are much pre-ferred (See exercise 5, on page 236, in Chapter 5, "Functions.")
A function prototype has the following general form:
type function_nameCparameter type list) ;
Trang 27no arguments Also, the keyword voi d is used if no value is returned by the function If
a function takes a variable number of arguments, then ellipses are used For ple, the function prototype
exam-i nt pri ntfCconst char ~'format, );
can be found in stdio.h (See exercise 14, on page 63.) This information allows the piler to enforce type compatibility Arguments are converted to these types as if they were follOwing rules of assignment
com-To illustrate the use of functions, we set for ourselves the following task:
Creating maxmin Program
1 Print information about the program (this list)
2 Read an integer value for n
3 Read in n real numbers
4 Find minimum and maximum values
Let us write a program called maxmin that accomplishes the task It consists of three functions written in the file maxmin.c
In file maxmin.c
#include <stdio.h>
float float void
maximumCfloat x, float y);
minimumCfloat x, float y);
prn_infoCvoid);
int mainCvoid)
{
i nt float max, min, x; i, n;
max = maximumCmax, x);
min = minimumCmin, x);
}
printfC"\n%s%l1.3f\n%s%11.3f\n\n",
"Maximum value:", max,
"Minimum value:", min);
float minimumCfloat x, float y) {
}
i f Cx < y)
return x;
else return y;
"This program reads an integer value for n, and then",
"processes n real numbers to find max and min values.");
To test the program, we give the command
maxmin
Suppose, when prompted, we type in 5 followed by the line
737.7799 -11.2e+3 -777 0.001 3.14159
31
Trang 2832 Chapter 1 An Overview of C
Here is what appears on the screen:
•
This program reads an integer value for n, and then
processes n real numbers to find max and min values
maximum(float x, float y);
minimum(float x, float y);
prn_info(void);
i nt mai n (voi d)
{
The function prototypes for the functions maxi mumO, mi ni mumO, and prn_ i nfoO
occur at the top of the file after any #i ncl ude lines and #defi ne lines The first two
function prototypes tell the compiler that the functions maxi mum 0 and mi ni mum 0
ea::h take t,wo arguments of type float and each return a value of type float The
thlrd functIOn prototype tells the compiler that prn_ i nfoO takes no arguments and
returns no value Note that for the first two function prototypes we could just as well
have written
float
float maximum(float, float)· ,
mlnlmum(float, float);
The co:upiler does not make any use of parameters such as x and y in function
proto-types rhe parameters serve only as documentation for the reader of the code
• int main(void) {
i nt float
• printf("\nInput %d real numbers: ", n);
scanf("%f", &x);
max = min = x;
The user is asked to input n real numbers The first real number is read and its value
is placed at the address of x Because the assignment operator associates from right to left
max min = x; is equivalent to max = (mi n = x);
Thus, the value x is assigned first to mi n and then to max (See Section 2.9, "Precedence and Associativity of Operators," on page 83.)
Trang 2934 Chapter 1 'Y An Overview of C
This means that a copy of the value of each argument is made, and it is these copies
that are processed by the function The effect is that variables passed as arguments to
functions are not changed in the calling environment
float maximum(float x, float y)
This is the function definition for the function maxi mum O It specifies explicitly how
the function will act when it is called, or invoked A function definition consists of a
header and a body The header is the code that occurs before the first left brace { The
body consists of the declarations and statements between the braces { and} For this
function definition the header is the line
float maximum(float x, float y)
The first keyword float in the header tells the compiler that this function is to return a
value of type float The parameter list consists of the comma-separated list of
identi-fier declarations within the parentheses e and) that occur in the header to the function
definition Here, the parameter list is given by
float x, float y
The identifiers x and yare formal parameters Although we have used the identifiers x
and y both here and in the function ma in 0, there is no need to do so There is no
rela-tionship, other than a mnemonic one, between the x and y used in maxi mum 0 and the x
and y used in ma in O Parameters in a function definition can be thought of as
place-holders When expressions are passed as arguments to a function, the values of the
expressions are associated with these parameters The values are then manipulated
according to the code in the body of the function definition Here, the body of the
func-tion definifunc-tion consists of a single i f-el se statement The effect of this statement is to
return the larger of the two values x and y that are passed in as arguments
return x;
This is a retu rn statement The general form of a retu rn statement is
return; or retu rn expr;
1.7'Y Functions 35
A retu rn statement causes control to be passed back to the calling environment If an expression follows the keyword return, then the value of the expression is passed back as well
float minimumefloat x, float y) {
}
if ex < y)
return x;
else return y;
The function definition for mi n i mum 0 comes next Note that the header to the function definition matches the function prototype that occurs at the top of the file This is a common programming style
void prn_infoevoid) {
This is the function definition for prn_ i nfoO The first voi d tells the compiler that this function returns no value, the second that this function takes no arguments
Call-by-Value
In C, arguments to functions are always passed by value This means that when an expression is passed as an argument to a function, the expression is evaluated, and it is this value that is passed to the function The variables passed as arguments to func-
tions are not changed in the calling environment Here is a program that illustrates this:
Trang 30When a is passed as an argument, the expression a is evaluated to produce a value that
we can think of as a copy of a It is this copy, rather than a itself, that is passed to the
function Hence, in the calling environment the variable a does not get changed
Tbis argument-passing convention is known as call-by-value To change the value of a
variable in the calling environment, other languages provide call-by-reference In C, to
get the effect of call-by-reference, pointers must be used (See Section 6.3,
"Call-by-Ref-erence," on page 252.)
1.8 Arrays, Strings, and Pointers
In C, a string is an array of characters, and an array name by itself is a pointer Because
of tbis, the concepts of arrays, strings, and pointers are intimately related A pointer is
just an address of an object in memory C, unlike most languages, provides for pointer
arithmetic Because pointer expressions of great utility are possible, pointer arithmetic
is one of the strong points of the language
1.8 Arrays, Strings, and Pointers 37
In file scores.c
#include <stdio.h>
#define CLASS_SIZE 5 int main(void)
{
}
int i, j, score[CLASS_SIZEJ sum = 0, tmp;
pri ntf("Input %d scores: ", CLASS_SIZE);
for (i = 0; i < CLASS_SIZE; ++i) { scanf("%d", &score[i]);
sum += scorer;];
} for (i 0; i < CLASS_SIZE - 1; ++i) for (j = CLASS_SIZE - 1; j > i;
if (score[j-1J < score[jJ) { tmp = score[j-l];
score[j-1] = score[jJ;
score[j] = tmp;
} pr;ntf("\nOrdered scores:\n\n");
for (; = 0; i < CLASS_SIZE; ++i)
/* bubble sort */ )
/* check the order */
pr;ntf(" score[%d] =%5d\n", i, score[i]);
printf("\n%18d%s\n%18.lf%s\n\n", sum, II ;5 the sum of all the scores", (double) sum / CLASS_SIZE, " ;5 the class average");
return 0;
If we execute the program and enter the scores 63, 88, 97, 53, 77 when prompted, we will see on the screen
Trang 31is the sum of all the scores
is the class average
A bubble sort is used in the program to sort the scores This construction is typically
done with nested for loops, with a test being made in the body of the inner loop to
check on the order of a pair of elements If the elements being compared are out of
order, their values are interchanged Here, this interchange is accomplished by the code
tmp = score[j-lJ;
score[j-lJ = score[jJ;
score[j] =: tmp;
In the first statement, the variable tmp is used to temporarily store the value of
score [j-l] In the next statement, the value of score [j-1J stored in memory is being
ovemTitten with the value of score [jJ In the last statement, the value of score [j] is
being overwritten with the original value of score [i], which is now in tmp Hand
simu-lation of the program with the given data will show the reader why this bubble sort
con-struct of two nested fa r loops achieves an array with sorted elements The name
bubble sort comes from the fact that at each step of the outer loop the desired value
among those left to be worked over is bubbled into position Although bubble sorts are
easy to code, they are relatively inefficient Other sorting techniques execute much
faster This is of no concern when sorting a small number of items infrequently, but if
the number of items is large or the code is used repeatedly, then efficiency is, indeed,
an important consideration The expression
(double) sum / CLASS_SIZE
which occurs as an argument in the final pri ntfO statement, uses a cast operator The
effect of (double) sum is to cast, or convert, the i nt value of sum to a doub 1 e Because
the precedence of a cast operator is higher than that of the division operator, the cast is
done before division occurs (See Section 2.9, "Precedence and Associativity of
Opera-tors," on page 83.) When a daub 1 e is divided by an i nt, we have what is called a mixed
expression Automatic conversion now takes place The i nt is promoted to a doub 1 e,
and the result to the operation is a doubl e If a cast had not been used, then integer
division would have occurred and any fractional part would have been discarded
More-over, the result would have been an i nt, which would have caused the format in the
pri ntfO statement to be in error
1.8 V Arrays, Strings, and Pointers 39
In C, ~ string is an arr~y of characters In this section, in addition to illustrating the use
of strmgs, we want to mtroduce the use of getcharO and putcharO These are ros defined in stdio.h Although there are technical differences, a macro is used in the same way a function is used (See Section 8.7, "The Macros in stdio.h and ctype.h," on page 382.) The macros getcharO and putcharO are used to read characters from the keyboard and to print characters on the screen, respectively
mac-Our next ~rogram ~tores a line typed in by the user in an array of characters (a string) and then prmts the lme backwards on the screen The program illustrates how charac-ters in C can be treated as small integers
char c, name[MAXSTRING];
i, sum = 0;
int printf("\nHi! What is your name? ");
for (i = 0; (c = getchar()) != '\n'; ++i) {
if Ci sal pha(c)) sum += Cj
Your name spelled backwards is ");
for ( i; i >= 0; i) putchar(name[i])j printf("\n%s%d%s\n\n%s\n",
"and the letters in your name sum to ", sum,
"Have a nice day!");
return 0;
" tf ,
Trang 3240 Chapter 1 'f An Overview of C
If we run the program and enter the name Ali ce B Carole when prompted, the
fol-lowing appears on the screen:
Hi! What is your name? Alice B Carole
Nice to meet you Alice B Carole
Your name spelled backwards is eloraC .B ecilA
and the letters in your name sum to 1142
Have a nice day!
• • Dissection of the nice_day Program
• #include <ctype.h>
#include <stdio.h>
The standard header file stdio.h contains the function prototype for pri ntfO It also
contains the macro definitions for getcharO and putcharO, which will be used to
read characters from the keyboard and to write characters to the screen, respectively
The standard header file ctype.h contains the macro definition for i sal phaO, which
will be used to determine if a character is alphabetic-that is, if it is a lower- or
upper-case letter
The symbolic constant MAXSTRING will be used to set the size of the character array
name We are making the assumption that the user of this program will not type in more
than 99 characters Why 99 characters? Because the system will add the' \0' as one
extra guard character terminating the string
i nt
c, name[MAXSTRINGJ;
i, sum 0;
The variable c is of type char The identifier name is of type array of char, and its size
is MAXSTRING In C, all array subscripts start at O Thus, name [0J, name [1], ,
name [MAXSTRING - 1J are the elements of the array The variables i and sum are of
type i nt; sum is initialized to O
• printf("\nHi! What is your name? ");
This is a prompt to the user The program now expects a name to be typed in followed
by a carriage return
1.8 'f Arrays, Strings, and Pointers 41
• (c = getchar()) != '\n' ThiS expression consists of two parts On the left we have (c getchar 0)
Unlike other languages, assignment in C is an operator (See Section 2.11, "Assignment Operators," on page 87.) Here, getcharO is being used to read a character from the keyboard and to assign it to c The value of the expression as a whole is the value of whatever is assigned to c Parentheses are necessary because the order of precedence
of the operator is less than that of the ! = operator Thus,
c = getchar() != '\n' is equivalent to c = (getcharO != '\n') which is syntactically correct, but not what we want In Section 2.9, "Precedence and Associativity of Operators," on page 83, we discuss in detail the precedence and asso-ciativity of operators
• for (i = 0; (c = getchar()) != '\n'; ++i) {
name[iJ = c;
if (i sal pha(c)) sum += c;
} The variable i is initially assigned the value O Then getcha r 0 gets a character from the keyboard, assigns it to c, and tests to see if it is a newline character If it is not, the body of the for loop is executed First, the value of c is assigned to the array element name[iJ Next, the macro isalphaO is used to determine whether c is a lower- or uppercase letter If it is, sum is incremented by the value of c As we will see in Section 3.3, "Characters and the Data Type char," on page 111, a character in C has the integer value corresponding to its ASCII encoding For example, 'a' has value 97, 'b I has value
98, and so forth Finally, the variable i is incremented at the end of the for loop The for loop is executed repeatedly until a newline character is received
After the fa r loop is finished, the null character \0 is assigned to the element name [i ]
By convention, all strings end with a null character Functions that process strings, such
as pri ntfO, use the null character \0 as an end-of-string sentineL We now can think of the array name in memory as
Trang 3342 Chapter 1 T An Overview of C
o 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
III printf("\n%s%s%s\n%s" ,
"Nice to meet you ", name, ".",
"Your name spelled backwards is H);
99
Notice that the format %s is used to print the character array name The elements of the
array are printed one after another until the end-of-string sentinel \0 is encountered
III for ( i; i >= 0; i)
putchar(name[i]);
If we assume that Ali ce B Carole followed by a carriage return was typed in, then i
has value 15 at the beginning of this for loop (Do not forget to count from 0, not 1.)
After i has been decremented, the subscript corresponds to the last character of the
name that was typed in Thus, the effect of this fo r loop is to print the name on the
screen backwards
III printf("\n%s%d%s\n\n%s\n",
"and the letters in your name sum to ", sum, ".",
"Have a ni ce day! ") ;
We print the sum of the letters in the name typed in by the user, and then we print a
final message After the sum of the letters in the name is printed, a period is printed
Two newlines are used to create a blank line before the final message is printed Notice
that this pri ntfO style allows us to easily visualize what is to appear on the screen
•
Pointers
A pointer is an address of an object in memory Because an array name is itself a
pointer, the uses of arrays and pointers are intimately related The following program is
designed to illustrate some of these relationships:
1.8 T Arrays, Strings, and Pointers
by thE sEashorE
Dissection of the abc Program
III #include <string.h>
43
The standard library contains many string-handling functions (See Section 6.11,
"String-Handling Functions in the Standard library," on page 272.) The standard header file string.h contains the function prototypes for these functions In this program we
will use strcpy() to copy a string
Trang 3444 Chapter 1 V An Overview of C
II char c = 'a', *p, s[MAXSTRING];
The variable c is of type char It is initialized with the value 'a' The variable p is of
type pointer to char The string 5 has size MAXSTRING
II P = &c;
The symbol & is the address operator The value of the expression &c is the address in
memory of the variable c The address of c is assigned to p We now think of p as
II pr;ntf("%c%c%c ", ~tp, >'<p + 1, 1<p + 2);
The format %c is used to print the value of an expression as a character The symbol ~<
is the dereferencing, or indirection, operator The expression ~'p has the value of
what-ever p is pointing to Because p is pOinting to c and c has the value 'a', this is the value
of the expression ~'p and an a is printed The value of the expression >"p + 1 is one
more than the value of >"p, and this causes a b to be printed The value of the expression
"'p + 2 is two more than the value of *p, and this causes a c to be printed
II "ABC"
A string constant is stored in memory as an array of characters, the last of which is the
null character \0 Thus, the size of the string constant "ABC" is 4, not 3 Even the null
string If II contains one character, namely \0 It is important to realize that string
con-stants are of type array of char An array name by itself is treated as a pointer, and this
is true of string constants as well
III strcpy(s, "ABC");
The function strcpy() takes two arguments, both of type pointer to char, which we
can think of as strings The string pointed to by its second argument is copied into
memory beginning at the location pointed to by its first argument All characters up to
and including a null character are copied The effect is to copy one string into another
It is the responsibility of the programmer to ensure that the first argument points to
enough space to hold all the characters being copied After this statement has been
exe-cuted, we can think of s in memory as
1.8 V Arrays, Strings, and Pointers 45
II pri ntf("%s %c%c%s\n", 5, ''''5 + 6, ~'s + 7, 5 + 1);
The array name 5 by itself is a pointer We can think of 5 as pointing to 5 [0], or we can
think of 5 as being the base address of the array, which is the address of 5 [0] Printing
5 in the format of a string causes ABC to be printed The expression "'5 has the value of what 5 is pointing to, which is 5 [0] This is the character A Because six letters more than A is G and seven letters more than A is H, the expressions "'5 + 6 and "'5 + 7, printed in the format of a character, cause G and H to be printed, respective!y ~he
expression s + 1 is an example of pointer arithmetic The value of the exp~esslO.n IS a pointer that points to 5 [lJ, the next character in the array Thus,s + 1 pl'lnted III the format of a string causes BC to be printed
II strcpy(s, "she sells sea shells by the seashore");
This copies a new string into s Whatever was in 5 before gets overwritten
II P = s + 14;
The pointer value s + 14 is assigned to p An equivalent statement is
p &s[14J;
If you count carefully, you will see that p now points to the first letter in the word
"she 11 s." Note carefully that even though 5 is a pointer, it is not a pointer variable, but rather a pointer constant A statement such as
}
As long as the value of what p is pointing to is not equal to the null character, the body
of the fa r loop is executed If the value of what p is pointing to is equal to 'e' then
Trang 3546 Chapter 1 T An Overview of C
that value in memory is changed to I E I • If the value of what p is pointing to is equal to
I I , then that value in memory is changed to I \n ' The variable p is incremented at the
end of the fo r loop This causes p to point to the next character in the string
III printf("%s\n", s);
The variable s is printed in the format of a string followed by a newline character
Because the previous for loop changed the values of some of the elements of s, the
This creates the identifier p as a painter to char and the identifier s as an array of 100
elements of type char Because an array name by itself is a pointer, both p and s are
pointers to char However, p is a variable pointer, whereas s is a constant pointer that
points to s [0J Note that the expression ++p can be used to increment p, but because s
is a constant pointer, the expression ++s is wrong The value of s cannot be changed Of
fundamental importance is the fact that the two expressions
s[iJ and '/«(s + i)
are equivalent The expression s [i ] has the value of the ith element of the array
(count-ing from 0), whereas ~'(s + i) is the dereferencing of the expression s + i, a pointer
expression that points i character positions past s In a similar fashion, the two
Files are easy to use in C To open the file named myJile, the following code can be used:
c;
''<i fp;
ifp = fopen("rny_file", "r");
The second line in the body of rna in () declares i fp (which stands for infile pointer) to
be a pointer to FILE The function fopen () is in the standard library, and its function prototype is in stdio.h The type FILE is defined in stdio.h as a particular structure To use the construct, a user need not know any details about it However, the header file must be made available by means of a #i ncl ude directive before any reference to FILE
is made The function fopen 0 takes two strings as arguments, and it returns a pointer
to FILE The first argument is the name of the file, and the second argument is the mode in which the file is to be opened
Three modes for a file
"r" for read
"w" for "'Tite
When a file is opened for writing and it does not exist, it is created If it already exists, its contents are destroyed and the writing starts at the beginning of the file If
for some reason a file cannot be accessed, the pointer value NULL is returned by fopenO After a file has been opened, all references to it are via its file pointer Upon the completion of a program, the C system automatically closes all open files All C sys-tems put a limit on the number of files that can be open simultaneously Typically, this
Trang 3648 Chapter 1 "f An Overview of C
limit is either 20 or 64 When using many files, the programmer should explicitly close
any files not currently in use The library function fc lose 0 is used to close files
Let us now examine the use of files With text, it is easy to make a frequency analysis
of the occurrence of the characters and words making up the text Such analyses have
proven useful in many disciplines, from the study of hieroglyphics to the study of
Shakespeare To keep things simple, we ""ill write a program that counts the
occur-rences of just uppercase letters Among our files is one named chapter], which is the
current version of this chapter We will write a program called em_letters that will open
files for reading and writing to do the analysis on this chapter We give the command
ent_'etters chapter 1 data 1
to do this However, before we present our program, let us describe how command line
arguments can be accessed from within a program The C language provides a
connec-tion to the arguments on the command line Typically, to use the connecconnec-tion one would
code
#include <stdio.h>
int rnainCint argc, char *argv[])
{
Up until now we have always invoked rnai n 0 as a function with no arguments In fact,
it is a function that can have arguments The parameter argc stands for argument
count Its value is the number of arguments in the command line that was used to
exe-cute the program The parameter argv stands for argument vector It is an array of
pOinters to char Such an array can be thought of as an array of strings The successive
elements of the array point to successive words in the command line that was used to
execute the program Thus, argv [0] is a pointer to the name of the command itself As
an example of how this facility is used, suppose that we have written our program and
have put the executable code in the file cnUetters The intent of the command line
ent_'etters chapterl data 1
is to invoke the program ent_Ietters with the two file names chapter] and datal as
com-mand line arguments The program should read file chapter] and write to file datal If
we give a different command, say
ent_'etters ehapter2 data2
1.9 "f Files 49
then the program should read file ehapter2 and 'write to file data2 In our program the three words on the command line will be accessible through the three pointers argv [0J, argv [1] I and argv [2]
Here is our program:
In file cnLletters.c /* Count uppercase letters in a file */
"Usage: ", argv[0] , " infile outfile",
"The uppercase letters in infile will be counted.",
"The results will be written in outfile.");
while CCc getcCifp))!= EOF)
fprintf(ofp, "%c:%5d putcC'\n', ofp);
return 0;
After we have given the command
enUetters chapterl data 1
this is what we find in the file datal:
"
/* initialize array to zero */
/* find uppercase letters */
/* print results */
'A' + i, letter[i]);
Trang 37FILE *ifp, *ofp;
The array 1 etter will be used to count the occurrences of the uppercase letters The
variables i fp and ofp are of type pointer to FILE We often use the identifiers i fp and
ofp, which stand for infiZe pointer and outfile pointer, respectively
II if (argc != 3) {
}
printf("\n%s%s%s\n\n%s\n%s\n\n",
"Usage: ", argv[0] , " infile outfile",
"The uppe rcase 1 ette rs in i nfi 1 e will be counted.",
"The results will be written in outfile.");
exit(I);
If the number of words on the command line is not three, then the program is being
used incorrectly This causes a message to be printed and the program to be exited
Suppose the following command line is typed:
ent_letters chapter 1 abc abc
Because the line contains four words, argc will have value 4, and this will cause the
fol-lowing message to appear on the screen:
Usage: cnt_letters infile outfile
The uppercase letters in infile will be counted
The results will be written in outfile
ifp = fopen(argv[l] , "r");
ofp = fopen(argv[2] , "w");
1.9 'f' Files Sl
Ifwe assume that we have typed the command line
cnt_letters chapterl data 1
to execute this program, then argv[0] points to the string "cnt_l etters", argv[1] points to the string "chapter1", and argv[2] points to the string IIdatal" The C sys-
otem does this automatically Thus, the file chapter1 is opened for reading with file pointer i fp referring to it, and the file datal is opened for writing with file pointer ofp
referring to it
for (i = 0; i < 26; ++i) letter[i] = 0;
/* initialize array to zero */
In ANSI C, automatically allocated local array elements need not be initialized to zero
To be sure, the programmer must do it
II (c = getc(ifp)) != EOF
The function getcO is a macro defined in stdio.h It is similar to getcharO except that it takes as an argument a pointer to FILE When getc(ifp) is invoked, it gets the
next character from the file pointed to by i fp The identifier EOF stands for end-of-file
It is a symbolic constant defined in stdio.11, typically by the line
#define EOF (-1)
The value EOF is returned by getcO when there are no more characters in the file In C, characters have the integer value corresponding to their ASCII encoding (See Section 3.3, "Characters and the Data Type char," on page 111.) For example, 'a' has value 97, , b' has value 98, and so forth A char is stored in 1 byte, and an i nt is typically stored 'in either 2 or 4 bytes Thus, a char can be considered a small integer type Conversely,
an i nt can be considered a large character type In particular, an i nt can hold all the values of a char and other values as well, such as EOF, which is not an ordinary charac-ter value The variable c was declared to be an i nt rather than a char because it even-tually would be assigned the value EOF
II while ((c = getc(ifp)) != EOF)
if (c >= 'A' && c <= 'z') ++letter[c 'A'];
/* find uppercase letters */
A character is read and assigned to c If the value of the character is not EOF, then the body of the whi 1 e loop is executed
Trang 3852 Chapter 1 T An Overview of C
• C >= 'A' && c <= 'z'
The expression c >= 'A' is true if c is greater than or equal to 'A' Similarly, the
expression c <= 'z' is true if c is less than or equal to • Z ' The symbols && represent
the logical and operator An expression of the form
exprl && expr2
is true if and only if both exprl and expr2 are true Because of operator precedence
C >= 'A' && c <= • Z' is equivalent to (c >= 'A') && (c <= 'Z')
Thus, the expression c >= 'A' && c <= 'z' is true if and only if c has the value of an
uppercase letter
• ++letter[c - 'A'];
If c has the value 'A I , then c - I A' has the value 0 Thus, the array element 1
et-ter [0] gets incremented when c has the value' A' Similarly, if c has the value' B' ,
then c - 'A' has the value 1 Thus, the array element 1 ette r [ gets incremented
when c has the value 'B' In this way a count of the uppercase letters is kept in the
ele-ments of the array letter with letter[0] corresponding to the letter A, letter[l]
corresponding to the letter B, and so forth
• for (i = 0; i < 26; ++i) { /* print results */
if (i % 6 == 0)
putc('\n', ofp);
The symbol % is the modulus operator An expression such as a % b yields the
remain-der of a divided by b For example, 5 % 3 has the value 2 In the body of the for loop
we have used the expression i % 6, which has the value 0 whenever the value of i is a
multiple of 6 Because of operator precedence, the expression
i % 6 == 0 is equivalent to (i % 6) o
Thus, the expression i % 6 == 0 is true every sixth time through the loop; at these
times a newline character is printed If you look at the output of the program, you will
see that it is printed in six columns The macro putcO is defined in stdio.h It is similar
to putchar 0 except that its second argument is a pointer to FILE The value of its first
argument is written to the indicated file in the format of a character
• fprintf(ofp, "%c:%5d ", 'A' + i, letter[i]);
The function fpri ntfO is similar to pri ntfO except that it takes as its first
argu-1.10 T Operating System Considerations 53
ment a pointer to FILE When the function is invoked, it writes to the indicated file rather than to the screen Observe that 'A' + i is being printed in the format of a char-acter When i is 0, the expression' A' + i has the value' A', causing the letter A to be printed; when i is 1, the expression 'A' + i has the value 'B', causing the letter B to
be printed; and so forth
•
Although we did not do so, we could have explicitly closed the open files just before we exited from mainO Instead, we relied on the C system to close the files We would use the following code to expliCitly close the files:
fclose(ifp) ; fclose(ofp);
1.10 Operating System Considerations
In this section, we discuss a number of topics that are system-dependent We begin with the mechanics of writing and running a C program
Writing and Running a C Program
The precise steps that have to be followed to create a file containing C code and to pile and execute it depend on three things: the operating system, the text editor, and the compiler However, in all cases the general procedure is the same We first describe
com-in some detail how it is done com-in a UNIX environment Then we discuss how it is done in
an MS-DOS environment
In the discussion that follows, we will be using the ee command to invoke the C piler In reality, however, the command depends on the compiler that is being used For example, if we were using the command line version of the Turbo C compiler from Bor-land, then we would use the command tee instead of ec (For a list of C compilers, see the table in Section 11.13, "The C Compiler," on page 522.)
Trang 39com-54 Chapter 1 " An Overview of C
Steps to be followed in writing and running a C program
1 Using an editor, create a text file, say pgm.c, that contains a C program The
name of the file must end with c, indicating that the file contains C source code
For example, to use the vi editor on a UNIX system, we would give the command
vi pgm.c
To use an editor, the programmer must know the appropriate commands for
inserting and modifying text
2 Compile the program This can be done with the command
cc pgm.c
The cc command invokes in turn the preprocessor, the compiler, and the loader
The preprocessor modifies a copy of the source code according to the
prepro-cessing directives and produces what is called a translation unit The compiler
translates the translation unit into object code If there are errors, th~n the
pro-grammer must start again at step 1 with the editing of the source file Errors that
occur at this stage are called syntax errors or compile-time errors If there are no
errors, then the loader uses the object code produced by the compiler, along with
object code obtained from various libraries provided by the system, to create the
executable file a.out The program is now ready to be executed
3 Execute the program This is done with the command
a.out
Typically, the program will complete execution, and a system prompt will
reap-pear on the screen Any errors that occur during execution are called run-time
errors If for some reason the program needs to be changed, the programmer
must start again at step 1
If we compile a different program, then the file a.out will be overwritten, and its
pre-vious contents lost If the contents of the executable file a.out are to be saved, then the
file must be moved, or renamed Suppose that we give the command
cc sea.c
This causes executable code to be written automatically into a.out To save this file, we
can give the command
mv a.out sea
1.10 " Operating System Considerations 55
causes a.out to be moved to sea Now the program can be executed by giving the
conunand
sea
UNIX, it is common practice to give the executable file the same name as the ,sponding source file, except to drop the c suffix If we wish, we can use the -0 option to direct the output of the cc command For example, the command
Let us now consider an MS-DOS environment Here, some other text editor would most likely be used Some C systems, such as Turbo C, have both a command line envi-ronment and an integrated environment The integrated environment includes both the text editor and the compiler (Consult Turbo C manuals for details.) In both MS-DOS and UNIX, the command that invokes the C compiler depends on which C compiler is being used In MS-DOS, the executable output produced by a C compiler is written to a file having the same name as the source file, but with the extension exe instead of c Sup- pose, for example, that we are using the command line environment in Turbo C If we give the command
tee sea.c
then the executable code will be written to sea.exe To execute the program, we give the
command
sea.exe or equivalently sea
To invoke the program, we do not need to type the exe extension If we wish to rename
this file, we can use the rename command
Trang 4056 Chapter 1 v An Overview of C
Interrupting a Program
When running a program, the user may want to interrupt, or kill, the program For
example, the program may be in an infinite loop (In an interactive environment it is not
necessarily wrong to use an infinite loop in a program.) Throughout this text we
assume that the user knows how to interrupt a program In MS-DOS and in UNIX, a
con-trol-c is commonly used to effect an interrupt On some systems a special key, such as
delete or rubout is used Make sure that you know how to interrupt a program on your
system
Typing an End-af-file Signal
When a program is taking its input from the keyboard, it may be necessary to generate
an end-of-file signal for the program to work properly In UNIX, a carriage return
fol-lowed by a control-d is the typical way to effect an end-of-file signal (See exercise 26,
on page 68, for further discussion.)
Redirection af the Input and the Output
Many operating systems, including MS-DOS and UNIX, can redirect the input and the
output To understand how this works, first consider the UNIX command
Is
This command causes a list of files and directories to be written to the screen (The
comparable command in MS-DOS is dir.) Now consider the command
Is > tmp
The symbol> causes the operating system to redirect the output of the command to
the file tmp What was written to the screen before is now written to the file tmp
Our next program is called dbLout It can be used with redirection of both the input
and the output The program reads characters from the standard input file, which is
normally connected to the keyboard, and writes each character twice to the standard
output file, which is normally connected to the screen
file dbLout.c
#include <stdio.h>
int main(void) {
dbLout >
dbLout <
infile outfile infile > outfile
Used in this context, the ~ymb~ls < and> can be thought of as arrows (See exercise 26
Some commands are not meant to be used with redirection For example, the Is mand do~s not read characters from the keyboard Therefore, it mal<es no sense to redi-rect :he mput to the ls command; because it does not take keyboard input th