Preface

           C differs from most programming languages in its use of expressions, pointers, and arrays.  For those learning C, pointers are the greatest source of confusion.  The primary aim of this text is to provide working models of how pointers are used in C as well as an introduction to their use in C++.
            Most beginners falter on the use of pointers.  Many try to avoid pointers completely, but quickly find that pointers are used extensively throughout C programs.  Some attain a partial understanding of pointers which, at first, gets them by. However, when faced with complex programming tasks, they find that pointers become a necessity.
            In most programming languages one learns about pointers only after most other topics have been discussed.  Pointers are just one more added feature of the language.  In C and in C++, however, pointers are used with every feature.  There are pointers to variables, pointers as parameters, pointers as arrays, pointers to structures, and even pointers to pointers. With each feature pointers are used differently.  The way pointers work with variables is very different from the way pointers work with arrays.  In this text, you learn pointers as you learn each feature of the language.  With variables, you learn pointers to variables; with parameters, pointers to parameters; with functions: pointers to functions; with arrays, pointers in arrays; with structures, pointers to structures.  In addition, for C++ you will learn pointers to objects, to class members, and derived objects.  Such an approach provides an understanding of the many different ways pointers are used throughout the language.
            The text is arranged in five sections.  The first section focuses on the basic structure of the language.  Variables, functions, and expressions are carefully examined.  The second section deals with arrays.  Arrays form an exception in C.  Unlike structures they are not data objects.  They are completely managed by pointers.  The third section describes data structures and file management.  The chapter on data structures introduces basic concepts such as linked lists and trees.  A special examination is made of recursion and how it operates with lists, trees, and b-trees.  The chapters on file management discuss the different types of files with special emphasis on record files b-tree indexes.  The fourth section provides an introduction to C++, covering classes and objects, their use with pointers, as well as operator overloading and inheritance.  The fifth section covers additional topics greater detail such as the pre-processor and bitwise operations. 
            Expressions play a primary role in C, whereas statements have more of an organizational function.  Expressions define the tasks that are performed in a C program, including assignments and function calls.  In a sense, there are no assignment statements in C.  There are only assignment expressions.  This reflects a design similar to function applicative languages such as Lisp. Assignments and function calls can be part of any complex expression.  They can be found in the test expressions used in while or if statements.  They may be nested within complex arithmetic expressions. 
            In C, arrays are deceptively familiar.  Arrays can be declared and managed with a format called array notation that appears to operate like arrays in other programming languages.  However, an array is not a valid C data object.  Arrays are merely sections of designated memory manage by pointers.  The array name itself is, in fact, used as a pointer.  An attempt to understand the pointer operations that manage arrays can be overwhelming.  The pointer operations on arrays involve pointer offset expressions, double indirection on a pointer, incrementation of pointers, arrays of pointer whose elements are themselves pointers, and the crucial difference between pointers to objects and pointers to arrays.  Even coping with arrays of structures can become very involved, especially when the member of a structure element is itself an array.  For these reasons, arrays are handled with care in their own separate section.  Five separate chapters are devoted to examining arrays and their pointer operations.
            There are a great many functions in C designed to manage files. Reflecting a design developed for UNIX, all C files have one logical structure, a byte stream.  This stream can be accessed in different ways depending on the file function used.  Certain file functions access a file as formatted text, while file functions access a file as a record file.  Yet, in each case, one file is not considered to be physically different from the other.  There is a distinction made between binary and text files that may or may not apply depending upon the operating system used.  In UNIX there is no distinction, whereas in MS DOS there is.
            The file functions can be organized according to the way they access a file.  In this text the file functions are categorized into character text, line text, formatted text, record sequential, and random access file functions.  File management techniques involving data hiding and encapsulation are also discussed.
            Building on an understanding of C, it is much easier to learn C++.  The key component in C++ is the class which has similar features to that that of structures in C.  In this text, C++ structures are explained first, noting their similarities and differences from C structures.  Then classes are discussed along with their impact on program organization and style.  Using the same programs developed earlier in the text for C, C++ versions are examined.  Comparison of C and C++ versions of the same programs helps to highlight the similarities and differences between C and C++.  Though only a introduction to C++ can be presented in this text, all the key components are covered including pointers, overloading, constructors, and inheritance. 
            The programming styles used in C are another source of confusion to the beginner.  Among programming languages there are many kinds of programming styles, the most common being procedural, assembler, and function applicative styles.  Usually a programming language has only one programming style.  Pascal has a procedural style.  Lisp has a function applicative style.  Assembly language has an assembler style.  C, however, has all three.  C can have a procedural style, assembler style, and a function applicative style.  C programs will often integrate all three.  This gives C  great flexibility, but can easily lead to obscure code.  Beginners can easily become lost.  Beginners may start reading statements arranged in a procedural way and suddenly find themselves reading statements arranged in a function applicative way. 
            Therefore, it is best for beginners to work with C programs that use only one of these programming styles.  Both assembler and function applicative styles tend to be obscure, while the procedural style is very clear.  For this reason this text uses a procedural style in its approach to the C language.  There are some function applicative and assembler arrangements that are commonly used in most C programs.  But in this text, such arrangements are introduced within the context of a procedural style.  Such an approach keeps a C program from becoming what C programs too often becomes - obscure.  It is very easy to write unintelligible C programs.
            For beginners in C, clarity is more important than cleverness.  Because the language is so flexible, it is easy to lose one's way.  For this reason the text uses many short, clear, and simple programs.  Each highlights a new feature of C.  Slightly larger programs carefully integrate each new feature.  Any program contained in a listing is a working program and can be compiled on any compiler.