Synthesis Lectures Lectures on Mechanical Engineering Engineering
C Progr graamming and Num umeri erica call An Analy alysi siss An Introduction
Synthesis Le Syn Lecctu turres on Mecha Me chani nical cal En Engine gineerin ering g Synthesis Lectures on Mechanical Engineering series publishes 60–150 page publications pertaining to this diverse discipline of mechanical engineering. e series presents Lectures written for an audience of researchers, industry industr y engineers, undergraduate and graduate students. Additional Synthesis series will be developed covering key areas within mechanical engineering.
C Programming and Numerical Analysis: An Introduction
Seiichi Nomura 2018
Mathematical Magnetohydrodynamics
Nikolas Xiros 2018
Design Engineering Journey
Ramana M. Pidaparti 2018
Introduction to Kinematics and Dynamics of Machinery
Cho W. S. To 2017
Microcontroller Education: Do it Yourself, Reinvent the Wheel, Code to Learn
Dimosthenis E. Bolanakis 2017
Solving Practical Engineering Mechanics Problems: Statics
Sayavur I. Bakhtiyarov 2017
Unmanned Aircraft Design: A Review of Fundamentals
Mohammad Sadraey 2017
iii
Introduction to Refrigeration and Air Conditioning Systems: eory and Applications
Allan Kirkpatrick 2017
Resistance Spot Welding: Fundamentals and Applications for the Automotive Industry Menachem Kimchi and David H. Phillips 2017
MEMS Barometers Toward Vertical Vertical Position Detecton: Background eory, System Prototyping, and Measurement Analysis
Dimosthenis E. Bolanakis 2017
Engineering Finite Element Analysis
Ramana M. Pidaparti 2017
Copyright © 2018 by Morgan & Claypool All rights reserved. No part of this publication may be reproduced, stored in a retrieval retrie val system, or transmitted in anyform any formor or by anymea any means— ns—elec electr troni onic, c, mechan mechanica ical,l, photoc photocopy opy,, record recording ing,, or any any other other except except for brief brief quotat quotation ionss in printed reviews, without the prior permission of the publisher. C Programming and Numerical Analysis: An Introduction Seiichi Nomura www.morganclaypool.com
ISBN ISBN:: 9781 978168 6817 1733 3311 1111 ISBN ISBN:: 9781 978168 6817 1733 3312 1288 ISBN ISBN:: 9781 978168 6817 1733 3313 1355
pape paperb rbac ack k eboo ebook k hard hardco cove verr
DOI 10.2200/S00835ED1V01Y201 10.2200/S00835ED1V01Y201802MEC013 802MEC013 A Publication in the Morgan & Claypool Publishers series SYNTHESIS LECTURES ON MECHANICAL ENGINEERING
Lecture #13 Series ISSN Print Print 2573-3168 2573-3168 Electronic Electronic 2573-3176 2573-3176
C Progr graamming and Num umeri erica call An Analy alysi siss An Introduction
Seiichi Nomura e University of Texas Texas at Arlington
SYNTHESIS LECTURES LECTURES ON MECHANICAL ENGINEERING ENGINEERING #13
M & C
M o r g a n & cLaypool p u b l i s h e r s
ABSTRACT is book is aimed at those in engineering/scientific fields who have never learned programming before but are eager to master the C language quickly so as to immediately apply it to problem solving in numerical analysis. e book skips unnecessary formality but explains all the important aspects of C essential for numerical analysis. Topics covered in numerical analysis include single and simultaneous simultaneous equations, differential differential equations, equations, numerical numerical integration, integration, and simulasimulations by random numbers. In the Appendices, quick tutorials for gnuplot, Octave/MATLAB, and FORTRAN for C users are provided.
KEYWORDS C, numerical analysis, Unix, gcc, differential equations, simultaneous equations, Octave/MATLAB, Octave/MATLAB, FORTRAN, gnuplot
vii
Contents Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiii
PAR ART T I Int ntrrod oduc ucti tio on to C Progr gram amm min ing g . . . . . . . . . . . . . 1 1
Firs Firstt St Step epss to Ru Run n a C Prog ogra ram m. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.1 1.2 1.3 1.4
2
A Cycle of C Programmin Programmingg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 UNIX Command Command Primer Primer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 Overview of C Program Programming ming.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 1.3.1 Princip Principles les of C language language . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 1.3.2 Skeleto Skeletonn C program program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 Exercises Exer cises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Comp Co mpon onen ents ts of C La Lang ngua uage ge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.1 2.2 2.3
2.4
Variable ariabless and Data Data Types Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.1.1 Cast Operators Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.1.2 Exampl Examples es of Data Type Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Input/Output Input/ Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Operators Opera tors between between Variable Variabless . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3.1 Relatio Relational nal Operators Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3.2 Logical Operators Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3.3 Increm Increment/De ent/Decreme crement/Subst nt/Substitutio itutionn Operators Operators . . . . . . . . . . . . . . . . . . . 2.3.4 Exer Exercises cises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Control Contr ol Statements Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.4.1 if Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.4.2 for Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.4.3 while Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.4.4 do whi while le Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.4.5 switch Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17 18 19 20 22 23 23 24 25 25 26 27 31 32 33
viii
2.4.6 Miscella Miscellaneous neous Remarks Remarks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 2.4.7 Exer Exercises cises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 2.5 Func Functions tions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 2.5.1 Definit Definition ion of Functions Functions in C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 2.5.2 Locality of Variable Variabless within a Function Function . . . . . . . . . . . . . . . . . . . . . . . . . 41 2.5.3 Recursi Recursivity vity of Functions Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 2.5.4 Random Numbe Numbers, rs, rand() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 2.5.5 Exer Exercises cises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 2.6 Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 2.6.1 Definit Definition ion of Arrays Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 2.6.2 MultiMulti-dimensio dimensional nal Arrays Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 2.6.3 Examp Examples les . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 2.6.4 Exer Exercises cises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 2.7 File Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 2.7.1 I/O Redirect Redirection ion (Standard (Standard Input/Outpu Input/Outputt Redirection) Redirection).. . . . . . . . . . . . . 60 2.7.2 Fil Filee Handling (From (From within within a Program) Program) . . . . . . . . . . . . . . . . . . . . . . . . 61 2.8 Poi Pointers nters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 2.8.1 Addre Address ss Operat Operator or & and Dereferencing Operator * . . . . . . . . . . . . . . . . 63 2.8.2 Prop Properties erties of Pointer Pointerss . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 2.8.3 Func Function tion Arguments Arguments and Pointers Pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 2.8.4 Po Pointers inters and Arrays Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 2.8.5 Func Function tion Pointer Pointerss . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 2.8.6 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 2.8.7 Exer Exercises cises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 2.9 String Manipulati Manipulation on . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 2.9.1 How to to Handle a String of Characters Characters (T (Text) ext) . . . . . . . . . . . . . . . . . . . 75 2.9.2 String Copy/Com Copy/Compare/ pare/Length Length . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 2.10 Command Line Line Arguments Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 2.10.1 Entering Command Line Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . 80 2.10.2 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 2.11 Structur Structures es . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 2.11.1 Mixture of Different Types Types of Variables . . . . . . . . . . . . . . . . . . . . . . . . . 83 2.11.2 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
ix
PAR ART T II Nu Nume meri rica call An Anal alys ysis is . . . . . . . . . . . . . . . . . . . . . . 89 3
Note No te on Nu Nume meric rical al Err Error orss . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
4
Root Rootss of f.x/ D 0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
4.1 4.2
5
Numerical Nume rical Differ Differentia entiation tion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
5.1 5.2 5.3
6
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Introduction Rectangular Rectan gular Rule Rule . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Trapezoid rapezoidal al Rule . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Simpson’’s Rule . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Simpson Exercises Exer cises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
115 115 117 118 121
Solving Simul Simultane taneous ous Equat Equations ions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
7.1 7.2 7.3 7.4 7.5
8
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 Introduction Forward/Ba Forwa rd/Backward ckward/Centra /Centrall Difference Difference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 Exercises Exer cises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
Numerical Numerical Integra Integration tion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
6.1 6.2 6.3 6.4 6.5
7
Bisection Method Bisection Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 Newton’’s Method Newton Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 4.2.1 Newton Newton’’s Method for a Single Single Equation Equation . . . . . . . . . . . . . . . . . . . . . . . 102 4.2.2 Newton’s Method for Simultaneous Equations (Optional) . . . . . . . . . 106 4.2.3 Exer Exercises cises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Introduction Gauss-Jordan GaussJordan Eliminati Elimination on Method Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . LU Decompos Decomposition ition (Optio (Optional) nal) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Gauss-Seidel GaussSeidel Method ( Jacobi Method) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Exercises Exer cises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
123 126 129 133 135
Differential Differential Equat Equations ions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
8.1 8.2 8.3
Initial Value Initial Value Proble Problems ms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.1.1 Euler’s Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.1.2 Runge-K Runge-Kutta utta Method Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Higher-orde Highe r-orderr Ordinary Ordinary Differentia Differentiall Equations Equations . . . . . . . . . . . . . . . . . . . . . . . . Exercises Exer cises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
137 138 143 144 146
x
A
Gnuplot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
B
Octav Octavee (MA (MATLA TLAB) B) Tuto utorial rial for C Pr Progra ogramme mmers rs . . . . . . . . . . . . . . . . . . . . . . . 153
B.1 B.2
B.3 B.4
C
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 Introduction Basic Operatio Operations ns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 B.2.1 Principles of Octave/MATLAB Octave/MATLAB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 B.2.2 B.2 .2 Reserved Constants Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155 B.2.3 Vectors/Matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156 B.2.4 B.2 .4 Graph . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158 B.2.5 I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159 B.2.6 M-files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160 B.2.7 B.2 .7 Conditi Conditional onal Statement Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 Sketch of Comparison Comparison Betwe Between en C and Octave/M Octave/MA ATLAB . . . . . . . . . . . . . . 162 Exercises Exer cises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
FOR FORTRA TRAN N Tuto utorial rial for C Pr Progra ogramme mmers rs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
C.1 C.2 C.3 C.4
FORTRAN Features FORTRAN Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . How to to Run a FORTRA FORTRAN N Program Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Sketch of Compar Comparison ison Between Between C and FORTRAN FORTRAN . . . . . . . . . . . . . . . . . . . Exercises Exer cises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
169 170 171 178
Author’ss Biography . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181 Author’ Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
xi
Preface is book is aimed at those who want to learn the basics of programming quickly with immediate applications to numerical analysis in mind. It is suitable as a textbook for sophomore-level STEM students. e book has two goals as the title indicates: e first goal is to introduce the concept of computer programming using the C language. e second goal is to apply the programming skill to numerical analysis for problems arising in scientific and engineering fields. No prior knowledge of programming is assumed but it is desirable that the readers have a background in sophomore-level calculus and linear algebra. C was selected as the computer language of choice in this book. ere have been continuous debates as to what programming language should be taught in college. Until around the 1990s, FORTRAN had been the dominating programing language for scientific and engineering computation which was gradually taken over by modern programming languages as PASCAL and C. Today, MATLAB is taught in many universities as a first computer application/language for STEM students. Python is also gaining popularity as a general purpose programming language suitable as the first computer language to be taught. Despite Despite many options for the availability of various modern computer languages today, today, adopting adopting C for scientific scientific and engineer engineering ing computation computation still has several several merits. merits. C contains contains almost all the concepts and syntax used in the modern computer languages less the paradigm of objectoriented programming (use C++ and Java for that). It has been observed that whoever learns C first can easily acquire other programming languages and applications such as MATLAB quickly. e converse, however, does not hold. C is a compiled language and preferred over interpreted languages for programs that require fast execution. ere is no shortage of good textbooks for the C language and good textbooks for numerical analysis on the market but a proper combination of both seems to be hard to find. is book is not a complete reference for C and numerical numeric al analysis. Instead, the book tries tr ies to minimize the formality and limits the scope of C to these essential features features that are absolutely absolutely necessary for numeri numerical cal analy analysi sis. s. Some Some feat featur ures es in C that that are are not relev relevan antt to nume numeric rical al analy analysis sis are are not cover covered ed in this book. C++ is not covered either as the addition of object-oriented programming components offers little benefit for numerical analysis. After finishing this book, the reader should be able to work on many problems in engineering and science by writing their own C programs. e book consists of two parts. In Part I Part I,, the general syntax of the C language is introduced and explained explained in details. details. gcc is used as the compiler which is freely f reely available available on almost all platforms. As the native platform of gcc is UNIX, a minimum introduction to the UNIX operating system is also presented.
xii
PREFACE PREF ACE
In Part II Part II the the major topics from numerical analysis are presented and corresponding C programs are listed and explained. e subjects covered in Part II Part II include include solving a single equation, numerical differentiation, numerical integration, solving a set of simultaneous equations, and solving differential equations. In Appendix A Appendix A,, gnuplot which is a visualization application is introduced. e C language itself has no graphical capabilities and requires an external program to visualize the output from the program. In Appendix B Appendix B,, a brief tutorial tutor ial of Octave/MATLAB Octave/MATLAB is given. is is i s meant for those who are familiar with C but need to learn Octave/MA Octave/MATLAB TLAB in the shortest possible amount of time. In Appendi Appendixx C, a brie brieff tuto tutori rial al of FORT FORTRA RAN N is give given. n. Agai Again, n, this this is mean meantt for for thos thosee who who are already familiar with C to be able to read programs written in FORTRAN F ORTRAN (FORTRAN 77) quickly. is book is based on the course notes used for sophomore-level students of the Mechanical and Aerospace Engineering major at e University of Texas at Arlington. Seiichi Nomura March 2018
xiii
Acknowledgments Acknowledg ments I want to thank the students who took this course for their valuable feedback. I also want to thank Paul Petralia of Morgan & Claypool Publishers and C.L. Tondo of T&T TechWorks, Inc. for their support and encouragement. All the programs and tools used in this book are freely available over the internet thanks to the noble vision of the GNU project and the Free Software Foundation (FSF). Seiichi Nomura March 2018
PART ART I
Intr ntroduc oducti tion on to C Program ogrammi ming ng
3
In Part I, the basic syntax of the C language is introduced so that you can quickly write a program for problems in science and engineering to be discussed in Part II. is is never meant to be a complete reference for the C language. It covers only those items relevant to scientific/engineering computation. However, after Part I, you should be able to explore missing topics on your own. A minimum amount of computer environments is needed and all the programs listed should run on any version of gcc gcc . e only way to learn programming is to write a program by yourself. You never learn programming if you just read books sitting on a sofa.
5
CHAPTER 1
Firrst Steps to Run a C Program Fi In this chapter, the basic cycle of running a C program is explained. To execute a C program, it is necessary to first write a C code using a text editor, save the code with the file extension, “.c”, launch a C compiler compiler to translate translate the text into an binary code, and, if everything goes well, run an executable (called a.out in UNIX). If this is the first time you program in C, it is important that you try every single step described in the following sections.
1.1
A CYCLE OF C PROGRAMMING
ere are a variety of ways to access a C compiler and run a C program. Almost all schools run r un a UNIX server open to the students. You should be able to activate your account on the UNIX server, connect to the server via an ssh1 client such as PuTTY PuTT Y over the internet, and run a freely 2 distributed C compiler, gcc . It is also possible to have a similar setup at home by running your own Linux server or installing a PC/Mac version of gcc. If you come from a Windows or Mac environment, you are accustomed to the graphical user interface (GUI) clicking an icon to open an application. However, However, to use gcc, you must use the character-based interface (CUI) to compile and run your program in a UNIX shell, in a command line (DOS) window (Windows) or in Terminal App (Mac). To run gcc on the Windows W indows system, system, you can go to www.mingw.org and download the gcc installer, mingw-get-setup.exe . In what follows in this book, we use PuTTY 3 (terminal emulation software) to access a UNIX server and run gcc on the server. Figure 1.1 Figure 1.1 shows shows an opening screen when PuTTY is launched on the Windows system. In the box circled, enter the name of a server that runs gcc and press the Open button. It will prompt you to enter your username (case sensitive) and password (won’t echo back). Once you are are logg logged ed on the the serve serverr, you you are are prom prompt pted ed to ente enterr a comm comman andd from from the the cons consol olee (see (see Figur iguree 1.2 1.2).). If you have never used a UNIX system before, you may want to play with some of the essential UNIX commands. Try Try the following: fo llowing: 1. Login to the server via PuTTY. PuTTY. 1 ssh (Secure Shell) is a networking protocol by which two computers are connected via a secure channel. 2 gcc is an abbreviation for GNU Compiler Collection. It is a compiler system produced by the GNU Project. 3 PuTTY is a free and open-source terminal emulator available available for the Windows system that can be downloaded from www. putty.org. e size of the executable is less than 1 MB and the t he program loads very fast.
6
1. FIR IRSTSTE STSTEPS PS TO RU RUN N A C PR PROG OGR RAM
Figure 1.1: Opening 1.1: Opening screen of PuTTY. 2. Using nano,4 a simple text editor, compose your C program (Figure 1.3 (Figure 1.3).). $ nano nano MyProg MyProgram ram.c .c
e symbol, $, is the system prompt so do not type it. Enter the following text into nano. Note that all the input in UNIX is case-sensitive. #include #include
int main() main() { printf("Hel printf("Hello, lo, World!\n"); World!\n"); return return 0; } 4 nano is a simple editor that comes with all the th e installation of UNIX. It is a clone of
another simple text editor, pico.
1.1. 1. 1. A CY CYCL CLE E OF C PR PROG OGRA RAMM MMIN ING G
Figure 1.2: A 1.2: A UNIX session in PuTTY. 3. After you finish entering the text, save the file (Control-O (Control-O5 ) by entering MyProgram.c6 as the file name to be saved and press Control-X to exit from nano. is will save the file you just created permanently under un der the name of MyProgram.c MyProgram.c. 4. e file you created with nano is a text file that is not understood understood by the computer computer. It is necessary to translate this text file into a code which can be run on the computer. is translation process is called compiling and the software to do this translation is called a compiler. We use gcc for this purpose. At the system prompt ($), run a C compiler ( gcc) to generate an executable file ( a.out7 ). $ gcc MyProg MyProgram ram.c .c
If everything works, gcc will create an executable binary file whose default defaul t name is a.out. 5 Hold down the control key and press O. 6 e file name is case sensitive. 7 a.out is an abbreviation for assembler assembler output.
7
8
1. FIR IRSTSTE STSTEPS PS TO RU RUN N A C PR PROG OGR RAM
Figure 1.3: A 1.3: A nano session in PuTTY. 5. Run the executable file. $ ./a.ou ./a.out t8
6. If there is a syntax error, go back to item 2 and reissue nano. $ nano nano MyProg MyProgram ram.c .c
7. If there is no syntax error, run the executable file. $ ./a.ou ./a.out t
8. To logoff from the server, enter exit, logout, or hit control-D.
1.22 1.
UNIIX COM UN OMM MAN AND D PR PRIM IME ER
In a perfect world, you could compose a C program, compile compil e it, and run a.out and you are done with it. is scenario may work for a program of less than 10 10 lines but as the size of the program grows or the program depends on other modules, it is necessary to manipulate and organize files on the UNIX system. Even though this is not an introductory introducto ry book of the UNIX operating 8 “./” represents represents the
necessary.
current current directory directory.. If the current current directory is included included in the PATH environmental variable, “./” is not
1.2. 1. 2. UN UNIX IX CO COMMA MMAND ND PR PRIM IMER ER 9
system, a minimum amount of knowledge about the UNIX operating system is needed. e following are some of the UNIX commands that are used often. Try each command yourself from the system prompt and find out what it does. It won’t damage the machine. •
ls (Directory listing.)
• ls
-l (Directory listing in long format.)
• ls
(Directory tory listing listing,, one screen screen at one time, time, long format, format, chrono chronologi logical cal order order.) .) -lt -lt more (Direc
j
•
dir (alias for ls )
•
ls . (Lists the current directory.)
• cd
.. (Moves to the directory one level up.)
•
pwd (Shows the
•
cd / (Moves to the top directory.)
•
cd (Returns to the home directory.)
• mkdir • nano
present working directory director y.)
MyNewFolde MyNewFolder r (Creates a new
directory.)
myfile.txt myfile.txt (Creates a new file.)
• cp
program1.c program1.c program2.c program2.c (Copies program1.c to program2.c.)
• mv
old. old.c c new. new.c c (Renames old.c to new.c.)
• rm
program.c program.c (Deletes program.c.)
• rm
*.c *.c (Do not do this. It will delete all the files with extension c .)
• whoami (Shows your username.) •
who (Shows who are logged on.)
•
cal (Shows this
• cal cal
year’s calendar.) calendar.)
1980 1980 (Shows the calendar of 1980.)
To To quickly quic kly move mo ve while entering/editing a command line and in nano sessions, master the following shortcuts. ^f means holding down the control key and pressing the f key. •
^f (Moves cursor forward by one character, f for forward.)
•
^b (Moves cursor backward by one character, b for backward.)
10 1. FI FIR RST ST STE EPS TO RU RUN N A C PR PROG OGRA RAM M
•
^d (Deletes a character on cursor, d for delete.)
•
^k (Deletes entire line, k for kill.)
•
^p (Moves to previous line, same as up arrow, p for previous.)
•
^n (Moves to next line, same as down arrow, n for next.)
•
^a (Moves to top of line, a for the first alphabet.)
•
^e (Moves to end of line, e for end.)
1.33 1.
OVE VER RVIE IEW W OF C PR PROG OGR RAM AMM MIN ING G
Arguably Arguably,, the most important book on the C language is a book known as “K&R” written by Kernigh Kernighan an and Ritchie Ritchie9 who themselves developed the C language. It is concise yet well-written and is highly recommended for reading. 1.3. 1. 3.11
PRIN PR INCI CIPL PLES ES OF C LA LANG NGU UAGE
Surpr Surprisi isingl nglyy, the the C langu languag agee is base basedd on a few simpl simplee princ princip iples les.. ey ey are are summa summariz rized ed as follo follows ws:: 1. A C program program is a set of functions. functions. 2. A function in C is a code that follows the syntax below: type type name(t name(type ype var) var) { your your C code code here here.. .... ... . ...... return value; }
3. A function must be defined before it is used. 4. A function must return a value whose type must be declared (one of int int , float, double, char). e last line of a function must be a retu return rn xx statement where xx is a value to be returned upon exit. 5. A function must take arguments and must have a placeholder () even if there is no argument. 6. e content content of a function must be enclosed enclosed by “{” and “}”. 9 Kernighan and Ritchie, C Programming Language , 2nd ed.,
Prentice Hall, 1988.
1.3. 1. 3. OV OVER ERVIE VIEW W OF C PR PROG OGRA RAMMI MMING NG 11
7. A special special function function,, int int main() main(), is the one which is executed first. It is recommended that this function returns an integer value of 0. 8. All the variables used within a function must be declared. 1.3. 1. 3.22
SKEL SK ELET ETON ON C PR PROG OGRA RAM M
e following program is absolutely the smallest C program that can be written: int main() main() { return return 0; }
You You can compile and an d execute this program by issuing the following commands: $ gcc MyProg MyProgram ram.c .c $ ./a.ou ./a.out t
where MyProgram.c is the name under which the file was saved. Even though it is the smallest C program, the program itself is a full-fledged full-fledged C code. Of course, this program does nothing and and when when you you issu issuee ./a.out, the the prog progra ram m simp simply ly exit exitss afte afterr bein beingg exec execut uted ed and and you you are are retu return rned ed to the system prompt. Here is a line-by-line analysis of the program above. Refer to Section 1.3.1 Section 1.3.1 for for the list of items. e first line, int int main() main(), indicates that a function whose name is main is declared that returns an integer value (int) upon exit (Item 4). is function takes no arguments (empty para parame mete ters rs with within in the the pare parenth nthes eses es)) (Ite (Item m 5). 5). e prog progra ram m consis consists ts of only only one one funct functio ion, n, main(), which is executed first (Item 7). e content of the function, main(), is the line(s) surrounded by { { and } (Item 6). In this case, the program executes the return return 0 statement and exits back to the operating system returning a 0 value to the operating system. As C is a free-form language, the end of each statement has to be clearly marked. A semicolon ; is placed at the end of each statement. Hence, return return 0;. e following f ollowing program is a celebrated code that appeared first in the K&R book in the section and later adapted in just about every introductory book for C as the first Getting Started section C program that prints “Hello, World!” followed by an extra blank line. 1:#include 1:#include 2:int main() main() 3:{ 4:printf("Hello, World!\n"); 5:return 5:return 0; 6:}
12 1. FI FIR RST ST STE EPS TO RU RUN N A C PR PROG OGRA RAM M
Eachlineintheaboveprogramisnowparsed.efirstline,#include #include ,isabit conf confus usin ingg but but let’ let’ss skip skip this this line line for for the the time time bein beingg and and move move to the the subs subseq eque uent nt line lines. s. If you comcompile the program and execute a.out, you will find out that the program prints Hello, Hello, World! World! followed by a new line on the screen. Hence, you can guess that the odd characters, \n , represents a blank line. As there is no character that represents represents a blank line, you figure out that \n can be used as printing a blank line. Next, note that the part printf is followed by a pair of parentheses and therefore, it is a function in C (Item 5). It is obvious that this function, printf(), prints a string, Hello, Hello, World!, and quits. As it is a function in C, it has to be defined and declared before it is used. However, no such definition is found above the function, main(). e first line, #include #include , is in fact referring to a file that contains c ontains the definition of printf() printf() that is prel preloa oade dedd befor beforee anyt anythin hingg else else.. e file, file, stdio.h, is one one of the the head header er (hen (hence ce the the exte extens nsio ion, n, h) files files avai availa labl blee in the the C libr library ary that that is ship shippe pedd with with gcc.Asthenameindicates(stdio = Standar Standardd Input and Output), this header file has the definition of many functions that deal with input and output (I/O) functions. Finally, a function must have information about the type of the value it returns such as int, float, double, etc…(Item 4). In this case, the function int int main() main() is declared to return an integer value upon exit. Sure enough, the last statement retu return rn 0; is to return 0 when the execution is done and 0 is an integer. Here is how gcc gcc parses this program line by line: Line Line 1 Before anything else, let’s load a header file, , that contains the definition of
all the functions that deal with I/O from the system area.
Line Line 2 is is the start of a function called main(). is function returns an integer value int
upon exit. is function has no parameters to pass so the content within the parentheses is empty.
Line Line 3 e { character indicates that this is the beginning of the content of the function, main().
Line Line 4 is line calls the function, printf(), that is defined in and prints out a
string of Hello, Hello, function.
World! World! followed by a blank line. A semicolon, ; , marks the end of this
Line Line 5 is is the last statement of the function, main(). It will return the value 0 to the oper-
ating system and exit.
Line Line 6 e } character indicates the end of the content of the function, main().
You You can execute this program by $ nano nano hell hello. o.c c
1.3. 1. 3. OV OVER ERVIE VIEW W OF C PR PROG OGRA RAMMI MMING NG 13
(Enter the content of the program above.) $ gcc gcc hell hello. o.c c
(If it is not compiled, reedit hello.c.) $ ./a.ou ./a.out t Hello, World! World!
Here is another program that does some scientific computation. 1:#include 1:#include 2:#include 2:#include 3: /* Thi This is a comm commen ent t */ 4:int main() main() 5: { 6: float float x, y; 7: x = 6.28; 8: y=sin(x); y=sin(x); 9: prin printf tf(" ("Si Sine ne of %f is %f.\ %f.\n" n", , x, y); y); 10: 10: retu return rn 0; 11:}
as
is program computes the value of sin sin x where x D 6:28. e program can be compiled
$ gcc gcc MyPr MyProg ogra ram. m.c c -lm -lm
Note that the -lm 10 option is necessary when including .11 Here is a line by line analysis of the program: Line Line 1 e program preloads a header file, .
e prog progra ram m also also prel preloa oads ds an anoth another er head header er file, file, . is is head header er file file is nece necess ssary ary Line Line 2 e whenever mathematical functions functi ons such as sin.x/ are used in the program. /* and /* is a comment and is Line Line 3 is entire line is a comment. Anything surrounded by /*
ignored by the compiler. c ompiler.12
Line Line 4 is is the declaration of a function, main(), that returns an integer value but with no
parameter.
10 “-l” is to load a library and “ m” stands for the math library. 11 only contains protocol declarations for mathematical functions. It is necessary to locally load the mathematical
library, libm.a by the -lm option. 12 A comment can also start with // . is for one-line comment originated in C++.
14 1. FI FIR RST ST STE EPS TO RU RUN N A C PR PROG OGRA RAM M
Line Line 5 e { character indicates that this is the beginning of the content of the function, main().
Line Line 6 Two variables, x and y , are declared both of which represent floating numbers. Line Line 7 e variable, x , is assigned a floating number, 6.28. Line Line 8 efunction, sin.x/,isevaluatedwhere x is 6.28 6.28 and and the the resu result lt is assi assign gned ed to the the vari variab able le,, y.
Line Line 9 e result is printed. First, a literal string of “Sine Sine of” is printed followed by the actual
value of x x and “is” is printed followed by the actual value of y y, a period and a new line.
Line Line 10 e function, main(), exits with a return value of 0. Line Line 11 e } character indicates that this is the end of the content of the function, main().
ere are several new concepts in this program that need to be explained. e second line is to preload preload yet another another header file, math.h, as this program computes the sine of a number. In the fourth line, two variables, x and y, are declared. e float part indicates that the two variables represent floating numbers (real numbers with the decimal point). e fifth line says that that a numb number er,, 6.28 6.28,, is assig assigne nedd to the the varia variabl ble, e, x.eequalsign(=) here here is not not the the math mathem emat atic ical al equality equality that you are accustomed accustomed to. In C and all other computer languages, languages, an equal sign (=) is exclusively used for substitution, i.e., the value to the right of = is assigned to the variable to the left of =. In the eighth line, the printf() function is to print a list of variables (x and y) with formating formating specified by the double quotation quotation marks (“...”). e way formating works is that printf() prints everything everythin g literally within the parentheses except for special codes starting with the percentage sign (%). Here, %f represents a floating number which is to be replaced by the actual value of the variable. As there are two %f ’s, the first %f is replaced by the value of x and the second %f is replaced by the value of y y . e details of the new concepts shown here will be explained in detail in Chapter 2 Chapter 2..
1.44 1.
EXE XER RCI CISE SES S
It is not necessary necessar y to know all the syntax of C to work on the following problems. Each problem has a template that you can modify. Start with the template code, keep modifying the code and understand what each statement does. It is essential that you actually write the code yourself (not copy and paste) and execute it. 1. Write a C program to print three blank lines followed by “Hello, World!”. World!”. Use the following code as a template:
1.4. 1. 4. EX EXER ERCI CISE SES S
15
#include #include int main() main() { printf("\nHello, World!\n\n"); return return 0; } \n prints a new line.
2. Write a program to read two real numbers from the keyboard and to print their product. Use the following code as a template. Do not worry about the syntax, just modify one place. #include #include int main() main() { int int a, b; /* to decl declar are e that that a and and b are are inte intege ger r vari variab able les s */ printf printf("E ("Ente nter r two intege integer r number numbers s separa separated ted by space space ="); ="); scan scanf( f("% "%d d %d", %d", &a, &a, &b); &b); /* This This is the the way way to read read two two inte intege ger r numb number ers s and and assi assign gn them them to a and and b. */ prin printf tf(" ("Th The e sum sum of the the two two numb number ers s is %d.\ %d.\n" n", , a+b) a+b); ; /* %d is for for intege integer r format format. . */ return return 0; }
3. Write a program to read read a real number, number, x , and outputs its sine, i.e., sin.x/. You need to use and the the -lm comp compile ile opti option. on. Use Use the the follow following ing temp templa late te prog program ram that that comp comput utes es and x e . #include #include #include #include int main() main() { float float x; printf printf("E ("Ente nter r a number number ="); ="); scanf( scanf("%f "%f", ", &x); &x); printf("x= printf("x= %f exp(x)=%f\ exp(x)=%f\n",x, n",x, exp(x)); exp(x)); return return 0; }
16 1. FI FIR RST ST STE EPS TO RU RUN N A C PR PROG OGRA RAM M
You You have to use the -lm option when compiling: $ gcc MyProg MyProgram ram.c .c -lm $ ./a.ou ./a.out t
17
CHAPTER 2
Components of C Language In this chapter, the essential components of the C language are introduced and explained. e syntax covered in this chapter is not n ot exhaustive but after this chapter you should be able to write wr ite a simple C program that can solve many problems in engineering and science.
2.11 2.
VAR ARIA IABL BLES ES AN AND D DATA TYPE TYPES S
Every Every sing single le vari variab able le used used in C must must have have a type type whic whichh the the valu valuee of the the vari variab able le repr repres esen ents ts.. ere ere are four variable types listed in Table 2.1 Table 2.1.. Table T able 2.1: Data 2.1: Data types Type T ype
Content Format Range Example –2147483647 ~ +2147483647 10 Integer int %d ±2.9 ±2 .938 387e 7e – 39 ~ ± 1. 1.70 7014 14e e + 38 3. 3.14 14 Floating number %f float 2 –63 ~ 2+63 3.14159265358979 double Double precision %lf ASCII code ’a’ char Character %c
In Table 2.1 Table 2.1,, the third column shows the format of each data type which is used in the print() and scanf() functions. •
int represents
an integer value. e range of int int depends on the hardware and the version of the compiler. In most modern systems, int represents from -2147483647 to 2147483647.
• float represents a floating number. is will take care of most non-scientific floating numbers (single precision). For scientific and engineering computation, double must be used. • double is an extension of float float. is data type can handle a larger floating number at the expense of the amount of memory used (but not much). • char repr repres esent entss a singl singlee AS ASCII CII chara charact cter er.. is is data data type type is actua actually lly a subse subsett of int int inwhich the range is limited to 0 255. e character represented by char char must be enclosed by a single quotation mark (').
18 2. CO COMP MPON ONEN ENTS TS OF C LA LANG NGUA UAGE GE
2.1. 2. 1.11
CAST CA ST OPE OPERA RATO TORS RS
When an operation o peration between variables of different types t ypes is performed, the variables var iables of a lower type are automatically converted to the highest type following this order: int= int=ch char ar < floa float t < doub double le
For example, for a * b in which a is of int type and b is of float float type, then, a is converted to the float type automatically and the result is also of float float type. ere are times when two variables are both int type yet the result of the operation is desired to be of float float type. For example, #include #include int main() main() { int int a, b; a=3; a=3; b=5; b=5; printf("%f\ printf("%f\n", n", a/b); return return 0; }
e output is $ gcc gcc prog prog.c .c 2.c: 2.c: In functi function on 'main' 'main': : 2.c:6: 2.c:6:10: 10: warnin warning: g: format format '%f' '%f' expect expects s argume argument nt of type type 'doubl 'double', e', but but argu argume ment nt 2 has has type type 'int 'int' ' [-Wf [-Wfor orma mat= t=] ] printf("%f\ printf("%f\n", n", a/b); ^ $ ./a.ou ./a.out t -0.000000
It prin prints ts 0 with with a warn warnin ingg even even thou though gh the the resu result lt is expe expect cted ed to be 0.6. 0.6. To carry carry out out this this oper operat atio ionn as intended,1 a cast operator (an operator to allow to change the type of a variable to a specified type temporarily) must be used as #include #include int main() main() { int a,b; a,b; 1 Another way of achieving this is to modify a/b to 1.0*a/b.
2.1.. VARI 2.1 ARIABL ABLES ES AND DA DAT TA TYPES 19 a=3;b=5; printf("%f\n", (float)a/b); return return 0; }
e output is $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t 0.600000
e (float)a/b part forces both variables to be of float float type and returns 0.6 as expected. 2.1. 2. 1.22
EXAM EX AMPL PLES ES OF DATA TYPE
1. is program prints a character, “ h”. /* Print Print a charac character ter */ #include #include int main() main() { char a='h'; a='h'; printf("%c\n",a); return return 0; }
Note that the variable, a, is declared as char and initialized as “h” on the same line. 2. is program prints an integer 10. /* Print Print an intege integer r */ #include #include int main() main() { int a=10; a=10; printf("%d\n",a);
20 2. CO COMP MPON ONEN ENTS TS OF C LA LANG NGUA UAGE GE return return 0; }
Note that the variable, a, is declared as int and initialized as 10 on the same line. 3. is program prints a floating number 10.5. /* Prin Print t a floa floati ting ng numb number er */ #include #include int main() main() { float a=10.5; a=10.5; printf("%f\n",a); return return 0; }
Note that the variable, a, is declared as float and initialized as 10.5 on the same line. 4. is program prints two floating numbers, 10.0 and -2.3. /* Print Print floati floating ng number numbers s */ #include #include int main() main() { floa float t a, b=9. b=9.0, 0, c; a=10.0; a=10.0; c=-2.3; c=-2.3; printf printf("a ("a = %f\n", %f\n",a); a); printf printf("c ("c = %f\n", %f\n",c); c); return return 0; }
2.22 2.
INPUT UT//OU OUTP TPUT UT
Almost all C programs have at least one output statement. Otherwise, Otherwis e, the program won’t won’t output anything on the screen and there is no knowing if the program ran successfully suc cessfully or not. e most common input/output functions are printf() and scanf() both of which are defined in the header file stdio.h. Use printf() (Print with Format) for outputting data to the console and scanf() (Scan with Format) for inputting i nputting data from f rom the keyboard.
2.2. 2. 2. INP INPUT/ UT/OUT OUTPUT PUT 21
• printf() e syntax of the printf() function is printf("format",argument);
where format is the typesetting of the output that you can control and argument is a list of variables to be printed. e printf() function prints the value(s) of variables in argument to the standard output (screen) following the formatting command defined by format. Examples: printf("Hello, World!\n"); printf printf("T ("Two wo intege integers rs are %d and %d.\n" %d.\n",a, ,a,b); b); printf printf("T ("Two wo floati floating ng number numbers s are %f and %f.\n" %f.\n",a, ,a,b); b); printf printf("T ("Thre hree e floati floating ng number numbers s are %f, %f and %f.\n" %f.\n",a, ,a,b,c b,c); );
A string of characters surrounded by the double quotes (") is printed. However, the percentage sign (%) plus a format letter is automatically replaced by the value of a variable followed. Use %d for an integer, integer, %f for a floating floatin g number, %lf for a double precision number, and %c for a character. e backslash (\) is called the escape character and escapes the following letter. letter. \n represents the next line (inserting a blank line), \t represents a tab character and \a rings the bell. If you want to print the double quotation mark ("), use \". To To print the backslash backsl ash (\) itself, use \\ . • scanf() e scanf() is the inverse of printf() printf(), i.e., it scans the value(s) of variable(s) from the standard input (keyboard) with format. e formatting part (i.e., % …) in scanf() is the same as printf(). However, the variable name must be preceded by an & (ampersand). e reason why an & is required for scanf() but not for printf() will be clarified in Section 2.8 Section 2.8 (pointers). (pointers). Compare the following two programs: #include #include int main() main() { int a, b;
22 2. CO COMP MPON ONEN ENTS TS OF C LA LANG NGUA UAGE GE prin printf tf(" ("En Ente ter r two two inte intege gers rs sepa separa rate ted d by a comm comma a = "); "); scanf("%d, scanf("%d, %d",&a, %d",&a, &b); printf printf("a ("a=%d =%d b=%d\n b=%d\n", ", a, b); return return 0; }
e output is $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t Ente Enter r two two inte intege gers rs sepa separa rate ted d by a comm comma a = 12, 12, 29 a=12 a=12 b=29 b=29
is program expects that two values are entered from f rom the keyboard separated by a comma (,) because of "%d "%d, , %d" %d" in the scanf() function. You have to type the comma ( ,) immediately after the first number. e second number can be entered after as many spaces as you want. #include #include int main() main() { int int a; floa float t b; prin printf tf(" ("En Ente ter r an inte intege ger r and and a real real numb number er sepa separa rate ted d by a spac space e = "); "); scan scanf( f("% "%d d %f", %f",&a &a, , &b); &b); printf printf("a ("a=%d =%d b=%f\n b=%f\n", ", a, b); return return 0; }
e output is $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t Ente Enter r an inte intege ger r and and a real real numb number er sepa separa rate ted d by a spac space e = 21 6.5 6.5 a=21 b=6.500000 b=6.500000
In this program, two numbers must be entered separated by a space. e number of spaces is arbitrary.
2.33 2.
OPER OP ERA ATO TORS RS BE BETWE TWEEN EN VAR ARIA IABL BLES ES
ere are three types of operators among amon g variables. ey are (1) relational operators, operators , (2) logical operators, and (3) increment/decrement operators.
2.3.. OPERA 2.3 OPERATO TORS RS BETW BETWEE EEN N VARI ARIABL ABLES ES 23
2.3.1 REL RELA ATION TIONAL AL OPER OPERA ATOR TORS S
e relational operators are mathematical operators often used in the if statement. It is important to understand the difference between a single equal sign (=) and double equal signs (==) as the single equal sign (=) is used for an assignment while the double equal signs (==) are used as mathematical equality. equality. Table T able 2.2: Relational 2.2: Relational operators Symb Sy mbol ol < <= > >= == !=
Meanin Mean ing g a < b ; a is less than b. a <= b ; a is less than or equal to b. a > b ; a is greater than b. a >= b; a is greater than or equal to b. a = = b ; a is equal to b. a!= b ; a is not equal to b.
Examples
1. if
(a== (a==b) b) prin printf tf(" ("a a and and b are are equa equal. l.\n \n") "); ; else else prin printf tf(" ("a a and and b are are not not equa equal. l.\n \n") "); ;
e statement above means that if the two variables, a and b,arethesame,astring,“ a and b are are equa equal. l.”, is printed, otherwise a string, “a and and b are are not not equa equal. l.”, is printed. printed. Note the difference between one equal sign ( =) and two equal signs (==). One equal sign is for assignment and two equal signs are for logical equality. e double equal signs in C are equivalent to the equal sign in regular mathematical equations. 2. a
= 10; a = a + 1;
e single equal sign in C represents an action to assign the value to the right of the equal sign to the variable to the left of the equal sign. e statement a = a + 1 does not make sense as a mathematical expression. However, it makes perfect sense as a C statement. a + 1 is first evaluated to be 11 and this value of 11 is then assigned to a. Effectively, the value of a a was incremented by 1. 2.3.2 2.3 .2
LOGIC LOG ICAL AL OPE OPERA RATO TORS RS
Logical operators in C are mostly used within the if statement. Examples e following examples are self-explanatory for what they do:
24 2. CO COMP MPON ONEN ENTS TS OF C LA LANG NGUA UAGE GE
Table T able 2.3: Logical 2.3: Logical operators Symb Sy mbol ol
Mean Me anin ing g
&&
And
||
Or
!
Not
if (a>0 (a>0 && a<10 a<100) 0) prin printf tf(" ("a a is betw betwee een n 0 and and 100. 100.\n \n") "); ; if (a>0 (a>0 || a<-5 a<-5) ) prin printf tf(" ("a a is posi positi tive ve or less less than than -5.\ -5.\n" n"); ); int a=20; a=20; if (!(a (!(a== ==10 10)) )) prin printf tf(" ("a a is not not equa equal l to 10." 10."); ); if (a==10 (a==10) ) { prin printf tf(" ("Th The e valu value e of a is 10.\ 10.\n" n"); ); return return 0; } else else .... ....
2.3.3 INCR INCREME EMENT/D NT/DECRE ECREMEN MENT/SUB T/SUBSTITUTION STITUTION OPER OPERA ATOR TORS S
A C statement, a=a+1, means that the value of a a is to be incremented by 1. Five bytes (letters) are used to store a=a+1. As C is the language language for a minimalist, using 5 bytes for incrementing incrementing a variable by 1 seemed to be a waste of memory for the founders of C. Hence, new syntax has been added to shorten this memory allocation. Instead of a = a + 1 , a++ or ++a may be used.2 Table Table 2.4 2.4 lists lists shorthand notations for assignment operations. Examples i=100; i++;
is the same as i=100; i=i+1;
All of the following statements increment i by 1. i=i+1; 2 e naming of C++ follows this, i.e., i.e., an “incremental” improvement improvement over the C language.
2.4.. CONTR 2.4 CONTROL OL ST STA ATEM TEMENT ENTS S
25
Table T able 2.4: Shorthand 2.4: Shorthand notations for assignment operations Symb Sy mbol ol
Mean Me anin ing g
++
b = ++ a b = a ++ b = – – a
– –
b = a – –
+=
a += b
‒ =
a ‒ = b
*=
a *= b
/=
a /= b
%=
a %= b
a is
incremented by 1 and assigned to b. Same as a = a + 1; b = a; a is assigned to b first and incremented by 1. Same as b = a; a = a + 1; a is decremented by 1 and assigned to b. Same as a = a – 1; 1; b = a; a is assigned to b first and decremented by 1. Same as b = a; a = a – 1; 1; a + b is assigned to a. Same as a = a + b; a – b is assigned to a. Same as a = a – b; a * b is assigned to a. Same as a = a * b; a / b is assigned to a. Same as a = a / b; Remainder of a=b is assigned to a. Same as a = a%b;
i+=1; i++; ++i;
e difference between ++i and i++ is that the former pre-increments i before any operation while the latter post-increments i after the operation is done. 2.3.4 2.3 .4
EXER EX ERCIS CISES ES
1. Write a program that interactively reads temperature temperature in Celsius and convert it to Fahrenheit. Note
D .F D 32/ 95 :
C
Expected output: $ ./a.ou ./a.out t Ente Enter r temp temper erat atur ure e in C = 29 It is 84.2 84.2 degr degree ees s in Fahr Fahren enhe heit it. .
2.4
CONTR CO NTROL OL ST STA ATE TEME MENTS NTS
Without control statements, all a program can do is to execute the code f rom the top to the bottom once and for all which is probably not no t much useful. With control statements, a program can branch out to different parts and repeat operations as many times as need be. e following are the five types of control statements that can control the flow of the program:
26 2. CO COMP MPON ONEN ENTS TS OF C LA LANG NGUA UAGE GE
• if
.... .... else else
• for
( ; ; )
• while • do
while while
• switch 2.4.1
IF STATEMENT
A block (a set of statements surrounded surround ed by { and }) following the if statement is executed when the condition inside (: ( : : :) is satisfied. If there is no block, the next statement is executed. else is optional. e following program tells whether an integer entered from the keyboard is between 1 and 100 or not: #include #include int main() main() { int int i; printf printf("E ("Ente nter r an intege integer r = "); scanf("%d",&i); if (i>1 (i>1 && i<10 i<100) 0) printf printf("T ("The he number number is betwee between n 1 and 100.\n 100.\n"); "); else printf printf("T ("The he number number is not in that that range. range.\n" \n"); ); return return 0; }
e output looks like: $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t Ente Enter r an inte intege ger r = 45 The The numb number er is betw betwee een n 1 and and 100. 100. $ ./a.ou ./a.out t Ente Enter r an inte intege ger r = 104 104 The The numb number er is not not in that that rang range. e.
2.4.. CONTR 2.4 CONTROL OL ST STA ATEM TEMENT ENTS S
2.4.2
27
FOR STATEMENT
A for loop is to be used when the number of iterations to be executed is known in advance. e separated by a semicolon semicolon (;). e first part is for loop consists of three parts each of which is separated initialization of a counter variable, the second part is a test of the iteration counter variable and if this test fails, the loop is finished. e third part defines an action on the counter variable. A block can be followed after the for statement to execute multiple statements for each iteration. for (initi (initial al value; value; condit condition ion ; counte counter r increm increment ent) ) statem statement ent; ;
Examples
1. e following program prints 0–9. #include #include int main() main() { int int i; for (i=0; (i=0; i< 10; i++) i++) printf printf("i ("i=%d =%d\n" \n",i) ,i); ; return return 0; }
e output is $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t i=0 i=1 i=2 i=3 i=4 i=5 i=6 i=7 i=8 i=9
2. e following program computes S
D 1 C 2 C 3 C 4 C 5 C 6 C : : : C 100: D
28 2. CO COMP MPON ONEN ENTS TS OF C LA LANG NGUA UAGE GE #include #include int main() main() { int i, sum = 0; for for (i=0 (i=0; ; i<= i<= 100; 100; i++) i++) sum sum = sum printf printf("S ("Sum um = %d\n", %d\n", sum); sum); return return 0; }
+ i;
e output is $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t Sum Sum = 5050 5050
In this this progra program, m, i isacountervariableand sum isaplaceholderforthesum.eparameters in the for statement mean that the counter variable, i, is reset to be 0 first and as long as i is less than or equal to 100, the sum = sum + 1 statement is repeated. Upon each execution of sum = sum + 1 , i is incremented by 1. In the sum = sum + 1 statement, the previous value of sum sum is incremented by 1 at each iteration and the newly incremented value of sum+1 sum+1 replaces the previous value of sum sum . e following pattern can c an compute mathematical summation: sum sum = 0.0; 0.0; for for (i=0 (i=0; ; i<= i<= 100; 100; i++) i++) sum sum = sum sum + f(i) f(i); ;
for
100
X i
f.i/
D0
D f.0/ C f.1/ C f.2/ C : : : C f .100/: .100/:
Note: e iteration variables (i, j , k , : : :) must be always declared as int . 3. Approximating ln l n 2 It is known that3 1
21 C 31 41 C 51 : : : D ln 2:
3 Integrating the both sides of the geometric series,
1
1
2
3
4
5
C x D 1 x C x x C x x C : : :
(2.1)
2.4.. CONTR 2.4 CONTROL OL ST STA ATEM TEMENT ENTS S
29
erefore, by numerically summing up the left-hand lef t-hand side of Eq. (2.1 (2.1), ), one can obtain a numerical value of ln 2.D 0:693147:::/ . Equation (2.1 (2.1)) can be written as 1 .1/i C1 D ln 2: (2.2) i i D1 To To implement the left-hand lef t-hand side of Eq. (2.2 2.2)) in C, use the following statement:
X
sum sum = sum sum + pow( pow(-1 -1, , i+1) i+1)/i /i; ;
Note that pow(a,b) is a function found in which returns ab . A program to implement Eq. (2.1 (2.1)) should look like: #include #include #include #include int main() main() { int i,n; i,n; float sum=0.0; sum=0.0; printf printf("E ("Ente nter r # of iterat iteration ions s = "); scanf("%d" scanf("%d", , &n); for (i=1;i
e output is $ gcc gcc prog prog.c .c -lm -lm $ ./a.ou ./a.out t
one can obtain 2
ln .1
3
4
5
6
C x/ D x x2 C x3 x4 C x5 x6 C : : :
Substituting x D 1 on both sides yields ln 2
D 1 12 C 13 14 C 15 : : :
30 2. CO COMP MPON ONEN ENTS TS OF C LA LANG NGUA UAGE GE Ente Enter r # of iter iterat atio ions ns = Approx Approxima imatio tion n of ln(2)= ln(2)= $ ./a.ou ./a.out t Ente Enter r # of iter iterat atio ions ns = Approx Approxima imatio tion n of ln(2)= ln(2)= $ ./a.ou ./a.out t Ente Enter r # of iter iterat atio ions ns = Approx Approxima imatio tion n of ln(2)= ln(2)=
1000 1000 0.6936 0.693646. 46. Exact Exact value value of ln(2)= ln(2)= 0.6931 0.693147. 47. 1000 10000 0 0.6931 0.693191. 91. Exact Exact value value of ln(2)= ln(2)= 0.6931 0.693147. 47. 1000 100000 0000 00 0.6931 0.693137. 37. Exact Exact value value of ln(2)= ln(2)= 0.6931 0.693147. 47.
As is seen from the output above, the convergence of the series is rather slow. Also note that for today’s computers, iterations for 10,000,000 times pose no problem whatsoever. 4. We want to find one of the roots of a cubic equation defined by x3
C x 1 D 0;
(2.3)
which is between 0 and 1 by an iterative method. Modify Modi fy Eq. (2.3 (2.3)) to be read as x
D 1 C1 x2 :
(2.4)
Although Eqs. (2.3 (2.3)) and (2.4 (2.4)) are mathematically equivalent, Eq. (2.3 (2.3)) cannot be used as a valid C statement while Eq. (2.4 ( 2.4)) can be used as a valid C statement where the evaluated 1 value of 1Cx is is assig assigne nedd to x . Starti Starting ng with with appr approp opria riate te initi initial al gues guesss for x ,Eq.(2.4 ,Eq.(2.4)canbe )canbe iterated until convergence is attained. e following program uses x D 1 as initial guess: 2
#include #include int main() main() { int i,n; i,n; float x=1.0; printf printf("E ("Ente nter r # of iterat iteration ions s = "); scanf("%d", scanf("%d", &n); for (i=1;i (i=1;i
e output is
2.4.. CONTR 2.4 CONTROL OL ST STA ATEM TEMENT ENTS S
31
$ gcc gcc prog prog.c .c $ ./a.ou ./a.out t Ente Enter r # of iter iterat atio ions ns = 30 Iteration Iteration #=30, x=0.682327 x=0.682327. . $ ./a.ou ./a.out t Ente Enter r # of iter iterat atio ions ns = 31 Iteration Iteration #=31, x=0.682328 x=0.682328. . $ ./a.ou ./a.out t Ente Enter r # of iter iterat atio ions ns = 32 Iteration Iteration #=32, x=0.682328 x=0.682328. .
It is seen that the convergence was attained after 31 iterations. Although the convergence with this thi s iteration i teration method m ethod is i s slow s low,, there is no need to use us e any advanced mathematics to solve this cubic equation. 2.4.3
WHILE STATEMENT
A while statement executes the statement(s) that follows while the condition is true. Note that the following program outputs 10: #include #include int main() main() { int i=0; i=0; while while (i<10) (i<10) i++; i++; printf("%d\n",i); return return 0; }
e output is $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t 10
It appears that the program should output 9, not 10. However, in the test i<10 when i=9 , i is incremented to 10 and this value is held thereafter. For multiple statements, it is necessary to use a block with curly brackets ( { and } ).
32 2. CO COMP MPON ONEN ENTS TS OF C LA LANG NGUA UAGE GE #include #include int main() main() { int i=0; i=0; while (i<10) (i<10) {i++; printf printf("i ("i = %d\n", %d\n",i); i); } printf("%d\n",i); return return 0; }
e output is $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t i = 1 i = 2 i = 3 i = 4 i = 5 i = 6 i = 7 i = 8 i = 9 i = 10 10
2.4.4
DO WHI WHILE LE STATEMENT
e do while while loop is similar to the while loop except that the test occurs at the end of the loop body. is guarantees that the loop is executed at least once before continuing. Such a setup is frequently used where data is to be read. e loop is used to re-read the data if the first set was unacceptable. e following program keeps prompting until the user enters 0 or 1: #include #include int main() main() {
2.4.. CONTR 2.4 CONTROL OL ST STA ATEM TEMENT ENTS S
33
int input_valu input_value; e; do { prin printf tf(" ("En Ente ter r 1 for for yes, yes, 0 for for no :"); :"); scanf("%d", scanf("%d", &input_val &input_value); ue); } whil while e (inp (input ut_v _val alue ue != 1 && inpu input_ t_va valu lue e != 0); 0); return return 0; }
e output is $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t Ente Enter r 1 for yes, yes, 0 Enter 1 for yes, 0 Ente Enter r 1 for yes, yes, 0 Enter 1 for yes, 0
2.4.5
for for for for for for
no no no no
:10 :2 :-1 :0
SWITCH STATEMENT
A switch statement can branch out to different tasks depending on the value of the variable used. You can achieve the same result using multiple if statements but using switch simplifies the program flow. flow. e following program checks to see if the value entered is either 1 or 2 and prints “a is neit neithe her r 1 nor nor 2.” if otherwise: #include #include int main() main() { int int i; printf("En printf("Enter ter an integer="); integer="); scanf("%d" scanf("%d", , &i); switch(i) { case case 1: printf printf("a ("a is 1\n"); 1\n");bre break; ak; case case 2: printf printf("a ("a is 2\n"); 2\n");bre break; ak; defaul default: t: printf printf("a ("a is neithe neither r 1 nor 2\n"); 2\n");bre break; ak; } return return 0; }
e output is
34 2. CO COMP MPON ONEN ENTS TS OF C LA LANG NGUA UAGE GE $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t Enter Enter an intege integer=1 r=12 2 a is neither 1 nor 2 $ ./a.ou ./a.out t Enter Enter an intege integer=2 r=2 a is 2
It is important to use a break statement to break out from the block for each statement executed. Note that a colon (:) must be used instead of a semicolon (;) after case.
2.4.6 2.4 .6
MISCE MI SCELL LLANE ANEOUS OUS RE REMAR MARKS KS
ere are several remarks in C and UNIX that do not warrant separate sections but are nevertheless worth commenting. ey are summarized here.
• Exit from an infinite infinite loop. loop.
From time to time, the program you wrote may be trapped in an infinite loop and nothing can be done except for closing the window or shutting down the machine. machine. For instance, the following program generates an infinite loop:
#include #include int main() main() { int int i; for (i=1; (i=1; i>0; i>0; i++) i++) printf printf("l ("loop oop"); "); return return 0; }
2.4.. CONTR 2.4 CONTROL OL ST STA ATEM TEMENT ENTS S
35
To To exit from f rom the infinite loop, enter control-C.4 • Output formatting It is possible to modify the appearance of the output from the printf() function. Study the following format control codes used in the printf() statement: #include #include int main() main() { float a=3.14; a=3.14; printf("%f\n",a); printf("%10f\n",a); printf("%20f\n",a); printf("%30f\n",a); printf("%10.3f\n",a); printf("%10.4f\n",a); printf("%10.5f\n",a); printf("%10.6f\n",a); return return 0; } 4 Hold down the control key and press C. Also if the screen is suddenly frozen and does not accept any keyboard input, try
control-Q. is is usually caused by accidentally entering control-S (for pausing output).
36 2. CO COMP MPON ONEN ENTS TS OF C LA LANG NGUA UAGE GE
e output is $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t 3.140000 3.140000 3.140000 3.140000 3.140 3.1400 3.14000 3.140000
e format, %10.6f means that 10 spaces from the beginning of the line are reserved and the float variable is printed with 6 decimal places right justified. is formatting option is purely cosmetic and does not change the actual value of the variable. • What is a=b=20 ? A statement such as a=b=20 looks strange but it is an acceptable C statement. Try running the following code: #include #include int main() main() { floa float t a, b; printf("%f\n printf("%f\n", ", a=20.0); a=20.0); b=a=30.0; printf("%d\n printf("%d\n", ", a==20.0); a==20.0); return return 0; }
e output is $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t 20.000000 0
2.4.. CONTR 2.4 CONTROL OL ST STA ATEM TEMENT ENTS S
37
In the statement, a=b=20, the control goes toward the end of the line. Hence, b=20 is first executed in which b is assigned 20 but also the statement, b=20, itself is assigned the same value (20) which is subsequently assigned to a . is way, one can assign 20 to both a and b at the same time. In the program above, after b=a=30.0, the value of a a is 30. erefore, a==20.0 is false and hence the printf() function returns 0 (false). • In gcc, you can use the -o5 option to specify the name of the executable file instead of a.out. $ gcc MyProg MyProgram ram.c .c -o MyProg MyProgram ram
is generates an executable binary, MyProgram, instead of the default file, a.out, in the same directory. For the Windows version of gcc, the name of the executable is MyProgram.exe. • You can define a symbolic constant by the define preprocessor: #include #include #def #defin ine e PI 3.14 3.1415 1592 92 /* Defi Define nes s pi. pi. */ int main() main() { float float a; printf printf("E ("Ente nter r radius radius = "); scanf("%f" scanf("%f", , &a); printf printf("T ("The he area area of circle circle is=%f. is=%f.\n" \n", , a*a*PI a*a*PI); ); return return 0; }
e output is $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t Ente Enter r radi radius us = 2.0 2.0 The area area of circle circle is=12. is=12.566 566368 368. .
Whenever the C compiler encounters PI, the compiler replaces PI by 3.141592. It is customary to use upper case letters to define constants with the #define preprocessor. preprocessor. 5 o for output.
38 2. CO COMP MPON ONEN ENTS TS OF C LA LANG NGUA UAGE GE
• Why does the retu return rn 0; in int int main() main() have to return 0? Returning 0 is not absolutely necessary necessar y. In fact, retu return rn -1; or return return 2019; works just fine. However, by returning 0 to the operating system when int int main() main() exits, the operating system knows that the process finished normally and continues to run accordingly. It does the operating system a favor by telling the operating system that it does not have to bother to do anything special. 2.4.7 2.4 .7
EXER EX ERCIS CISES ES
1. Write Write a C program that interactively interactively reads the three coefficients of a quadratic quadratic equation and compute the two roots. e program must alert if there is no real root. e quadratic equation is given by ax 2
and the two roots are expressed as
C bx C c D 0;
b ˙ xD
p 2 b
2a
4ac :
Note: sqrt is available in . You need to compile the program with the -lm option, i.e., $ gcc MyProg MyProgram ram.c .c -lm
2. Write a C program to numerically compute the following series: 1
31 C 51 71 C 91 ;
As this series is known to be convergent to =4 ,6 approximate using the program. Vary iteration numbers. Note that the general term, an, is expressed as .1/nC1 an
D
6 Start with the geometric series of
1
1
Integrate both sides to get
2n
1 ;
n
2
4
3
5
D 1;2;3:::
6
8
C x D 1 x C x x C x : : : 2
7
9
arctan x
D x x3 C x5 x7 C x9 : : :
arctan 1
D 4 D 1 13 C 15 17 C 19 : : :
Substitute x D 1 in the above to get
2.5. 2. 5. FUN FUNCT CTIO IONS NS 39
2.55 2.
FUN FU NCTI TIO ONS
2.5. 2. 5.11
DEFI DE FINI NITI TION ON OF FUN FUNCT CTIO IONS NS IN C
e concept of functions in C is important as after all a C program is defined as a set of functions. You You have already seen an example of C function, main(), which is always executed first. at is the only special property with main(), which means that any function in C must follow the same syntax as main(), i.e., declaration of the type ( int for main()), argument(s) within the parentheses (leave it blank if none), all the statements within { and } , and return return value as the last line in main(). If the function does not need any return value, use void as the type of return value. Examples
1. e following program shows an example of the type, void. All the user-defined function, write(),7 does is to print “Hello World! ” and it does not return any value upon exit. erefore, it has to be declared dec lared as void. #include #include void write() write() { printf("Hello, World!\n"); } int main() main() { write(); return return 0; }
e output is $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t Hello, Hello, World! World!
As the function, write(), does not have any parameter to pass, it has to be called without any argument as write() in the main function. 2. e following program defines a function, cube(), which returns the cube of a parameter, x: 7 Surprisingly, C does have a built-in
function called write().
40 2. CO COMP MPON ONEN ENTS TS OF C LA LANG NGUA UAGE GE #include #include float float cube(f cube(floa loat t x) { return x*x*x; } int main() main() { float float x; printf printf("E ("Ente nter r x = "); scanf( scanf("%f "%f",& ",&x); x); printf printf("T ("The he cube cube of x is %f.\n" %f.\n", , cube(x cube(x)); )); return return 0; }
e output is $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t Enter x = 3 The The cube cube of x is 27.0 27.000 0000 000. 0.
Upon exit, cube(x) returns x 3 with x as the argument passed from the main function. 3. e following program computes x y (x to the power of y )8 using its own function, power(), instead of the pow()9 function available in : #include #include #include #include float float power( power(flo float at x, float float y) { return exp(y*log(x) exp(y*log(x)); ); } int main() main() { float float x,y; x,y; prin printf tf(" ("En Ente ter r x and and y sepa separa rate ted d by spac space e ="); ="); scanf("%f scanf("%f %f",&x,&y); %f",&x,&y); 8 If z z x y , taking the natural logarithm of both 9 pow(x,y) in returns x y .
D
sides yields ln z
D ln x D y ln x . Hence, z D e y
y ln x
.
2.5. 2. 5. FUN FUNCT CTIO IONS NS 41 if (x<0) (x<0) { printf printf("x ("x must must be positi positive ve !!\n") !!\n"); ; return return 0; } prin printf tf(" ("%f %f to powe power r of expo expone nent nt %f is %f.\ %f.\n" n", , x, y, powe power( r(x, x,y) y)); ); return return 0; }
e output is $ gcc gcc prog prog.c .c -lm -lm $ ./a.ou ./a.out t Ente Enter r x and and y sepa separa rate ted d by spac space e =2 4 2.0000 2.000000 00 to power power of expone exponent nt 4.0000 4.000000 00 is 16.000 16.000000 000. . $ ./a.ou ./a.out t Ente Enter r x and and y sepa separa rate ted d by spac space e =-2 =-2 4 x must must be posi positi tive ve !! x is negative. Otherwise, it computes x y and prints its value. e program exits if x
2.5. 2. 5.22
LOCA LO CALI LITY TY OF VAR ARIA IABL BLES ES WI WITHI THIN N A FUN FUNCT CTIO ION N
Variablesusedwithinafunctionare local,i.e.,theydonotretainthevaluesoutsidethefunction. In the following program, the variable name, sum, is used for both f() and main() yet sum used within f() does not propagate outside the function f() . #include #include int int f(in f(int t n) { int i,sum=0; i,sum=0; for (i=1;i (i=1;i<= <= n;i++) n;i++) sum=su sum=sum+i m+i; ; return return sum; sum; } int main() main() { int int i, sum= sum=0; 0; for (i=1;i (i=1;i <= 10;i++ 10;i++) ) sum=su sum=sum+i m+i*i; *i; printf printf("% ("%d d %d\n", %d\n", sum, sum, f(10)) f(10)); ;
42 2. CO COMP MPON ONEN ENTS TS OF C LA LANG NGUA UAGE GE return return 0; }
e output is $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t 385 385 55
e printed value of sum sum is the sum defined in main() even though a variable of the same name is returned in the function, f() . 2.5. 2. 5.33
RECU RE CURS RSIV IVITY ITY OF FUN FUNCT CTIO IONS NS
C functions can be used and defined recursively, which means that a C function can call its own within the function.10 Using the recursive algorithm, a program can be written compactly and efficiently. Examples
1. Fibonacci numbers e Fibonacci numbers, a n, are defined as
D 1; a2 D 1: (2.5) With a1 D 1; a2 D 1, a3 can be comp comput uted ed as a3 D a2 C a1 D 1 C 1 D 2. Similarly Similarly,, a4 can be computed as a 4 D a3 C a2 D 2 C 1 D 3. is way, starting with a 1 and a 2 , a n for any an
D an1 C an2;
a1
n can be computed by repeatedly applying Eq. (2.5 number of n ( 2.5).).11 As C functions can be defined recursively recursivel y, coding the Fibonacci number is straightforward straightfor ward as in the program below:
#include #include int fibo(i fibo(int nt n) { if (n== (n==1) 1) retu return rn 1; if (n== (n==2) 2) retu return rn 1; return return fibo(n fibo(n-1) -1) + fibo(n fibo(n-2) -2); ; } 10 In old languages such as FORTRAN, recursivity is not supported. 11 ere is an interesting background story with this number. See www.maths.surrey.ac.uk/hosted-sites/R.Knott/Fi bonacci/fibnat.html#Rabbits.
2.5. 2. 5. FUN FUNCT CTIO IONS NS 43 int main() main() { int int i; printf printf("E ("Ente nter r n = "); scanf( scanf("%d "%d", ", &i); &i); printf("%d\n", fibo(i)); return return 0; }
e output looks like $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t Enter n = 12 144
e program simply copies Eq. (2.5 (2.5)) to the definition of fibo() fibo().12 2. Compute 1 C 2 C 3 C 4 C : : : C n using the recursive algorithm. If we define sum.n/ sum.n/
the following relation holds: sum.n/ sum.n/
1 C 2 C 3 C 4 C : : : C n;
D sum.n sum.n 1/ C n;
sum.0/ sum.0/
D 0:
Using this recursive property, the following program can compute 1
C 2 C 3 C ::: C n
without using the for statement. #include #include int sum_of_inte sum_of_integers( gers(int int n) { if (n== (n==0) 0) retu return rn 0; return return n + sum_of_inte sum_of_integers( gers(n-1); n-1); 12 e explicit formula of the Fibonacci Fibonacci sequence is given given by
an
D
C p p 1 2
1
5
n
p 5
1 2
1
5
n
:
44 2. CO COMP MPON ONEN ENTS TS OF C LA LANG NGUA UAGE GE } int main() main() { int int n; prin printf tf(" ("En Ente ter r n = "); "); scanf("%d", scanf("%d", &n); printf("1+2+ printf("1+2+....+ ....+%d %d =%d \n", n, sum_of_inte sum_of_integers( gers(n)); n)); return return 0; }
e output is $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t Ente Enter r n = 100 100 1+2+....+10 1+2+....+100 0 =5050
2.5. 2. 5.44
RAND RA NDOM OM NU NUMB MBER ERS, S, RAND()
Random numbers can be generated by using rand() in to perform numerical simulations of various experiments that are hard to carry out otherwise. e following program prints random numbers 10 times: #include #include #include #include int main() main() { int int i; for for (i=0 (i=0; ; i < 10; 10; i++) i++) prin printf tf(" ("%d %d\n \n", ", rand() rand()); ); printf("\nMA printf("\nMAX X = %d\n", %d\n", RAND_MAX); RAND_MAX); return return 0; }
e output is $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t 1804289383 846930886
2.5. 2. 5. FUN FUNCT CTIO IONS NS 45 1681692777 1714636915 1957747793 424238335 719885386 1649760492 596516649 1189641421 MAX = 214748 214748364 3647 7
e function, rand(), returns an integer between 0 and RAND_MAX (system dependent)13 which is defined in the header file, .14 If floating random numbers between 0 and 1.0 are desired instead of between 0 and RAND_MAX, the following program is used: #include #include #include #include int main() main() { int int i; for (i=0; i< 10; i++) return return 0; }
printf printf("% ("%f\n f\n", ", 1.0*ra 1.0*rand( nd()/R )/RAND AND_MA _MAX); X);
e output is $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t 0.840188 0.394383 0.783099 0.798440 0.911647 0.197551 0.335223 0.768230 13 2147483647 for most systems. It is the maximum integer value handled 14 stdlib = standard library. librar y.
by the system.
46 2. CO COMP MPON ONEN ENTS TS OF C LA LANG NGUA UAGE GE 0.277775 0.553970
Note the %f format and the factor of 1.0. e value of rand()/RAND_MAX rand()/RAND_MAX alone returns 0 as both rand() and RAND_MAX are integers and the result is a truncated integer. However, the same numbers are output again and again each time the program is run. ey are all predictive and not random numbers. In order to generate a different sequence of random numbers each time the program is run, srand()15 available in must be used in conjunction with rand(). e srand() function sets its argument as the seed for a new sequence of pseudo-random integers to be returned by rand() rand(). ese sequences are repeatable by calling srand() with the same seed value. If no seed value is provided, the rand() function is automatically seeded with a value of 1. #include #include #include #include int main() main() { int int i; printf printf("E ("Ente nter r seed seed intege integer r = "); scanf("%d", scanf("%d", &i); srand(i); printf("%d\n printf("%d\n", ", rand()); rand()); return return 0; }
e output looks like $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t Ente Enter r seed seed inte intege ger r = 10 1215069295
In the program above, srand(i) takes a seed number i and generates a random number based on the value of i i . e problem with this approach is that if the same seed number is given, the rand() function returns the same value. Using the time() function defined in , you can generate a different seed number every time. e function, time(), with the argument NULL returns the elapsed time since 00:00:00 GMT, GMT, January Januar y 1, 1970, 16 measured in seconds. 15 srand = seed random. 16 is is the birthday of UNIX!
2.5. 2. 5. FUN FUNCT CTIO IONS NS 47 #include #include #include #include int main() main() { int int i; printf("%d\n", time(NULL)); return return 0; }
e output is $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t 1344034011
At the time of writing, 1,344,034,011 seconds have passed since 1/1/1960. As this value keeps increasing, it can be used as a seed number for srand(). e following program generates a different random number every time it is called.17 #include #include #include #include #include #include int main() main() { srand(time(NULL)); printf("%d printf("%d\n", \n", rand()); rand()); return return 0; }
e output may look like $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t 1819029242 (Wait (Wait a few second seconds.) s.) $ ./a.ou ./a.out t 1672748932 17 If the program is run twice within 1
second, the same random number is generated.
48 2. CO COMP MPON ONEN ENTS TS OF C LA LANG NGUA UAGE GE
Genera Gen eratin tingg Ran Random dom Num Number berss in Vario arious us Ran Ranges ges
With an integer number generated by rand() rand() and MAX_RAND, it is possible to convert this number ber to any any rang range, e, be it an inte intege gerr rang rangee or a flo float at numb number er rang range. e. e foll follow owin ingg list list show showss exam exampl ples es of various ranges generated by rand() rand(): 1. rand() returns an integer between 0 and RAND_MAX. 2. 1.0*rand()/RAND_MAX returns a floating number between 0 and 1. 3. 5.0*rand()/RAND_MAX returns a floating number between 0 and 5. 4. 10.0*rand()/RAND_MAX-5 returns a floating number between 5 and 5 . 5. rand()%718 returns an integer of 0, 1, 2, 3, 4, 5, or 6. 6. rand()%7+10 returns an integer of 10, 11, 12, 13, 14, 15, or 16. Using Us ing Ran Random dom Num Number berss to do Sim Simula ulatio tions ns (Mo (Monte nte Carl Carlo o Met Method hod))
Using random numbers to conduct numerical simulations is called the Monte Carlo method.19 As an example, consider the following integral:
Z p 1
1
x 2 dx
0
D 4 :
is integration represents the shaded area in i n Figure 2.1 Figure 2.1.. As it is a quarter of the whole unit y
1
y 0
=
1 – x
1
Figure 2.1: Monte 2.1: Monte Carlo method for numerical integration. 18 a%b returns the remainder of a/b a/b . 19 Monte Carlo is a city in Monaco where one of the major businesses is casinos.
2
x
2.5. 2. 5. FUN FUNCT CTIO IONS NS 49 =4.20 circle, its area is =4 Instead of carrying out the integral directly, the Monte Carlo method can be used to appr approx oxima imate te this this area area.. Henc Hence, e, an appr approx oxima imate te valu valuee of can can be obta obtain ined ed.. To see see ho how w this this wo work rks, s, a pair of two random numbers, x and y , whose range is between 0 and 1, can be identified as a point, .x; Figure 2.1.. If .x; .x; y/, inside the square defined by f.x;y/;0 x 1; 0 y 1g in Figure 2.1 .x; y/ 2 2 satisfies x C y < 1, the point, .x; .x; y/, is inside the shaded area. If not, .x; .x; y/ is outside the shaded area. Now, Now, generate a pair of two random numbers between between 0 and 1 for N times. For each each roun round, d, if x satisfie fied, d, incre increme ment nt the the count counter er i by 1. If not, go to the next round. nd. x 2 C y 2 < 1 is satis At the end of N square. N rounds, the value of i=N i =N should be proportional to the shaded area/the square. i =N is As N increases, it is expected that the ratio of i=N is close to 4 =1. is can be implemented by the following C program: #include #include #include #include #include #include #include #include #defin #define e PI 3.1415 3.141592 92 int main() main() { floa float t x, y; int i, count= count=0; 0; int int n; printf("En printf("Enter ter iteration iteration number = ");scanf("% ");scanf("%d", d", &n); srand(time(NULL)); for for (i=0 (i=0; ; i< n; i++) i++) { x=1.0*rand()/RAND_MAX; y=1.0*rand()/RAND_MAX; if (x*x+y (x*x+y*y *y < 1.0) 1.0) count= count=cou count+ nt+1; 1; } printf printf("T ("True rue value value = %f\n", %f\n", PI/4); PI/4); printf printf("A ("Appx ppx value value = %f\n", %f\n", 1.0*co 1.0*count unt/n) /n); ; return return 0; }
e output looks like 20 Mathematically, Mathematically, one can integrate the t he function directly as
Z p 1
1
0
x 2 dx
p D 1 2
1
1
x2
x
1
C sin
.x/
D 0
: 4
50 2. CO COMP MPON ONEN ENTS TS OF C LA LANG NGUA UAGE GE $ gcc gcc prog prog.c .c -lm -lm $ ./a.ou ./a.out t Enter Enter iterat iteration ion number number = 100 True True value value = 0.7853 0.785398 98 Appx Appx value value = 0.7900 0.790000 00 $ ./a.ou ./a.out t Enter Enter iterat iteration ion number number = 1000 1000 True True value value = 0.7853 0.785398 98 Appx Appx value value = 0.8140 0.814000 00 $ ./a.ou ./a.out t Enter Enter iterat iteration ion number number = 100000 100000 True True value value = 0.7853 0.785398 98 Appx Appx value value = 0.7874 0.787400 00
As is seen in the output above, the convergence by the Monte Carlo method is at best mediocre and should be used only as the last resort for 1D integrals. However, the Monte Carlo method is a quick way to approximate 2D and higher-dimensional integrals. 2.5.5 2.5 .5
EXER EX ERCIS CISES ES
1. A sequence an is given with the following rule: anC2
D 2anC1 C 3an;
Write a C program to compute a17 .
a0
D 2;
a1
D 1:
n , i.e., 2. (a) Write Write a functio function, n, int int factor factorial ial(in (int t n), which returns nŠ (the factorial of n 1 2 3 : : : n) using the recursive algorithm. (b) Using int factor factorial ial(in (int t n) above, write a program to compute 1
1 C 1Š1 C 2Š1 C : : : C 11Š :
3. Using the Monte Carlo method, integrate 1
Z 0
1
1
dx ; C x2 dx;
numerically. Vary the number of iterations (10, 100, 1,000) and estimate an appropriate number of iterations to obtain good accuracy. Note: e exact value of the above integra =4 so this can be also used to approximate the value of . tion is =4 4. Using the Monte Carlo method, estimate the volume of the unit sphere x2
C y 2 C z2 1:
2.5. 2. 5. FUN FUNCT CTIO IONS NS 51
5. Using the Taylor series for cos.x/ expressed as cos .x/
D1
x2 2Š
C
x4 4Š
x6 6Š
C :::
(2.6)
create your own cos .x/ and demonstrate your program by making a table which may look like the one shown in Table 2.5 Table 2.5,, where mycos(x) is from your program and cos .x/ is the math function defined in . Table T able 2.5: cos.x/ table mycos( x )
cox( x )
0.0
1.000
1.000
0.1
1.101
1.105
0.2
1.308
1.221
…
…
…
1.0
1.69
1.781
x
Note:
(a) e values above are false. (b) Equation (2.6 (2.6)) can be written as cos.x/
1 X D i
D0
. 1/i x 2i : .2i/Š
(c) Take the first 10 terms for the series. Template: Template: #include #include #include #include int factor factorial ial(in (int t n) { (your (your code code here) here) } float float mycos( mycos(flo float at x) { floa float t sum= sum=0; 0; int int i; for for (i=0 (i=0;i ;i<= <=10 10;i ;i++ ++) ) sum sum = sum sum + (you (your r code code here here); );
52 2. CO COMP MPON ONEN ENTS TS OF C LA LANG NGUA UAGE GE return return sum; sum; } int main() main() { float float ...; ...; int int i=1; i=1; /* coun counte ter r */ (for i=1;i< i=1;i< .......) .......) printf..... printf....... .. return return 0; }
2.6
ARRAYS
Vectors and matrices in linear algebra can be implemented in C as arrays. An array in C can represent many elements by a single variable name. is section explains the basic concept of arrays. Arrays are closely related to pointers in C which will be further explained in Section 2.8 Section 2.8.. 2.6. 2. 6.11
DEFI DE FINI NITI TION ON OF AR ARRA RAYS YS
An array is a variable which can represent represent multiple elements elements such as numbers and characters. characters. An array can be declared just like other variables as #include #include int main() main() { float float a[3]; a[3]; a[0]=1.0; a[0]=1.0; a[1]=2.0; a[1]=2.0; a[2]=5.0; a[2]=5.0; (.......) return return 0; }
e program above defines an array, array, a, which represents three elements. e values, 1.0, 2.0, and 5.0, are assigned to the first element, the second element and the third element of a a, respectively. Note that the index in arrays begins with 0 rather than 1 and ends with n 1 where n is the number of elements. is poses a little confusion when arrays are used to represent matrices or vectors in linear algebra as the index in dex in linear algebra begins at 1 so care must be taken when manipulating vector/matrix indices. You can initialize arrays at the same time they are declared as
2.6. 2. 6. AR ARRA RAYS YS 53 #include #include int main() main() { float float a[3]={ a[3]={1.0 1.0, , 2.0, 2.0, 3.0}; 3.0}; (......) return return 0; }
or simply, #include #include int main() main() { float float a[]={1 a[]={1.0, .0, 2.0, 2.0, 3.0}; 3.0}; (......) return return 0; }
i.e., if an array is initialized, its dimension can be omitted as the number of elements is automatically determined. e following program computes the sum of all the numbers in an array: #include #include #def #defin ine e N 5 int main() main() { int int i; float float a[N]={ a[N]={2.0 2.0, , -15.0, -15.0, 12.0, 12.0, -5.4, -5.4, 1.9}; 1.9}; float sum=0.0; sum=0.0; for for (i=0 (i=0;i ;i
e output is $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t The The sum sum is = -4.5 -4.500 0000 000. 0.
54 2. CO COMP MPON ONEN ENTS TS OF C LA LANG NGUA UAGE GE
2.6.2 MUL MULTI-DI TI-DIMEN MENSION SIONAL AL ARRA ARRAYS YS
Arrays can be nested, i.e., they can take more than 1 indices. Nested arrays (multi-dimensional arrays) can represent matrices in linear algebra. For example, the components of a 2 5 matrix, a, can be represented in C as
aD
aŒ0 aŒ0Œ0 Œ0 aŒ1 aŒ1Œ0 Œ0
aŒ0 aŒ0Œ1 Œ1 aŒ1 aŒ1Œ1 Œ1
aŒ0 aŒ0Œ2 Œ2 aŒ1 aŒ1Œ2 Œ2
aŒ0 aŒ0Œ3 Œ3 aŒ1 aŒ1Œ3 Œ3
aŒ0 aŒ0Œ4 Œ4 aŒ1 aŒ1Œ4 Œ4
:
Note that the index begins with 0, not 1. e following program defines a 2 5 matrix, mat, given as
mat D
1:0; 6:0;
2:0 2:0; 7:0;
3:0; 8:0;
4:0 4:0; 9:0;
5:0 10:0
;
and prints all the elements using double indices, i and j . #include #include #def #defin ine e COL COL 5 #def #defin ine e ROW ROW 2 int main() main() { int i,j; i,j; float float mat[RO mat[ROW][ W][COL COL]={ ]={{1. {1.0 0 ,2.0 ,2.0 ,3.0, ,3.0, 4.0 ,5.0}, ,5.0},{6. {6.0, 0, 7.0, 7.0, 8.0, 8.0, 9.0, 9.0, 10.0}} 10.0}}; ; for (i=0;i
e output is $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t 1.000000 1.000000 2.000000 2.000000 3.000000 3.000000 4.000000 4.000000 5.000000 5.000000 6.000000 6.000000 7.000000 7.000000 8.000000 8.000000 9.000000 9.000000 10.000000 10.000000
2.6. 2. 6. AR ARRA RAYS YS 55
2.6. 2. 6.33
EXAM EX AMPL PLES ES
1. Standard Standard deviation deviation and variance e average of a sequence, fx1 ; x2 ; x3 ; : : : xn g, is the arithmetic average of the components defined as
N
X
1 N
N
X
xi :
D1 e variance of the same sequence is defined as sx2
i
N
1
N 1
X i
.xi
D1
XN /2:
(2.7)
Note the factor, N 1, instead of N in Eq. (2.7 (2.7).). is is a mathematical mathematical necessity. necessity. e x i , is defined as standard deviation, sx , having the dimension of x sx
v ut X N
1
N
1
i
D1
.xi
XN /2:
e following program program computes the average and the standard deviation of 10 data points: #include #include #include #include #def #defin ine e N 10 int main() main() { float a[N]={0.97 a[N]={0.974742, 4742, 0.0982212, 0.0982212, 0.578671, 0.578671, 0.717988, 0.717988, 0.881543, 0.881543, 0.0771773, 0.0771773, 0.910513,0. 0.910513,0.576627 576627, , 0.506879, 0.506879, 0.629856}; 0.629856}; float float sum=0, sum=0, averag average, e, var=0, var=0, sd; int int i; for (i=0;i
56 2. CO COMP MPON ONEN ENTS TS OF C LA LANG NGUA UAGE GE
e output is $ gcc gcc prog prog.c .c -lm -lm $ ./a.ou ./a.out t Average= Average= 0.595222 0.595222 S.D.=0.3101 S.D.=0.310107 07
2. Regression Regression analysis analysis (curve fitting) As anot anothe herr exam exampl plee of arra arrays ys,, regr regres essi sion on anal analys ysis is that that can can obta obtain in the the best best fit curve curve for for give givenn experimental data is i s introduced. Table 2.6 Table 2.6 shows shows N measured points. Table T able 2.6: N measured points X
x1 x2 x3
…
x N
Y
y1 y2 y3
…
y N
( x x3 y , y3) y
|a x3+ b – y3| y = a x+ b
( x x1 y , y1) |a x1+ b – y1|
|a x2+ b – y2| ( x x2 y , y2)
0
x1
x2
x3
x
Figure 2.2: General 2.2: General regression analysis. e best fit line that represents the above data points in the format of y
D ax C b
is sought. e two parameters, a (slope) and b (intercept with the y axis), need to be chosen to minimize an error. e error is defined as the difference between the measured value and predicted value. Since this value can be either positive or negative, it is necessary
2.6. 2. 6. AR ARRA RAYS YS 57
to make it positive-definite by squaring the nominal value. erefore, the total error,21 E 2 , is the sum of the square of the difference at each point defined as E2
D
C b y1/2 C .ax2 C b y2/2 C : : : C .axN C b yN /2 N .axi C b yi /2 :
.ax1
X i
(2.8)
D1 Choose a and b so that E 2 be minimized. is can be achieved by partially differentiating (2.8)) with respect to both a and b and set them to be 0 as 22 E 2 in Eq. (2.8 @E2 @a
@E 2 @b
D 0;
D 0:
is yields a set s et of two simultaneous equations equation s for a and b as N
X C D D X C C D D X ! X ! X C D DX ! DX ! XD C D 2
.axi
i
b
yi /xi
0;
yi /. 1/
0;
1
N
2
.axi
i
or
b
1
N
N
xi2
i
a
xi
1 N
i
xi
N
b
1 N
a
i
D1 i D1 which can be solved s olved using Cramer’s Cramer ’s rule as
a
b
D
D
1 N
1 b
i
ˇˇ P D ˇ PD ˇˇ P D ˇˇ P D ˇˇ PP D ˇˇ PDD ˇP
N i 1 xi yi N i 1 yi N 2 i 1 xi N i 1 xi
N 2 i 1 xi N i 1 xi N 2 i 1 xi N i 1 xi
i
yi ;
D1
N i 1 xi
PD PD PPD D PD
xi yi ;
N
N i 1 xi
N
N i 1 xi yi N i 1 yi N i 1 xi
ˇˇ ˇ ˇˇ ˇˇ ˇˇ ˇˇ ˇ
;
:
N D e following program implements impl ements this result using 10 data points: 21 e dimension of E E 2 is the same as a 2 and b 2 . Hence, it is denoted as E 2 . 22 is method is called the least square method.
58 2. CO COMP MPON ONEN ENTS TS OF C LA LANG NGUA UAGE GE #include #include #def #defin ine e N 10 int main() main(){ { float x[N]={1,2,3,4,5,6,7,8,9,10}, y[N] y[N]={ ={-3 -3, , 2.9, 2.9, 0.5, 0.5, 3.0, 3.0, 2.6, 2.6, 5.2, 5.2, 4.9, 4.9, 4.5, 4.5, 6.1, 6.1, 7.2} 7.2}; ; float xysum=0.0, xysum=0.0, xsum=0.0, xsum=0.0, ysum=0.0, ysum=0.0, x2sum=0.0; x2sum=0.0; floa float t a, b, det; det; int int i; for for (i=0 (i=0; ; i< N; i++) i++) { xsum xsum = xsum xsum + x[i] x[i]; ; ysum ysum = ysum ysum + y[i] y[i]; ; xysu xysum m = xysu xysum m + x[i] x[i]*y *y[i [i]; ]; x2su x2sum m = x2su x2sum m + x[i] x[i]*x *x[i [i]; ]; } det=x2sum*N det=x2sum*N - xsum*xsum; xsum*xsum; a = (xysum*N-x (xysum*N-xsum*ys sum*ysum)/d um)/det; et; b = (x2sum*ysu (x2sum*ysum-xysu m-xysum*xsu m*xsum)/de m)/det; t; prin printf tf(" ("Th The e regr regres essi sion on line line is %f x + %f.\ %f.\n" n", , a, b); b); return return 0; }
e output is $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t The The regr regres essi sion on line line is 0.86 0.8636 3636 36 x + -1.3 -1.359 5999 998. 8.
It is also possible to apply the regression analysis to a curved line such as y D ax 2 C bx C c. 2.6.4 2.6 .4
EXER EX ERCIS CISES ES
1. Birthday Birthday paradox paradox How likely is it that two persons in a group of N people have the same birthday?23 Use the Monte Carlo method to estimate the probability. 23 is problem
is known as the birthday paradox and can c an be solved exactly by the probability theory. Mathematically, this 365Š p.N / D 1 365 D 23, the probability is over 50%. probability is expressed as p.N N .365 N /Š . When N D
2.6. 2. 6. AR ARRA RAYS YS 59
Suggested Suggested Approach: Approach:
(a) Prepare an integer array, a[N], that holds birthday dates for N people. (b) Generate Generate a random number between between 1 and 365 and assign the number to each element of a[] a[] .24 (c) Compare a[0] with the rest of birthdays and if there is a match, get out of the loop, increment the counter by 1 and go to (b) (the next round of simulation). (d) Compare a[1] with the rest of birthdays and if there is a match, get out of the loop, increment the counter by 1 and go to (b) (the next round of simulation). (e) : : :. counter/n. (f) After n simulations, compute the value of counter/n To To exit from f rom the loop, use the goto statement as for (i=0;i
2. row a die 10, 1,000 and 10,000 times and compute the average and the standard deviation. Template: Template: #include #include #include #include #include #include #include #include int main() main() { int i,a[10000]; i,a[10000]; float float sum=0, sum=0, avg, avg, std; std; srand(time(NULL));
24 Use the %
operator. operator. Example: 300%7 returns the th e remainder of 300 divided by 7, i.e., 6.
60 2. CO COMP MPON ONEN ENTS TS OF C LA LANG NGUA UAGE GE for (i=0;i<1000 (i=0;i<10000;i++ 0;i++) ) a[i]=....; a[i]=....; for (i=0;i<1000 (i=0;i<10000;i++ 0;i++) ) sum+= ....; ...................; return return 0; }
2.77 2.
FIL ILE E HANDLIN ING G
In this section, how C programs can interact with external files is explained. 2.7.1 2.7 .1
I/O RE REDIR DIRECT ECTION ION (ST (STAND ANDARD ARD INP INPUT/OUTP UT/OUTPUT UT RE REDIR DIRECT ECTION ION))
UNIX shells (csh/tcsh/bash (csh/tcsh/bash on most of UNIX platforms) and the DOS window have the capability of I/O redirection.25 Instead of entering data from the keyboard and displaying the output on the computer screen, it is possible to re-direct input/output to/from other devices such as files, printers, etc. Table 2.7 Table 2.7 summarizes summarizes the available options. Table T able 2.7: I/O 2.7: I/O redirections Notion
Meaning
$ program > filename $ pr program >> filename $ program < filename
O utput to file Append output to to file Get input from file
If a.out alone is entered from the keyboard, all the output from a.out is displayed on the screen. However, with a.out a.out > result result.da .dat t, the output is saved to an external file, result.dat, and nothing is shown s hown on the screen. You You can examine the contents of result.dat result.dat by the more command. $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t > result result.da .dat t $ more more result result.da .dat t
If the program requires that the input must come from an existing external file and the output must be saved to another external file, you can have both directions on the same line as 25 is is operating system dependent and not a property property of the C language.
2.7. 2. 7. FIL FILE E HA HAND NDL LING 61 $ gcc gcc prog prog.c .c $ ./a. ./a.ou out t < data data.d .dat at > resu result lt.d .dat at $ more more result result.da .dat t
e file, data.dat, contains the necessary data to be input to the program. e following fol lowing command com mand (in (i n a DOS window) creates a file, filelist.dat, that lists all the files in the current directory:26 c:\dir c:\dir > fileli filelist. st.dat dat
2.7. 2. 7.22
FILE FI LE HA HAND NDLI LING NG (F (FRO ROM M WI WITHI THIN N A PR PROGR OGRAM AM))
I/O redirection is operating system dependent (UNIX and DOS) and only available when the C program is run from a command line. It is not possible to use I/O redirection when the C program is run under GUI. To To write/read an external file f rom within a C program, the file must be opened o pened first and must be closed after necessary operations on the file are done. For opening/closing a file, the functions, fopen() and fclose(), with a special keyword 27 FILE (note the upper case) must be used. Use the following syntax. e file variable, fp , is a pointer (the topic in Section 2.8 Section 2.8).). #include #include int main() main() { FILE FILE *fp; *fp; fp = fopen("fil fopen("filename" ename","w") ,"w"); ; /* Write Write someth something ing to fp. */ fclose(fp); return return 0; }
e function, fopen(), takes a (append), w (write), or r (read) as a possible argument. e following program opens an external file, data.dat, for writing and writes “ Hello, World!” to the file. 26 In the Windows system, a file, prn, cannot be used as the name for an external file. It is reserved for 27 is is a FILE pointer that keeps track of the memory location of the file.
a printing device.
62 2. CO COMP MPON ONEN ENTS TS OF C LA LANG NGUA UAGE GE #include #include int main() main() { FILE FILE *fp; *fp; fp=fopen("data.dat","w"); fprintf(fp,"Hello, World!\n"); fclose(fp); return return 0; }
e following program reads three floating numbers separated by a space from an external file, data.dat, and prints out their values on the screen: #include #include int main() main() { FILE FILE *fp; *fp; float float a,b,c; a,b,c; fp=fopen("data.dat","r"); fsca fscanf nf(f (fp, p,"% "%f f %f %f", %f", &a, &a, &b, &b, &c); &c); printf printf("% ("%f f %f %f", %f", a,b,c) a,b,c); ; fclose(fp); return return 0; }
Multiple files can be opened for writing/reading as #include #include int main() main() { FILE FILE *fp1, *fp1, *fp2; *fp2; float a,b,c; fp1=fopen("data1.dat","w"); fp2=fopen("data2.dat","w"); fprint fprintf(f f(fp1, p1,"Th "This is is the first first file.\ file.\n") n"); ; fprintf(fp2, fprintf(fp2,"This "This is the second second file.\n"); file.\n"); fclose(fp1); fclose(fp1); fclose(fp2) fclose(fp2); ; return return 0; }
2.8. 2. 8. PO POINT INTER ERS S
2.88 2.
63
POIN INTE TER RS
e concept of a pointer in C is probably the most challenging chal lenging subject for a C learner. Pointers Pointers are available in C and C++ but not in any other programming languages. Your program looks just like what a C program should appear if pointers poi nters are used in many places. However, there are only two new operators ( & and * ) that need to be learned in order to understand the pointer. e good news for scientific and engineering programming is that you can get around using a pointer for most of programming needs. e only instances that a pointer is needed for engineering/science are (1) working on matrices and vectors in linear algebra and (2) using a variable that is substituted for a function both of which will be explained in this section. 2.8.1 2.8 .1
ADDRE ADD RESS SS OPE OPERA RATO TOR R & AND DERE DEREFEREN FERENCING CING OPERA OPERATOR TOR *
Pointers are closely related to the hardware of a computer that runs a C program. When a C compiler reads a source code, the compiler maps each variable defined in the code to an appropriate location in RAM that holds the value of that variable. For example, consider the following program: #include #include int main() main() { float float a =20.0, =20.0, b=50.0 b=50.0; ; float float *pa, *pa, *pb; *pb; pa=&a; pa=&a; pb=&b; pb=&b; return return 0; }
When the compiler c ompiler reads the program above, it will make a table of o f memory memo ry mapping which may look like Table 2.8 Table 2.8.. Note that this is a fictitious machine for illustrative purposes. In this fictitious machine, the variable a is mapped to the (absolute) memory location at 102 in RAM which holds the value of 20.0. Similarly, the variable b is mapped to the memory location at 150 that holds the value of 50.0. You You can find out the memory memo ry location (address) that holds the value of a given variable by placing an & (ampersand, called an address operator or a referencing operator) in front of the variable name. us in the example above, a represents 20.0 and &a represents 102. Run the following program: #include #include int main() main()
64 2. CO COMP MPON ONEN ENTS TS OF C LA LANG NGUA UAGE GE
Table T able 2.8: Memory 2.8: Memory map on a fictitious machine Variable V ariable Name Absolute Memory Address Content …
100
…
…
101
…
a
102
20.0
…
…
…
b
105
50.0
…
151
…
…
…
…
pa
200
102
…
…
…
pb
220
150
{ int a=10; a=10; printf("Add printf("Address ress of a=%d.\n", a=%d.\n", &a); return return 0; }
e compiler outputs a warning warni ng and the output f rom a.out is negative, which is wrong. $ gcc gcc prog prog.c .c prog.c prog.c: : In functi function on 'main' 'main': : prog.c prog.c:5: :5:10: 10: warnin warning: g: format format '%d' '%d' expect expects s argume argument nt of type type 'int', 'int', but but argu argume ment nt 2 has has type type 'int 'int *' [-Wf [-Wfor orma mat= t=] ] printf("Add printf("Address ress of a=%d.\n", a=%d.\n", &a); ^ $ ./a.ou ./a.out t Address Address of a=-10747042 a=-1074704200. 00.
is is i s because bec ause &a holds the address of a memory location which is larger than the maximum integer that can be handled by the compiler (=2147483647). e %p format instead of the %d format should be used to display a memory address in hexadecimal mode28 correctly. correctly. Change %d to %p in printf() in the previous code. e output will be something like (each machine is different) 28 In hexadecimal format, 16 letters (0–9 and a–f ) are used to represent a number.
2.8. 2. 8. PO POINT INTER ERS S
65
$ gcc gcc prog prog.c .c $ ./a.ou ./a.out t Address Address of a=0xbfa1e9a a=0xbfa1e9a8. 8.
Note that a number beginning with 0x or oX is interpreted as a number in hexadecimal format. Compare the following two programs side by side using an array a[3] a[3]: #include #include int main() main() { int a[]={100,2 a[]={100,2,-56}; ,-56}; printf("%p\ printf("%p\n", n", &a[0]); &a[0]); printf("%p\ printf("%p\n", n", &a[1]); &a[1]); printf("%p\ printf("%p\n", n", &a[2]); &a[2]); return return 0; }
#include #include int main() main() { double a[]={100,2, a[]={100,2,-56}; -56}; printf("%p\ printf("%p\n", n", &a[0]); &a[0]); printf("%p\ printf("%p\n", n", &a[1]); &a[1]); printf("%p\ printf("%p\n", n", &a[2]); &a[2]); return return 0; }
e output from f rom the two programs may look like li ke (each machine is different) $ gcc gcc prog prog1. 1.c c $ ./a.ou ./a.out t 0xbfc76660 0xbfc76664 0xbfc76668
$ gcc gcc prog prog2. 2.c c $ ./a.ou ./a.out t 0xbf988c50 0xbf988c58 0xbf988c60
In the the first first (left (left)) prog progra ram, m, the the arra arrayy, a[], is decla declare redd as an inte intege gerr arra arrayy whil whilee in the the seco second nd (right) program, a[] is declared as a double precision array. Intheoutputfromthefirst(left)program,theaddressofadjacentcomponentsisseparated by 4 bytes which implies that the C compiler stores each integer in teger number (int) using 4 bytes. On the other hand, in the output from the second (right) program, the address is incremented by 8 bytes which implies that the C compiler stores each double precision (double) number using 8 bytes. 2.8. 2. 8.22
PROP PR OPER ERTI TIES ES OF PO POINT INTER ERS S
A pointer is a variable just like a or b above. e only difference is that it stores the “address of another variable.” erefore, if pa pa is a pointer, the content of pa pa is not a regular number such as 20.0 or 50.0 but more like a large number such as 0xbf988c50 as in the examples above. You You must declare a pointer variable the same way you you declare any regular variable but with an asterisk (*) preceding the variable name as
66 2. CO COMP MPON ONEN ENTS TS OF C LA LANG NGUA UAGE GE #include #include int main() main() { float a=20.0; a=20.0; float float *pa; *pa; pa=&a; printf("%p\ printf("%p\n", n", pa); printf("%p\ printf("%p\n", n", &a); return return 0; }
e output (each machine is i s different) looks like $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t 0xbfb0f214 0xbfb0f214
In the program above, floa float t *pa declares that pa is a pointer pointing to a float variable. Note that a pointer itself is always a large integer (memory address location) so the type of a pointer (float in the example above) merely implies that the variable var iable pointed by the pointer pa is of float float type. e pa=&a; statement means that the address of a a is assigned to pa . Sometimes within the program you want to examine what value the pointer actually refers to, i.e., you want to know the content of the variable pointed by the pointer. pointer. Let’s L et’s look at the following program: #include #include int main() main() { float a=20.0; a=20.0; float float *pa; *pa; pa=&a; printf("%f\ printf("%f\n", n", *pa); printf("%f\ printf("%f\n", n", a); return return 0; }
e output is
2.8. 2. 8. PO POINT INTER ERS S
67
$ gcc gcc prog prog.c .c $ ./a.ou ./a.out t 20.000000 20.000000
In the program above, * (asterisk—known as the dereferencing operator) before a pointer variable works the same way as using a directly. erefore, if pa pa is a pointer pointer pointing to a floating floating variable a, the use of a and *pa within a program is identical. is way, you can effectively change the content of a a without directly mentioning a . Pointers can be incremented or decremented just as any other variables. e difference between the increment of pointers and the increment of regular variables is that the value of increment increment for the pointer depends on the type of the variable variable the pointer pointer is pointing pointing to. Take Take the following example: #include #include int main() main() { float float a[3]={ a[3]={1.0 1.0, , 2.0, 3.0}, *pa=&a *pa=&a[0] [0]; ; double double b[3]={1.23 b[3]={1.2345670, 45670, 2.009876555 2.009876555, , 3.14159265 3.14159265}, }, *pb=&b[0]; *pb=&b[0]; printf printf("f ("floa loat t %15p%1 %15p%15p% 5p%15p 15p\n" \n", , pa, pa+1, pa+1, pa+2); pa+2); printf("do printf("double uble %15p%15p%15 %15p%15p%15p\n", p\n", pb, pb+1, pb+2); pb+2); return return 0; }
e output looks like (each machine is different) di fferent) $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t float 0xbf8135e4 double 0xbf8135f0
0xbf8135e8 0xbf8135f8
0xbf8135ec 0xbf813600
In the program above, as a double precision variable occupies occ upies more memory space (8 bytes) than a single precision variable (4 bytes), the increment of the double precision pointer, pb, advances the memory location loc ation by 8 bytes while the increment of the single precision pointer, pa, advances the memory location by 4 bytes even though the increment for both pointers is 1. e C language uses pointers extensively for the following f ollowing reasons: • e only way to modify the content of arguments in a function call is to use pointers. • Computer hardware can be directly controlled by pointers. • Matrices and vectors in linear algebra are actually pointers.
68 2. CO COMP MPON ONEN ENTS TS OF C LA LANG NGUA UAGE GE
2.8. 2. 8.33
FUNCT FUN CTIO ION N AR ARGU GUME MENT NTS S AN AND D PO POINT INTER ERS S
One of the usages of pointers is to modify the content of a variable (parameter) passed through a function call. Suppose you want to write a function, tentimes(), that accepts a variable, a, as a parameter and multiply 10 by a a . Such a program may look like #include #include void tentimes(f tentimes(float loat a) { a = 10.0 10.0*a *a; ; } int main() main() { float float b=20; b=20; tentimes(b); prin printf tf(" (" b = %f\n %f\n", ", b); b); return return 0; }
e output is $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t b = 20.0 20.000 0000 000 0
Unfortunately, this program does not work as intended. e content of b b was not modified even with the a = 10.0*a statement in the definition of tentimes() tentimes(). ere is nothing wrong with this program as this is how a function call in C works. When a function is called with an argument (i.e., tentimes(b)), a copy of the value of the argument (i.e., b ) is made, that value is passed to the function and the actual argument variable b is never altered. All that the function (i.e., tentimes()) can see from the function main() is the copied value of the parameter (i.e., 20) and this information does not have anything to do with the variable itself (i.e., b). is effectively makes it impossible to modify the value of arguments passed to functions. is way of passing a parameter in C functions is called the call by value method. Afixistousepointers.Insteadofpassingacopyofthevalueofthevariabletothefunction, if the address of that variable is passed to the function, the function can find where the value of the variable is stored, stored, go to that address, and modify the content at that address address any way it wants. is is called c alled the call by reference method. method. e program above can be now modified as
2.8. 2. 8. PO POINT INTER ERS S
69
#include #include void tentimes(fl tentimes(float oat *a) { *a = 10.0 10.0** **a; a; } int main() main() { float b=20; tentimes(&b); prin printf tf(" (" b = %f\n %f\n", ", b); b); return return 0; }
e output from f rom this program is $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t b = 200. 200.00 0000 0000 00
is output is what was expected. Note that the dummy variable, a, is declared as a pointer (*a) and instead of b b , the address of b b (&b) is passed to the function, tentimes(). In the function, tentimes(), *a represents the content of the variable pointed by a a .29 As an example of this concept, the following program uses a function, swap(), that takes two pointers as arguments and exchanges the values of the two variables pointed by the pointers: #include #include void void swap(f swap(floa loat t *pa, *pa, float float *pb) *pb) { float float tmp; tmp; tmp=*pa; *pa=*pb; *pb=tmp; } int main() main() { float a=10.0, b=50.0; b=50.0; prin printf tf(" ("Ol Old d a = %f and and old old b = %f\n %f\n", ",a, a,b) b); ; swap(&a,&b); 29 10.0**a is the product between 10.0 and the value
pointed by a, i.e., *a .
70 2. CO COMP MPON ONEN ENTS TS OF C LA LANG NGUA UAGE GE prin printf tf(" ("Ne New w a = %f and and new new b = %f\n %f\n", ", a,b) a,b); ; return return 0; }
e output is $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t Old Old a = 10.0 10.000 0000 000 0 and and old old b = 50.0 50.000 0000 000 0 New New a = 50.0 50.000 0000 000 0 and and new new b = 10.0 10.000 0000 000 0
2.8. 2. 8.44
POINT PO INTER ERS S AN AND D AR ARRA RAYS YS
Handling matrices and vectors in linear algebra is the most relevant use of pointers for scientific and engineering programming. When an array, a[3], is declared as #include #include int main() main() { float float a[3]={ a[3]={1.0 1.0, , 2.0, 2.0, 3.0}; 3.0}; return return 0; }
the C compiler actually interprets a as a pointer and reserves appropriate memory space. In the program program above, above, an array a is a pointer pointing to the 0-th element of the array, a[0], while a[0], a[1], and a[2] behave just like regular variables. e content of a is the address which points to a[0]. Since a is a pointer, dereferencing the array name ( *a) will give the 0-th element of the array, array, i.e., a[0]. is gives us a range of equivalent notations for accessing arrays. In Table 2.9 Table 2.9,, *(a+2) means that the value (address) of the pointer, a, is advanced by two units and the content at that address is referenced which is equivalent to the value of a[2] a[2]. Table T able 2.9: Accessing 2.9: Accessing array elements in two different ways Array Access
Pointerr Equivalent Pointe
a[0]
*a
a[1]
*(a+1)
a[2]
*(a+2)
2.8. 2. 8. PO POINT INTER ERS S
71
Since an array is a pointer, it is possible to pass an array to a function, and modify any element of that array. array. Here is an example: #include #include void void twice( twice(flo float at *a) { int int i; for (i=0; (i=0; i<3; i<3; i++) i++) a[i]=2 a[i]=2*a[ *a[i]; i]; } int main() main() { float float b[3]={ b[3]={1.0 1.0, , 2.0, 2.0, 3.0}; 3.0}; int int i; twice(b); for (i=0; (i=0; i<3; i<3; i++) i++) printf printf("% ("%f\n f\n", ", b[i]); b[i]); return return 0; }
e output from f rom the program is $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t 2.000000 4.000000 6.000000
e program above is to use a function that takes an array as an input and doubles d oubles all the elements in that array. Previously, it was noted that the only way to modify the argument in a function is to use a pointer. is principle also works for arrays as the name of an array is a pointer. erefore, erefore, when passing an array arr ay to a function, the address operator, &, before the array name is not needed. e following program does the same as the one above: #include #include void twice(float twice(float a[3]) { int int i; for (i=0; (i=0; i<3; i<3; i++) i++) a[i]=2 a[i]=2*a[ *a[i]; i]; } int main() main()
72 2. CO COMP MPON ONEN ENTS TS OF C LA LANG NGUA UAGE GE { float float b[3]={ b[3]={1.0 1.0, , 2.0, 2.0, 3.0}; 3.0}; int int i; twice(b); for (i=0; (i=0; i<3; i<3; i++) i++) printf printf("% ("%f\n f\n", ", b[i]); b[i]); return return 0; }
2.8. 2. 8.55
FUNCT FUN CTIO ION N PO POINT INTER ERS S
ere is another type of pointer that can point to a function instead of a variable. Such a pointer is called a function pointer . Using a function pointer, it is possible to use a variable representing different functions. A problem may arise when it is necessary to perform some operation (such as numerical integration) integration) for many different different functions. Without using a pointer pointer to a function, such a program needs to be written to repeat the operations for as many times as the number of different functions. With the use of a function pointer, the program can be written such that the name of a function can be handled just like a variable name in which the variable for the function name can be substituted for any name of the actual function. When a function is declared such as float myfunc() myfunc(), the name of the function, myfunc, itself is actually a pointer pointing to a memory location where the routine of the function code begins.30 A function pointer can be declared as type_of_function (*func_name)(type_of_argument)
where type_of_function is the type of a function to which the function points, func_name is the name of the function pointer and type_of_argument is the type of the argument in func_name. For example, a function pointer, float (*foo)(floa (*foo)(float, t, float) float) , can be pointed to an actual function, floa float t f1(f f1(flo loat at x, floa float t y). In the following code, func() is a function pointer which points poin ts to an actual double type function that has a double type variable as the argument. #include #include #include #include double double f1(dou f1(double ble x) {ret {retur urn n x ; } double double f2(dou f2(double ble x) 30 is is similar to an array. array. e array name itself is a pointer pointing pointing to the address of the first element of the array. array.
2.8. 2. 8. PO POINT INTER ERS S
73
{ret {retur urn n x*x x*x ; } int main() main() { double double (*func)(do (*func)(double); uble); func=&f1; printf("%lf printf("%lf\n", \n", func(2)) func(2)) ; func=&f2; printf("%lf printf("%lf\n", \n", func(2)); func(2)); func=&cos; printf("%lf\n", func(3.141)); return return 0; }
e output is $ gcc gcc prog prog.c .c -lm -lm $ ./a.ou ./a.out t 2.000000 4.000000 -1.000000
As func() is a func functi tion on poin pointe terr, a stat statem emen entt such such as func=&cos assig assigns ns the the addr addres esss of the the cosin cosinee function defined in to func. After this statement, func() and cos() are identical. 2.8. 2. 8.66
SUMM SU MMAR ARY Y
• e asterisk ( *) in C has the following meanings: 1. Multiplication Multiplication if used used as a binary operator (a*b). 2. e value at the address contained in a pointer if used as a unary operator ( *pa) (dereferencing operator). 3. Declaration of a variable as a pointer used in the declaration statement (int int *pa *pa). • e ampersand ampersand symbol symbol (&) in C has the following meanings: 1. e address of a variable if used as a unary operator (&a) (referencing operator). 2. Logical OR if used used as a binary operator operator (a==1.0 a==1.0 && b==2.0 b==2.0). 3. Bitwise Bitwise OR between between two binary numbers numbers (a & b).
74 2. CO COMP MPON ONEN ENTS TS OF C LA LANG NGUA UAGE GE
• Pointers Pointers must be used if the values of arguments arguments in a function function need to be changed. is is the reason reason why scanf() scanf() requires & but not printf(). e value of the variable to be passed to scanf() is entered from f rom the keyboard. Hence, it is necessary to pass the address of that variable to scanf() so that the content of the variable can be modified. 2.8.7 2.8 .7
EXER EX ERCIS CISES ES
1. We want to write a function, circle, which takes the radius of a circle from the main function function and assign the area of the circle to the variable, area, and the perimeter of the circle to the variable, perimeter. Since the contents of the variables are to be modified by a function, it is necessary necessary to use pointers. Use the following template template and complete your program. #include #include void void circle circle(fl (float oat r, (fill (fill in your your code)) code)) { (fill (fill in your your code.. code...); .); } int main() main() { float float r, area, area, perime perimeter ter; ; printf printf("E ("Ente nter r radius radius = "); scanf( scanf("%f "%f", ", &r); &r); circle(r, circle(r, &area, &area, &perimeter) &perimeter); ; printf("r=%f printf("r=%f area=%f peri=%f\n", peri=%f\n", r, area, perimeter) perimeter); ; return return 0; }
2. Write rite a funct functio ionn that that take takess two two float floating ing varia variabl bles es,, a and b ,andrearrangetheminascending order, order, i.e., #include #include void void reorde reorder(f r(floa loat t *pa, *pa, float float *pb) *pb) { (your (your code code here) here) } int main() main() { float float a=15, a=15, b=-6; b=-6; reorder(&a, reorder(&a, &b);
2.9.. STR 2.9 STRING ING MANI MANIPUL PULA ATIO TION N
75
printf printf("% ("%f f %f\n", %f\n", a, b); return return 0; }
shows -6 15
3. Remember that an array is also a pointer as exemplified by #include #include int main() main() { int a[5]={1,2,3 a[5]={1,2,3,4,5} ,4,5}; ; int int i; for (i=0;i (i=0;i < 5;i++) 5;i++) printf printf("% ("%d\n d\n", ", a[i]); a[i]); for (i=0;i (i=0;i < 5;i++) 5;i++) printf printf("% ("%d\n d\n", ", *(a+i) *(a+i)); ); return return 0; }
so a[i] and *(a+i) are identical. Using this idea, write a program to compute com pute the average of all the elements for the following array: a[20]={0.2 a[20]={0.228952, 28952, 0.568418, 0.568418, 0.820277, 0.820277, 0.117099, 0.117099, 0.755212, 0.755212, 0.509299, 0.509299, 0.572073, 0.572073, 0.224526, 0.224526, 0.852861, 0.852861, 0.0612133, 0.0612133, 0.175636, 0.175636, 0.568243, 0.568243, 0.0100543, 0.0100543, 0.702012, 0.702012, 0.0345108, 0.0345108, 0.146549, 0.146549, 0.189951, 0.189951, 0.144139, 0.144139, 0.261263, 0.261263, 0.474034}; 0.474034};
2.99 2.
STR ST RIN ING G MA MANI NIPU PUL LATI TION ON
2.9. 2. 9.11
HOW HO W TO HA HAND NDL LE A ST STRI RING NG OF CH CHAR ARA ACT CTE ERS (T (TE EXT XT))
A text (a string of characters) characters) in C is handled as a set of individual characters, characters, i.e., an array of characters. erefore, an array has to be used to represent a text (string). (strin g). Since any array variable is a pointer as discussed in Section 2.8 Section 2.8,, the variable that represents a string is a pointer as well. Compare the following programs side by side:
76 2. CO COMP MPON ONEN ENTS TS OF C LA LANG NGUA UAGE GE #include #include int main() main() { float a=2.0; printf("%f\n",a); return return 0; }
#include #include int main() main() { char b='A'; b='A'; printf("%c\n",b); return return 0; }
In the left program above, the float variable, a, represents a single value, 2:0. In the right program above, the char variable, c, represents a single singl e character, A . #include #include int main() main() { float float a[]={2 a[]={2.0, .0, 3.0, 3.0, 4.0, 4.0, 5.0}; 5.0}; printf("%f\n",a[0]); return return 0; }
#include #include int main() main() { char b[]="Hello b[]="Hello!"; !"; printf("%c\n",b[0]); return return 0; }
In the left programs above, an array, array, a, represents a set of four numbers, 2.0, 2.0, 3.0, 3.0, 4.0, 4.0, 5.0 and the first number is printed. In the right programs above, an array, b, represents a string of six characters, “Hello!,” and the first character is printed. #include #include int main() main() { float *a, b[]={1.0,2. b[]={1.0,2.0}; 0}; a=b; printf("%f\n",a[0]); return return 0; }
#include #include int main() main() { char *a, b[]={'H','E b[]={'H','E','L' ','L', , 'L','O','!','\0'}; a=b; printf("%c\n",a[0]); return return 0; }
In the left program above, a pointer variable, a, points to the address of a[0] a[0]. In the right program, a pointer variable, a , points to the address of the first character, “ H.” Instead of using b[ ]={' ]={'H' H', , 'E', 'E', 'L', 'L', 'L', 'L', 'O', 'O', '!', '!', '\0' '\0'} } , a direct assignment of b[ b[ ]="HELLO!" ]="HELLO!" can be used with the double quotation mark ("). Note that a special character '\0' needs to be placed to mark the end of the string when we initialize each character individually. Use the %s format to represent the entire string instead of the %c format that represents only one character.
2.9.. STR 2.9 STRING ING MANI MANIPUL PULA ATIO TION N
77
#include #include int main() main() { char char *a; a="Hello, a="Hello, World!"; World!"; printf("%s\n",a); return return 0; }
e output is $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t Hello, Hello, World! World!
As is seen in the examples above, a single quotation mark ( ') and a double quotation mark (") work differently. differently. e single quotation mark must be used for one character while the double quotation mark must be used for a string of characters. For example, "ABC" (double quotation) is for a string of characters and is therefore therefore an array (pointer). On the other hand, 'A' (single quotation) is for a single character. Consider the following program: #include #include int main() main() { char char s[4] s[4] = "ABC "ABC"; "; printf("%s printf("%s\n", \n", s); return return 0; }
You You may wonder why the element number of the array, s, is 4, not 3. e C compiler automatically adds a special character NULL (ASCII code 0, commonly denoted as “n0”) to the end of the string to indicate that that is the end of the character array so that the element number of a character array is always the number of characters plus 1. To To read a string from the standard input (i.e., keyboard), use the following example: #include #include int main() main() {
78 2. CO COMP MPON ONEN ENTS TS OF C LA LANG NGUA UAGE GE char str[100]; str[100]; prin printf tf(" ("En Ente ter r a word word = "); "); scanf("%s", scanf("%s", str); printf("%s\n",str); return return 0; }
e output may look like $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t Ente Enter r a word word = Good Good morn mornin ing g Good
Note that there is no “&” before str in the scanf() function as str is already a pointer. Also, only “Good” is printed even though “ Good morning morning” was entered. is is because the format, %s, in scanf(), reads input until a space is entered (a word). If two strings (two words) are to be read, "%s "%s %s" %s" must be used. e C compiler automatically adds “\0” after the end of the last character in the string. 2.9.2 STRIN STRING G COPY/C COPY/COMP OMPARE/ ARE/LE LENGT NGTH H
To To copy a string to another string or to compare a string against agains t another string, it is best to use functions, strcpy() and strcmp(), available in . #include #include #include #include int main() main() { char char c1[] c1[] = "ABC "ABCDE DE", ", c2[6 c2[6]; ]; strcpy(c2,c1); printf("%s\n",c2); return return 0; }
e output is $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t ABCDE
2.9.. STR 2.9 STRING ING MANI MANIPUL PULA ATIO TION N
79
In the program above, the function, strcpy(c2,c1), copies the pointer, poi nter, c1, to another pointer poin ter,, c2. Note c2[6] instead of c2[5] c2[5] as the NULL character must be added after the end of the string. To To compare two strings, use strcmp() available in : #include #include #include #include int main() main() { char s[100]; s[100]; printf("Enter \"ABCDEF\""); scanf("%s" scanf("%s", , s); if (strcm (strcmp(s p(s,"A ,"ABCD BCDEF" EF") ) == 0) printf printf("A ("ABCD BCDEF EF was entere entered d correc correctly tly.\n .\n"); "); else printf("Wr printf("Wrong. ong. %s was entered.\n" entered.\n",s); ,s); return return 0; }
In the program above, the strcmp() function takes two strings as the arguments and returns 0 if the two strings match. Note that you can output " (double quotation mark) by “escaping” it using the backslash character. To To find the length of the string, use the strlen() function: #include #include #include #include int main() main() { char c[50]; c[50]; printf printf("E ("Ente nter r string string = "); scanf("%s" scanf("%s", , c); printf printf("Y ("You ou entere entered d %s\n", %s\n", c); printf printf("I ("Its ts length length is %d\n", %d\n", strlen strlen(c) (c)); ); return return 0; }
e output is $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t Enter Enter string string = Good Good aftern afternoon oon. .
80 2. CO COMP MPON ONEN ENTS TS OF C LA LANG NGUA UAGE GE You entere entered d Good Good Its Its leng length th is 4
Again, only “Good” was read as the format, %s, reads a string until a space is entered (a word).
2.10 2. 10 COM OMMA MAND ND LIN INE E AR ARGU GUME MENTS NTS 2.10.1 2.1 0.1 EN ENTE TERIN RING G CO COMMA MMAND ND LI LINE NE ARG ARGUME UMENTS NTS
e traditional way of executing a C program after successful compilation is to issue the program name at the system prompt as in the following example: $ gcc gcc prog prog.c .c -lm -lm -o prog prog $ ./prog ./prog (interactiv (interactive e session) session)
Instead of entering necessary information during the interactive session (using scanf() and printf() funct function ions) s),, you you can ente enterr nece necessa ssary ry para parame mete ters rs at the the same same time time you you enter enter the the prog progra ram m name as $ gcc gcc prog prog.c .c -lm -lm -o prog prog $ ./pr ./prog og 3421 3421 8756 8756 (execu (executes tes progra program m to manipu manipulat late e 3421 3421 and 8756 8756 and prints prints result results) s)
is is called “command line arguments” arguments ” (also called “command line parameters”) and provides a handy way to pass necessary arguments to the main() function without user interaction. Recall that the function, main(), is the function in C that is to be executed first. Other than that, it is an ordinary function in C just like any other functions so that it must have an argument part. e function, main(), actually takes two arguments. e first argument is the numbe numberr of comma command nd line line argu argume ment ntss inclu includin dingg the the progr program am name name itse itselflf and and the the seco second nd argu argume ment nt (an array of strings) stores each command line argument entered after the program name. e syntax of the arguments in main() is int main(i main(int nt argc, argc, char char *argv[ *argv[]) ])
e first argument, argc, is of integer type and is assigned the number of command line arguments including the command name itself. e second argument, argv, is a pointer to an array of strings that stores each of the command line arguments. Note that argv[ argv[ ] is an array so that 31 it can take multiple command line arguments. 31 Actually, argv[ argv[ ] isapointertoanotherpointer(anarrayofanotherarray)aseachelementof argv[ argv[ ] isastringofcharacters.
2.10 2. 10.. COM COMMAN MAND D LI LINE NE AR ARGU GUME MENT NTS S
81
Consider the following program: #include #include int main(i main(int nt argc, argc, char char *argv[ *argv[]) ]) { int int i; printf printf("N ("Numb umber er of argume arguments nts = %d\n", %d\n", argc); argc); for(i= for(i=0; 0; i
Execute the program above with command line arguments as in the following example: $ gcc gcc prog prog.c .c $ ./a. ./a.ou out t I hate hate C lang langua uage ge. . Numb Number er of argu argume ment nts s = 5 0: ./a.ou ./a.out t 1: I 2: hate hate 3: C 4: language. language.
e string “ ./a.out” is stored in argv[0], the string “I” is stored in argv[1], etc. Note that each of the command line arguments is entered as a string. For example, when a number 4 is entered, it is stored as a character “4” (ASCII code 52), not as the numeric value of 4. If you want the program to interpret the entered parameters as numeric values, not a string stri ng of characters, use atoi() (ASCII to INTEGER) or atof() (ASCII to FLOAT) available in . #include #include #include #include int main(i main(int nt argc, argc, char char *argv[ *argv[]) ]) { printf("%d\n", atoi(argv[1])); return return 0; }
e output looks like
82 2. CO COMP MPON ONEN ENTS TS OF C LA LANG NGUA UAGE GE $ gcc gcc prog prog.c .c $ ./a. ./a.ou out t 2018 2018 2018
e following program computes the sum of all the numbers entered as command line arguments: #include #include #include #include int main(i main(int nt argc, argc, char char *argv[ *argv[]) ]) { floa float t sum= sum=0. 0.0; 0; int int i; for (i=1;i
e output looks like $ gcc gcc prog prog.c .c $ ./a.out 1 2 3 4 5 6 7 8 9 10 The The sum sum is 55.0 55.000 0000 000. 0.
2.10.22 EXE 2.10. EXERCIS RCISES ES
1. Write a program using the concept of command line arguments to solve a quadratic equation, ax 2 C bx C c D 0, by entering a , b , and c as command line arguments, i.e., $ ./a. ./a.o out 3 -1 -1
will return x1= -0.434 -0.434259 259, , x2 = 0.7675 0.767592. 92.
by solving 3x 2 x 1 D 0.
2.11. 2.1 1. STRU STRUCTU CTURES RES 83
2.111 STR 2.1 STRUC UCTUR TURES ES 2.11.1 2.1 1.1 MIXTUR MIXTURE E OF DIF DIFFE FERE RENT NT TYPES OF VARI ARIABL ABLES ES
An array is a single variable that can represent many elements. However, all the elements in an array must be of the same type. What if you want to have a single variable that represents different types of elements such as a mixture of integers, floating numbers and strings? A structure is is a collection collection of one or more variables variables under a single name. ese variable variabless can be of different different types, and are selected selected from f rom the structure by name. A structure is a convenient convenient way of grouping several pieces of related information together. together. Forexample,astructurecalled student can be crea create tedd which which repr repres esen ents ts the the schoo schooll reco record rdss of students such as the ID, the midterm score, the final score and the final grade. e following program exemplifies the concept of structures: #include #include struct struct student{ student{ char char *ID; *ID; int Midterm; Midterm; int Final; Final; char char Grade; Grade; }; int main() main() { struct struct studen student t smith= smith={"1 {"1000 000123 123456 456", ", 89, 98, 'A'}, 'A'}, doe={"1000 doe={"1000123457 123457", ", 45, 53, 'F'}; printf("%s\n", smith.ID); printf("%d\n", doe.Midterm); doe.Grade='D'; printf("%c\n", doe.Grade); return return 0; }
e output is $ gcc gcc prog prog.c .c $ ./a.ou ./a.out t 1000123456 45 D
84 2. CO COMP MPON ONEN ENTS TS OF C LA LANG NGUA UAGE GE
In the the prog progra ram m above above,, a struc structu ture re calle calledd student is defin defined ed havi having ng four four membe members rs (ID, (ID, Midte Midterm, rm, Final, Final, Grade) which is a mixture mixture of different different types. e first member, member, ID is a string (hence, a pointer), pointer), the second and third members, Midterm and Final, are integers and the last member, Grade, is a character. Two variables, smith and doe , are declared as of student student type and initialized. A member in a structure can be accessed by using the dot (.). You You can also define an array of structures str uctures as #include #include struct student{ student{ char char *ID; *ID; int Midterm; Midterm; int Final; Final; char Grade; Grade; }; int main() main() { struct student student myclass[15]; myclass[15]; int int i; myclass[0].ID="10000123212"; myclass[0].Grade='C'; (.....) myclass[14].Grade='B'; (.....) return return 0; }
It is also possible to use a pointer to a structure as #include #include