1. Trang chủ
  2. » Công Nghệ Thông Tin

IT training a book on c programming in c (4th ed ) kelley pohl 1998 01 08

376 73 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 376
Dung lượng 47,39 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

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 2

TT

ADDISON-WESLEY

Boston • San Francisco • New York· Toronto • jIy[ontreal

London • Munich • Paris • Madrid

Capetown • Sydney' Tokyo • Singapore • Mexico Cit:J1

Trang 3

Many 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 4

1.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 5

viii , 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 6

x " 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 7

xii ., 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 8

13.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 9

7

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 10

xviii 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 11

t

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 12

Chapter 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 13

commit-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 14

4 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 15

6 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 16

8 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 17

10 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 18

12 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 19

14 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 20

16 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 21

18 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 22

20 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 23

22 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 24

variable 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 25

1, 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 26

28 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 27

no 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 28

32 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 29

34 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 30

When 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 31

is 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 32

40 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 33

42 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 34

44 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 35

46 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 36

48 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 37

FILE *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 38

52 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 39

com-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 40

56 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

Ngày đăng: 05/11/2019, 14:57

TỪ KHÓA LIÊN QUAN