Programming in Ansi c by Balagurusamy Third Edition PDF - Ebook download as Text File .txt), PDF File .pdf) or read book online. ebook. Balagurusamy. Uploaded by. amitukumar. Balaguruswamy Ansi c Book PDF. Uploaded by. Anuj Raj. Programming in Ansi c by Balagurusamy Third. Programming in Ansi c by Balagurusamy Third Edition PDF. Document Cover. Programming in Ansi c by.
|Language:||English, Spanish, Hindi|
|Genre:||Politics & Laws|
|Distribution:||Free* [*Registration needed]|
Author: E. Balagurusamy Publisher: Tata McGraw-Hill Date: Format: pdf. Language: English ISBN Pages: ISBN Programming In ANSI c by Balagurusamy pdf Download free . “The C Programming Language”, 2nd edition, by Kernighan and Ritchie, is widely considered to. 1 programing in ansi 'c' balagurusamy 2 let us c yashwant kanitkar 3 algebra vol2 This Digital Download PDF eBook edition and related web site are NOT.
We start with a careful information hiding technique for abstract data types, add generic functions based on dynamic linkage and inherit code by j udicious lengthening of structures. Finally, we put it all together in a class h ierarchy that makes code much easier to maintain. Programming takes discipline. Good programming takes a lot of discipline, a large number of principles, and st andard, defensive ways of doing things right.
Programmers use tools. Good progra mmers make tools to dispose of routine tasks once and for all. Therefore, in chapter seven we build a small preprocess or to create the boilerplate required. It looks like yet another new object-orie nted dialect language yanoodl perhaps? The following chapters refine our technology.
In chapter eight we add dynamic type checking to catch our mist akes earlier on. In chapter nine we arrange for automatic initialization to prev ent another class of bugs. Chapter ten introduces delegates and shows how classe s and callback functions cooperate to simplify, for example, the constant chore of producing standard main programs. More chapters are concerned with plugging m emory leaks by using class methods, storing and loading structured data with a c oherent strategy, and disciplined error recovery through a system of nested exce ption handlers.
Finally, in the last chapter we leave the confines of ANSI-C and implement the obligatory mouse-operated calculator, first for curses and then f or the X Window System. This example neatly demonstrates how elegantly we can de sign and implement using objects and classes, even if we have to cope with the i diosyncrasies of foreign libraries and class hierarchies. Each chapter has a sum mary where I try to give the more cursory reader a rundown on the happenings in the chapter and their importance for future work.
Most chapters suggest some exe rcises; however, they are not spelled out formally, because I firmly believe tha t one should experiment on one's own. Because we are building the techniques from scratch, I have refrained from making and using a massive class library, even th ough some examples could have benefited from it.
If you want to understand objec t-oriented programming, it is more important to first master the techniques and consider your options in code design; dependence on somebody else's library for yo ur developments should come a bit later. It is also quite instructive to use a program like diff a nd trace the evolution of the root classes and ooc reports through the later cha pters.
I hav e shown this to a number of people in courses and workshops and others have used the methods to get their jobs done. It would have stopped there as my footnote to a fad, if Brian Kernighan and my publishers, Hans-Joachim Niclas and John Wai t, had not encouraged me to publish the notes and in due course to reinvent it all once more. My thanks go to them and to all those who helped with and suffer ed through the evolution of this book. Hollage, October Axel-Tob ias Schreiner. Data Types.
A bstract Data Types. Memory Management. Obje ct. An Application. Constructors and Des tructors. Methods, Messages, Classes and Objects. Summar y. The Main Loop. The Scanner. The Recognizer. The Processor. Infix Output. Linkag e and Inheritance. Static and Dynamic Linkage. Visibility and Acce ss Functions. Is It or Has It? Multiple Inheritance. Aggreg ates. Scanning Identifiers. Using Variables. Assi gnment. Superclass Selectors. Implementation Strategy.
Object Revisited. Techni que. Coding Standard. Avoiding Recursion Summary. An Example. Class Methods. Abstract Base Classes. Implemen tation. Implement ation. Exercise s. C Manual. The ooc Command. GUI Calculator Cl asses. The Datab ase.
Names and Scope. Pointers to Functions. Report Files.
Root Classes. Programmers are rarely content with what's avai lable and a programming language normally provides facilities to build new data types from those that are predefined.
More complicated e xamples do not fare much better. At a theoretical level this requires us to specify the properties of the data type by mathematical axioms involving the possible operations. Alternative ly. This approach. Good programming principles dictate tha t we conceal the representation of a data item and declare only the possible man ipulations. A simple approach is to form aggregates su ch as arrays.. For example. ANSI-C has int. What exactly is a data type?
We can take several points of view. To declare what we can do with a set. We can hardly reveal or assume less: Set will have to somehow represent the fact. Abstract data types sati sfy the good programming principles of information hiding and divide and conquer.
If we m anage to distribute the necessary information correctly. Since the representation is not part of the definition. If we used this name for a set function. Viewed this way. This technique of protecting header files is so standard. As an example we consider a set of elements with the operations add. With an abstract d ata type we cleanly separate the programming tasks of implementation and usage: Information such as the representation of data items is given only to the one with a need to know: For the moment.
If we built a bigger class library. Set is a pointer.. Real life objects need more functionality to do something us eful. On the one hand it makes it impos sible to discover what a set looks like. The text only shows the interesting parts of each new file. At this point. If t hey are. Just like Set. This description leaves room for the functionality of strcmp: Removing an element not in a s et will result in a null pointer being passed to delete. The call to differ illustrates a semantic point: If all is well.
For now. If an object stores no information and if every object belongs to at most one set.. The program should simp ly print ok. If an object is a member of a set. For ou r purpose of developing a coding technique. It only returns an element in heap with value zero: Sets and objects have the same representation.
In chapter 13 we will look at a general technique for handling exce ptions. Before an object is added to a set. An element of heap is recycled by setting it to zero: If an element contains MANY.
This is the first of many errors. A set is represented in its obje to the set. A more realistic implementation should at least print a reasonable error message o r use a general function for error handling which the user may overwrite.
It turns out that we d o not need differ to implement a set. If so. We still need to provide it. The other functions are just as simple. Our implementation is quite unconventional. In this case.
This time we use dynamic memory and represent sets and objects as structures: Si nce we will use dynamic memory to represent sets and objects. We did use these pointers in main to create new sets and objects. If we decrement count each time the element is passed to drop and only remove the element once coun t is zero. It increments the element's reference counter and the number of elements in the set: For an element. The overhea d of a function call is insignificant compared to the danger of an application b eing able to overwrite a critical value.
If drop finds its element in the set. If the reference count reaches zero. After it is dropped from the set once. The application co de can only access a header file where a descriptor pointer represents the data type and where operations on the data type are declared as functions accepting a nd returning generic pointers.
A more general and more conventional solution represents a set as a li near list of nodes storing the addresses of objects in the set. The test p rogram now has the output ok drop? If we continue to represent objects as small unique integer values. The descriptor pointer is passed to a general fun ction new to obtain a pointer to a data item. This imposes no restriction on objects and permits a set to be implemented without knowing the r epresentation of an object.
For debugging it is very helpful to be able to look at individual objects. Bot h functions return the number of characters written. Our application in section 1. Now new h as a problem. The drawback is that new would explicit ly contain code for each data type which we support. When the stri ng is deleted.
The obvious approach is to make a pointer to the destructor part of the type descriptor which is passed to new. We could give delete another parameter: Based on the parameter.
For a new string we allocate a dynamic buffer to hold the text. It is responsible for creating objects and returning pointers that can be passed to delete.
We call such a function a destructor for the object. There is a much more general and elegant way: Part of each and every object will be a pointer with which we can locate a cle an-up function. So far we need something like the following declarations: What s hould this pointer point to? If all we have is the address of an object. Classes and Objects delete must be able to locate the destructor without knowing what type of obje ct it has been given.
Looking closely. The constructor is called b y new and is only responsible for initializing the memory area allocated by ne w. Since constructor and destructor are type-specific and do not change. It seems likely that we will soon invent other type-specific functions such as a function to display objects.
This spa ce is later freed by delete. Therefore w e will use a pointer to a table of function pointers. For a string. Many objects will share the same type descriptor. This is why we initialize this pointer already in new: Dynamic Linkage. We c all these functions methods for the objects. The constructor is called by new for a new memory area which is mostly uninitialized: So far a class.
Since we are using plain C functions. Each of our objects starts with a pointer to its own type description An object is an instance of a class.. Conven tionally speaking.
Looking down this list. Only the constructor may have to cope with a partially initialized memory area. We call all objects with the same type descriptor a class. Calling a method is termed a messag e and we have marked the receiving object of the message with the parameter name self. All other methods stored in the type description are called in a similar fashion. The obje ct is created at run time and the dashed pointers are then inserted.
Since we might later want to share the original parameters among several functions. This is used to call the destructor if any exists. If an object does not want to be deleted. If the constructor decides to cheat. In each case we have a si ngle receiving object self and we need to route the method call through its desc riptor: Note that only exp licitly visible functions like new can have a variable parameter list.
We force a conv ersion of p which treats the beginning of the object as a pointer to a struct Cl ass and set the argument class as the value of this pointer. We force the conversion using a local varia ble cp and very carefully thread our way from self to its description: Section Poly morphic functions are actually built into many programming languages. As an ex ample.
In any case. For the momen t at least. We can view selectors as method s which themselves are not dynamically linked but still behave like polymorphic functions because they let dynamically linked functions do their real work. Once we implement more classes which al l contain.
We will call differ a selector function. This phenomenon is called overloading: Methods can be polymorphic without having dynamic linkage. It is an example of a polymorphic fu nction.
There is no clear distinction here: Here is the application: The first two prototypes declare selectors. They are derived from the correspond ing components of struct Class by simply removing one indirection from the decla rator. Notice the difference: All our methods are common to all objects. Dynamic linkage helps to clearly identify which functions need to be written to implement a new data type.
Later both. The destructor frees the dynamic memory controlled by the string. If we really compare two distinct strings. This can easily be done by calling new: S ince delete can only call the destructor if self is not null. The constructor retrieves the text passed to new and stores a dynamic copy in the struct String which was al located by new: Before the co nstructor saves a text it first looks through the list to see if the same text i s already stored.
In order to pr operly initialize the type descriptor. Atoms are more expensive to construct and d estroy: Atoms are very cheap to compare: All these methods are static because they should only b e called through new.
An atom is a unique string object. The methods are made availab le to the selectors by way of the type descriptor: With this im plementation our application from section 2.
If we find a suitable atom. Otherwise we insert the new string object into the circular list and set its reference count to 1. The destructor p revents deletion of an atom unless its reference count is decremented to zero. Otherwise we clear the circular list marker i f our string is the last one or we remove our string from the list.
Polymorphic functions are quite useful. This is difficult for Set because we can no longer record in th e set elements to which set they belong.
Through selectors and dynamic link age the same function name will take different actions for different classes. Does it make any differ ence what we pass to new? Su ch a function is called polymorphic. We call all objects sharing the same descriptor a class. Atoms are much more efficient. Things get interesting if we also deal with subst rings. In particular.
There should be more methods for string s: An object is an in stance of a class. A cheap and very convenient debugging tool is a polymorphic fu nction store to display any object on a file descriptor. We use selector functions to locate and c all dynamically linked methods for an object. Can th e value of an atom be changed? The y provide a level of conceptual abstraction: This often simplifies a routine job a nd it usually results in code that can be extended easily.
If things go wrong. Rather tha n writing a few functions. As an example we will write a small program to read and evaluate arithmetic expressions consisting of floating point numbers. This book is not about compiler building.
Normally we would use the compiler generator tools lex and ya cc to build that part of the program which recognizes an arithmetic expression.
Here is the main loop: At the end of a line token is zero: Any other character is returned as is. White space is ignored and for a leading digit or decimal point we extract a floating point number with the ANSI-C function strtod. The exit code of the program reports if any 3. If error is called somewher continues execution with another return from setjmp is the value passed to longjmp. The only problem is that we must avoid infinite recur sion.
If we have detected a number. If we wa nt to build a system that can handle more complicated expressions we need to sto re expressions for later processing. All we need is a reasonably general way to represent an expression. If we recognize it. A grammatic al rule like sum: If we do not use yacc we recognize expressions b y the method of recursive descent where grammatical rules are translated into eq uivalent C functions. Alternatives are translated into switch or if statements.
The conventional technique is to use a binary tree and store token in each node: If we only want to perform simple arithmetic on numerical values. For example: We need to introduce a union to create a nod e in which we can store a numerical value and we waste space in nodes representi ng unary operators. This is not very flexible. Now we can code sum as follows: As soon as token is consum ed we need to call scan 0. This pointer is entere d by new so that delete can reach its node-specific function: If we want to e mit a postfix version of the expression.
All we require is that the va rious nodes start with a pointer for the dynamic linkage. It should be easy to guess how a numerical value is implemented. It is represent ed as a structure with a double information field: A unary operator such as Minus is left as an exercise. The type descriptions tie everything together: Here are two examples: In addition to the operator name u sed for postfix output we add two numbers to the struct Type: This is usually a bit tricky.
As an example consider. Dyn amic linkage has helped to divide a problem into many very simple functions. A binary node such as an addition is given the precedence of its sup erior and a flag indicating whether parentheses are needed in the case of equal precedence. If our node has less precedence than its superior. The tricky part is for a binary node to decide if it must surround itself with p arentheses.
A s usual. Here is a quick tes t for one of the classes we would like to have: ANSI-C does not include stand ard functions for graphics output. The type description struct Class in new. If we stick with two-dimensional. Cartesian coordinates. The selector draw is implemented in new. It replaces selectors such as diff er introduced in section 2. If we implement each graphical object relat ive to its own reference point. Once again. We can recycle the new.
We make a copy of the implementation of points and change those parts where a circle is different from a point. This is where we would normally crank up our te xt editor and perform source code reuse. Drawing happens a bit differently. Consider the layout of the representations of points and circles: If move were dynamically linked. The necessary actions are identical for a point an d a circle: We let the derived structure start with a copy of the base structure that we are extending.
Information hiding demands that we should never reach into the base structure directly. If we derive struct Cir cle by adding to the end of struct Point. Since representation of the subclass object a circle starts out like t he representation of a superclass object a point. It is perfectly sound to pass a circle to move: Here is a sound way to make sure the initial part of a circle always looks like a point: This is all the re is to simple inheritance: We get a bit stuck in move.
A subcla ss can choose to supply its own methods in place of the dynamically linked metho ds of its superclass. Let us look at the previous picture again If inherited. While we can pass points as well as circles to move. The situation is different for a dynamicall y linked method like draw. If overwritten. In case of doubt it is probably better to decide on dynamic rather than static linkage eve n if it is less efficient.
We cannot discover the linkage from the two declarations. Consider the decla rations for move and draw: Unfort unately. Beginning in chapter 7 we will use a simple preprocesso r to simplify coding.
While the f unction calls to the methods do not change. Generic functions can provide a useful conceptional a bstraction and they tend to reduce the number of function names which we need to remember in the course of a project. Static linkage is more efficient be cause the C compiler can code a subroutine call with a direct address.
Additionall y. The only difference is that we d eclare a statically linked method like move as part of the abstract data type interface in Point. Efficiency dictates that a subclass reach in to its superclass components directly. Information hiding and maintainability re quire that a superclass hide its own representation as best as possible from its subclasses. If we opt for the latter. The representation file Circle.
F inally. From an information hiding perspective this i s not such a good idea. The representa tion of a circle is declared in a second header file. While reading coordinate values should not create major problems we can never be sure that in other situations a subclass implementation is not going to cheat and modify its superclass part directly. For a subclass it includes the representation file of the superclass so that we can derive the representation of the subclass by extending the superclass: The subclass needs the superclass representation to implement inheritance: Th e macro definitions demonstrate..
This structure has the same size as before. If t hey are, the descriptor has to indicate at least how much memory is required. This description leaves room for the functionality of strcmp : for s ome pairs of objects we might choose to return a negative or positive value to s pecify an ordering. Real life objects need more functionality to do something us eful. For the moment, we restrict ourselves to the bare necessities for membersh ip in a set.
If we built a bigger class library, we would see that a set and in fact everything else is an object, too. At this point, a lot of functionality re sults more or less for free. If all is well, we find the objec ts in the set and we should not find another new object. The program should simp ly print ok. The call to differ illustrates a semantic point: a mathematical s et can only contain one copy of the object a; an attempt to add it again must re turn the original object and differ ought to be false.
Similarly, once we remo ve the object, it should no longer be in the set. Removing an element not in a s et will result in a null pointer being passed to delete. For now, we stick wit h the semantics of free and require this to be acceptable. If an object stores no information and if every object belongs to at most one set, we can re present each object and each set as small, unique, positive integer values used as indices into an array heap.
If an object is a member of a set, its array el ement contains the integer value representing the set. Objects, therefore, point to the set containing them.
Sets and objects have the same representation, so new pays no attentio n to the type description. It only returns an element in heap with value zero: if! Before an object is added to a set, we let it contain the impossible ind ex value MANY so that new cannot find it again and we still cannot mistake it as a memb er of any set.
A more realistic implementation should at least print a reasonable error message o r use a general function for error handling which the user may overwrite. For ou r purpose of developing a coding technique, however, we prefer to keep the code uncluttered. In chapter 13 we will look at a general technique for handling exce ptions. A set is represented in its obje to the set. If an element contains MANY, it can be adde it should already be in the set because we do not permi more than one set.
The other functions are just as simple. In this case, however, we would replicate most of the code of find in drop. Our implementation is quite unconventional. It turns out that we d o not need differ to implement a set. We still need to provide it, because our application uses this function. For an element, count reco rds how many times this element has been added to the set.
If we decrement count each time the element is passed to drop and only remove the element once coun t is zero, we have a Bag , i. If drop finds its element in the set, it decrements the element's reference count and the number of element s in the set. The overhea d of a function call is insignificant compared to the danger of an application b eing able to overwrite a critical value.
Our application in section 1. After it is dropped from the set once, contains will still find it in the bag. The test p rogram now has the output ok drop? The application co de can only access a header file where a descriptor pointer represents the data type and where operations on the data type are declared as functions accepting a nd returning generic pointers.
The descriptor pointer is passed to a general fun ction new to obtain a pointer to a data item, and this pointer is passed to a general function delete to recycle the associated resources. Normally, each ab stract data type is implemented in a single source file. Ideally, it has no acce ss to the representation of other data types.
If we continue to represent objects as small unique integer values, and if we put a ceiling on the number of objects available, we can repr esent a set as a bitmap stored in a long character string, where a bit selected by the object value is set or cleared depending on the presence of the object in the set.
A more general and more conventional solution represents a set as a li near list of nodes storing the addresses of objects in the set. This imposes no restriction on objects and permits a set to be implemented without knowing the r epresentation of an object. For debugging it is very helpful to be able to look at individual objects. Bot h functions return the number of characters written. For a new string we allocate a dynamic buffer to hold the text. When the stri ng is deleted, we will have to reclaim the buffer.
Based on the parameter, we could use a chain of if statements to handle each creation individually. The drawback is that new would explicit ly contain code for each data type which we support.
It, too, must behave differently based on the type of the object b eing deleted: for a string the text buffer must be freed; for an object as used in chapter 1 only the object itself has to be reclaimed; and a set may have acqu ired various chunks of memory to store references to its elements.
We could give delete another parameter: either our type descriptor or the function to do th e cleaning up, but this approach is clumsy and error-prone.
There is a much more general and elegant way: each object must know how to destroy its own resources. Part of each and every object will be a pointer with which we can locate a cle an-up function. We call such a function a destructor for the object. Now new h as a problem. It is responsible for creating objects and returning pointers that can be passed to delete , i.
The obvious approach is to make a pointer to the destructor part of the type descriptor which is passed to new. Since constructor and destructor are type-specific and do not change , we pass both to new as part of the type description.
Note that constructor a nd destructor are not responsible for acquiring and releasing the memory for an object itself this is the job of new and delete. The constructor is called b y new and is only responsible for initializing the memory area allocated by ne w.
For a string, this does involve acquiring another piece of memory to store the text, but the space for struct String itself is allocated by new. This spa ce is later freed by delete. First, however, delete calls the destructor whi ch essentially reverses the initialization done by the constructor before delete recycles the memory area allocated by new. Therefore, revising the declarations shown in section 2. What s hould this pointer point to?
If all we have is the address of an object, this po inter gives us access to type-specific information for the object, such as its d estructor function. It seems likely that we will soon invent other type-specific functions such as a function to display objects, or our comparison function dif fer , or a function clone to create a complete copy of an object.
Therefore w e will use a pointer to a table of function pointers. Looking down this list, we notice that every function works for the object through which it will be selected. Only the constructor may have to cope with a partially initialized memory area. We c all these functions methods for the objects.
Calling a method is termed a messag e and we have marked the receiving object of the message with the parameter name self. Since we are using plain C functions, self need not be the first paramete r. Many objects will share the same type descriptor, i.
We call all objects with the same type descriptor a class ; a single object is called an instance of the class. So far a class, an abstract data type, and a set of possible values together with operations, i.
An object is an instance of a class, i. Conven tionally speaking, an object is a value of a particular data type. The obje ct is created at run time and the dashed pointers are then inserted. We force a conv ersion of p which treats the beginning of the object as a pointer to a struct Cl ass and set the argument class as the value of this pointer. Next, if a construc tor is part of the type description, we call it and return its result as the res ult of new , i. Section 2.
Note that only exp licitly visible functions like new can have a variable parameter list. Since we might later want to share the original parameters among several functions, we pass the address of ap to the constructor when it re turns, ap will point to the first argument not consumed by the constructor. This is used to call the destructor if any exists. Here, self plays th e role of p in the previous picture. If the constructor decides to cheat, the destructor thus ha s a chance to correct things, see section 2.
If an object does not want to be deleted, its destructor would return a null pointer. All other methods stored in the type description are called in a similar fashion. In each case we have a si ngle receiving object self and we need to route the method call through its desc riptor: 2. For the momen t at least, we guard against null pointers. In any case, differ illustrates why this technique of calling functions is called dynamic linkage or late binding : while we can call differ for arbitrary objects as long as they start with an approp riate type description pointer, the function that actually does the work is dete rmined as late as possible only during execution of the actual call, not before.
We will call differ a selector function. It is an example of a polymorphic fu nction , i. Once we implement more classes which al l contain. We can view selectors as method s which themselves are not dynamically linked but still behave like polymorphic functions because they let dynamically linked functions do their real work.
Poly morphic functions are actually built into many programming languages, e. This phenomenon is called overloading : argument types and the operator name together determine what the operator does; the same opera tor name can be used with different argument types to produce different effects. Methods can be polymorphic without having dynamic linkage. They are derived from the correspond ing components of struct Class by simply removing one indirection from the decla rator.
Here is the application: include "String. We show the size of a String objec t not the size of the text controlled by the object and we check that two differ ent texts result in different strings. Chapters nine and ten are on functions, structures and unions. Pointers, perhaps the most difficult part of C to understand, is covered in Chapter eleven in the most user-friendly manner. The above organization would help the students in understanding C better if followed appropriately.
Each major feature of the language is treated in depth followed by a complete program example to illustrate its use. The sample programs are meant to be both simple and educational. Two new projects are added at the end of the book for students to go through and try on their own. Each chapter includes a section at the, beginning to introduce the topic in a proper per- spective. It also provides a quick loqkyiuto the features that are discussed in the chapter. Wherever necessary, pictiinal dehciifztions of concepth are included to -improve clarity and to facilitate better understanding.
The Just Remember section at theend of the chapters lists out helpful hints and possible problem areas. Numerous chapter-end questions and exercises provide ample opportunities to the readers to review the concepts leamed and to practice their applications.
Supplementary Material With this revision we have tried to enhance the online learning center too. The supplemen- tary material would include the following: For the Instructor Cl Solutions to the debugging exercises For the Student D Exclusive project for implementation with code, step-by-step description and user manual El Code for the two projects given in the book D Two mini projects D Reading material on C This book is designed for all those who wish to be C programmers, regardless of their past knowledge and experience in programming.
But this strange sounding language is one of the most popular computer languages today because it is a structured, high-level, machine independent language. It allows software developers to develop programs without worrying about the hardware platforms where they will be implemented. Although it never became popular in USA, it was widely used in Europe. Subsequently, several languages were announced. C uses many concepts from these languages and added the concept of data types and other powerful features.
This operating system, which was also developed at Bell Laboratories, was coded almost entirely in C. UNIX is one of the most popular network operating systems in use today and the heart of the Internet data superhighway. For many years, C was used mainly in academic environments, but eventually with the release of many C compilers for commercial use and the increasing popularity of UNIX, it began to gain widespread support among computer professionals. Today, C is running under a variety of operating system and hardware platforms.
The rapid growth of C led to the development of different versions of the language that were similar but often incompatible. This posed a serious problem for system developers. They continue to i. The result was the standard for C. This version is usually referred to as C The history andudievelopment of C is illustrated in Fig.
We, therefore, discuss all the new features added by C99 in an appendix separately so that the readers who are interested can quickly refer to the new material and use them wherever possible. It is a robust language whose rich set of built-in functions and operators can be used to write any complex program.
The C compiler combines the capabilities of an assembly language with the features of a high-level language and therefore it is well suited for writing both system software and business packages. In fact, many of the C compilers available in the market are written in C. This is due to its variety of data types and powerful operators. For example, a program to increment avariable from 0 to takes about one second in C while it takes more than 50 seconds in an interpreter BASIC.
Several standard functions are available which can be used for developing programs. C is highly portable.
This means that C programs written for one computer can be run on another with little or no modification. A proper collection of these modules would make a complete program. This modular structure makes program debugging, testing and maintenance easier.
Another important feature of C is its ability to extend itself. A C program is basically a collection of functions that are supported by the C library.
We can continuously add our own functions to C library. With the availability of a large number of functions, the programming task becomes simple. The main is a special function used by the U system to tell the computer where the program starts. Every program must have exactly one main function. Txi case, the closing brace also marks the 'end. The function body contains a set of instructions to perform the given task.
In this case, the function body contains three statements out of which only the printf line is an executable statement. Although comments can appear anywhere, they cannot be nested in C. That means, we cannot have comments inside comments. Since comments do not affect the execution speed and the size of a compiled program, we should use them liberally in our programs.
They help the programmers and other users in understanding the various functions and operations of a program and serve as an aid to debugging and testing. We shall see the use of comment lines more in the examples that follow. The concepts of compilation and linking are explained later in this chapter, The printf function causes everything between the starting and the ending quotation marks to be printed out.
In this case, the output will be: I see. I remember Note that the print line ends with a semicolon. Every statement in C should end with a semicolon ; mark. This can be achieved by adding another pr-intf function as shown below: These arguments are simply stnngs of characters to be printed out.
This combination is collectively called the newline character A newline character Instructs the computer to go to the next new line. However, note that there is no space between , and I. For example, the statement - pr1'ntf "I see, n I remember! However, this is not necessary for the functions print]: See Chapter 4 for more on input and output functions. C does make a distinction between uppercase and lowercase letters.
In C, everything iswritten in lowercase letters. However, uppercase letters are used for symbolic names; representing constants. Figure 1. All C programs need a main function. Following forms are allowed. Thekeyword V0 d means that the function does not return any information to the operating system an int means that the function returns aniinteger value to the operating system.
Zf", amount ; This program when executed will produce the following output: It is a good practice to use comment lines in the beginning to give infhrmation such as name of the program, author, date, etc. Comment characters are also used in other lines to indicate line numbers. The words number and amount are variable names that are used to store numeric data. The numeric data may be either in integer form or in real form.
In C, all variables should be declared to tell the compiler what the variable names are and what type of data they hold. The variables must be declared before they are used. Declaration statements must appear at the beginning of the functions as shown in Fig. All declaration statements end with a semicolon; C supports many other data types and they are discussed in detail in Chapter 2.
A list of keywords is given in Chapter 2. Data is stored in a variable by assigning a data value to it. This is done in lines 8 and The next statement is an output statement that prints the value of number.
The print statement. Note that these arguments are Separated by a comma. The newline character n causes the next output to appear on a newline. The second and third lines begin with ltdefine instructions. Whenever a symbolic name is encountered, the compiler substitutes the value associated with the name automatically.
These values remain constant throughout the execution of the program. QMfor a period of 10 years with an initial"; 2 50 investment of Therefore I V: For example, the statement. They can also be declared as - All computations and printing are accomplished in a while loop. In this case as long as the value of year is less than or equal to the value of PERIOD, the four statements that follow while are executed.
Note that these four statements are grouped by braces. The concept and types of loops are discussed in Chapter 6. They are discussed in Chapter 3. The program shown in Fig.
The program will print the following output. The values of a and b are passed on to x and y respectively when the function mul is called. The standard mathematical functions are defined and kept as a part of C math library. If we want to use any of these mathematical functions, we must add an lfinolude instruction in the program. The program calculates cosinevalues for angles 0, 10, Some functions are written by users, like us, and many others are stored in the C library.
Library functions are grouped category-wise and stored in different files known as header files. If we want to access the functions stored in the library, it is necessary to tell the compiler about the files to be accessed.
This is achieved by using the preprocessor directive include as follows: Preprocessor directives are placed at the beginning of a program. A function is a subroutine that may include one or more state- 7 1. To write a C program, we first create functions and then put them together. A C program may contain one or more sections as shown in Fig.
The documentation section consists of a set of comment lilies giving the name of the pro. The link section provides instructions to the compiler to link functions from the system library. There are some variables that are used in more than onelfunction.