Insert Menu

Chapter 5 - C and C++ Programming

Visual C++ 6: The Complete Reference
Chris H. Pappas and William H. Murray, III
  Copyright 1998 The McGraw-Hill Companies

C Archives
Our archeological dig for the origins of the C language begins with a discussion of the UNIX operating system, since both the system and most of the programs that run on it are written in C. However, this does not mean that C is tied to UNIX or any other operating system or machine. The UNIX/C co-development environment has given C a reputation for being a system programming language because it is useful for writing compilers and operating systems. C is also very useful for writing major programs in many different domains.
The UNIX OS was originally developed in 1969 on what would now be considered a small DEC PDP-7 at Bell Laboratories in Murray Hill, New Jersey. UNIX was written entirely in PDP-7 assembly language. By design, this operating system was intended to be “programmer friendly,” providing useful development tools, lean commands, and a relatively open environment. Soon after the development of UNIX, Ken Thompson implemented a compiler for a new language called B.
At this point it is helpful to examine the origins and history behind Ken Thompson’s B language, a direct predecessor to C. Following is a comprehensive C lineage:
Language
Origins/Inventor
Algol 60
Designed by an international committee in early 1960
CPL
(Combined Programming Language) Developed at both Cambridge and the University of London in 1963
BCPL
(Basic Combined Programming Language) Developed at Cambridge by Martin Richards in 1967
B
Developed by Ken Thompson, Bell Labs, in 1970
C
Developed by Dennis Ritchie, Bell Labs, in 1972
Then, in 1983, the American National Standards Institute (ANSI) committee was formed for the purpose of creating ANSI C—a standardization of the C language.
Algol 60 was a language that appeared only a few years after FORTRAN was introduced. This new language was more sophisticated and had a strong influence on the design of future programming languages. Its authors paid a great deal of attention to the regularity of syntax, modular structure, and other features usually associated with high-level structured languages. Unfortunately, Algol 60 never really caught on in the United States. Many say this was due to the language’s abstractness and generality.
The inventors of CPL (Combined Programming Language) intended to bring Algol 60’s lofty intent down to the realities of an actual computer. However, just as Algol 60 was hard to learn and difficult to implement, so was CPL. This led to its eventual downfall. Still clinging to the best of what CPL had to offer, the creators of BCPL (Basic Combined Programming Language) wanted to boil CPL down to its basic good features.
When Ken Thompson designed the B language for an early implementation of UNIX, he was trying to further simplify CPL. He succeeded in creating a very sparse language that was well suited for use on the hardware available to him. However, both BCPL and B may have carried their streamlining attempts a bit too far; they became limited languages, useful only for dealing with certain kinds of problems.
For example, no sooner had Ken Thompson implemented the B language than a new machine, called the PDP-11, was introduced. UNIX and the B compiler were immediately transferred to this new machine. While the PDP-11 was a larger machine than its PDP-7 predecessor, it was still quite small by today’s standards. It had only 24K of memory, of which the system used 16K, and one 512K fixed disk. Some thought was given to rewriting UNIX in B, but the B language was slow because of its interpretive design. There was another problem as well: B was word oriented, but the PDP-11 was byte oriented. For these reasons, work was begun in 1971 on a successor to B, appropriately named C.
Dennis Ritchie is credited with creating C, which restored some of the generality lost in BCPL and B. He accomplished this through a shrewd use of data types while maintaining the simplicity and direct access to the hardware that were the original design goals of CPL.
Many languages developed by a single individual (C, Pascal, Lisp, and APL) contain a cohesiveness that is missing from those created by large programming teams (Ada, PL/I, and Algol 60). It is also typical for a language written by one person to reflect the author’s field of expertise. Dennis Ritchie was noted for his work in systems software—computer languages, operating systems, and program generators.
Given Ritchie’s areas of expertise, it is easy to understand why C is a language of choice for systems software design. C is a relatively low-level language that allows you to specify every detail in an algorithm’s logic to achieve maximum computer efficiency. But C is also a high-level language that can hide the details of the computer’s architecture, thereby increasing programming efficiency.
C vs. Older High-level Languages
At this point, you may be asking, “How does C compare to other programming languages?” A possible continuum is shown in Figure 5-1. If you start at the bottom of the continuum and move upward, you go from the tangible and empirical to the elusive and theoretical. The dots represent major advancements, with many steps left out. Early ancestors of the computer, like the Jacquard loom (1805) and Charles Babbage’s “analytical engine” (1834), were programmed in hardware. The day may well come when we will program a machine by plugging a neural path communicator into a socket implanted into the temporal lobe (language memory) or Broca’s area (language motor area) of the brain’s cortex.
Figure 5-1: Theoretical evolution of programming languages
The first assembly languages, which go back to the original introduction of electronic computers, provide a way of working directly with a computer’s built-in instruction set and are fairly easy to learn. Because assembly languages force you to think in terms of hardware, you had to specify every operation in the machine’s terms. Therefore, you were always moving bits into or out of registers, adding them, shifting register contents from one register to another, and finally storing the results in memory. This was a tedious and error-prone endeavor.
The first high-level languages, such as FORTRAN, were created as alternatives to assembly languages. High-level languages were much more general and abstract, and they allowed you to think in terms of the problem at hand rather than in terms of the computer’s hardware.
Unfortunately, the creators of high-level languages made the fallacious assumption that everyone who had been driving a standard, so to speak, would prefer driving an automatic. Excited about providing ease in programming, they left out some necessary options. FORTRAN and Algol are too abstract for systems-level work; they are problem-oriented languages, the kind used for solving problems in engineering, science, or business. Programmers who wanted to write systems software still had to rely on their machine’s assembler.
In reaction to this situation, a few systems software developers took a step backward—or lower, in terms of the continuum—and created the category of machine-oriented languages. As you saw in C’s genealogy, BCPL and B fit into this class of very low-level software tools. These languages were excellent for a specific machine but not much use for anything else; they were too closely related to a particular architecture. The C language is one step above machine-oriented languages but still a step below most problem-solving languages. C is close enough to the computer to give you great control over the details of an application’s implementation, yet far enough away to ignore the details of the hardware. This is why the C language is considered at once a high- and a low-level language.
Advantages of C
Every computer language you use has a definite look to its source code. APL has its hieroglyphic appearance, assembly language its columns of mnemonics, and Pascal its easily read syntax. And then there’s C. Many programmers encountering C for the first time will find its syntax cryptic and perhaps intimidating. C contains very few of the friendly English-like syntax structures found in many other programming languages. Instead, C presents the software engineer with unusual-looking operators and a plethora of pointers. New C programmers will soon discover a variety of language characteristics whose roots go back to C’s original hardware/software progenitor. The following sections highlight the strengths of the C language.
Optimal Code Size
There are fewer syntax rules in C than in many other languages, and it is possible to write a top-quality C compiler that will operate in only 256K of total memory. There are actually more operators and combinations of operators in C than there are keywords.
Terse Set of Keywords
The original C language, as developed by Dennis Ritchie, contained a mere 27 keywords. The ANSI C standard has added several reserved words. Microsoft C/C++ further enhances the instruction set and brings the total Microsoft C/C++ keyword count to over 70.
Many of the functions commonly defined as part of other programming languages are not included in C. For example, C does not contain any built-in input and output capabilities, nor does it contain any arithmetic operations (beyond those of basic addition and subtraction) or string-handling functions. Since any language missing these capabilities is of little use, C provides a rich set of library functions for input/output, arithmetic operations, and string manipulation. This agreed-upon library set is so commonly used that it can almost be seen as part of the language itself. One of the strengths of C, however, is its loose structure, which enables you to recode these functions easily.
Lightning-fast Executables
The C code produced by most compilers tends to be very efficient. The combination of a small language, a small run-time system, and the fact that the language is close to the hardware makes many C programs run at speeds close to their assembly language equivalents.
Limited Type Checking
Unlike Pascal, which is a strongly typed language, C treats data types somewhat more loosely. This is a carryover from the B language, which was also a loosely typed language. This looseness allows you to view data in different ways. For example, at one point in a program, the application may need to see a variable as a character and yet, for purposes of uppercasing (by subtracting 32), may want to see the same memory cell as the ASCII equivalent of the character.
Top-down Design Implementations
C contains all of the control structures you would expect of a modern-day language. This is impressive when you consider C’s 1971 incubation period, which predated formal structured programming. For loops, if and if-else constructs, case (switch) statements, and while loops are all incorporated into the language. C also provides for the compartmentalization of code and data by managing their scope. For example, C provides local variables for this purpose and calls-by-value for subroutine data privacy.
Modular Structure
C supports modular programming, which is the concept of separate compilation and linking. This allows you to recompile only the parts of a program that have been changed during development. This feature can be extremely important when you are developing large programs, or even medium-size programs on slow systems. Without support for modular programming, the amount of time required to compile a complete program can make the change, compile, test, and modify cycle prohibitively slow.
Transparent Interface to Assembly Language
There is a well-defined method for calling assembly language routines from most C compilers. Combined with the separation of compilation and linking, this makes C a very strong contender in applications that require a mix of high-level and assembler routines. C routines can also be integrated into assembly language programs on most systems.
Bit Manipulation
Often in systems programming, it is necessary to manipulate objects at the bit level. Naturally, with C’s origins so closely tied to the UNIX operating system, the language provides a rich set of bit-manipulation operators.
Pointer Data Types
One of the features an operating system requires of a language is the ability to address specific areas of memory. This capability also enhances the execution speed of a program. The C language meets these design requirements by using pointers (discussed in Chapter 10). While it is true that other languages implement pointers, C is noted for its ability to perform pointer arithmetic. For example, if the variable student_ record_ptr points to the first element of an array student_records, then student_record_ptr + 1 will be the address of the second element of student_records.
Extensible Structures
All arrays in C are one-dimensional. Multidimensional arrangements are built from combinations of these one-dimensional arrays. Arrays and structures (records) can be joined in any manner desired, creating database organizations that are limited only by the programmer’s ability. Arrays are discussed in more detail in Chapter 9.
Memory Efficient
For many of the same reasons that C programs tend to be fast, they tend to be very memory efficient. The lack of built-in functions saves programs from having to carry around support for functions that are not needed by that application.
Cross-platform Portability
Portability is a measure of the ease of converting a program running on one computer or operating system to another computer or operating system. Programs written in C are among the most portable in the modern computer world. This is especially true in the mini- and microcomputer worlds.
Powerful Library Routines
There are many commercial function libraries available for all popular C compilers. Libraries are available for graphics, file handling, database support, screen windowing, data entry, communications, and general support functions. By using these libraries, you can save a great deal of development time.
Disadvantages of C
There are no perfect programming languages. Different programming problems require different solutions. It is the software engineer’s task to choose the best language for a project. On any project, this is one of the first decisions you need to make, and it is nearly irrevocable once you start coding. The choice of a programming language can also make the difference between a project’s success and failure. The following sections cover some of the weaknesses of the C language to give you a better idea of when to use and when not to use C for a particular application.
Limited Type Checking!
The fact that C is not strongly typed is one of its strengths, but it is also one of its weaknesses. Technically, typing is a measure of how closely a language enforces the use of variable types. (For example, integer and floating-point are two different types of numbers.) In some languages, it is illegal to assign one data type to another without invoking a conversion function. This protects the data from being compromised by unexpected roundoffs.
As discussed earlier, C will allow an integer to be assigned to a character variable, and vice versa. What this means to you is that you are going to have to properly manage your variables. For experienced programmers, this will present no problem. However, novice program developers may want to remind themselves that this can be the source of side effects.
A side effect in a language is an unexpected change to a variable or other item. Because C is not a strongly typed language, it gives you great flexibility to manipulate data. For example, the assignment operator (=) can appear more than once in the same expression. This flexibility, which you can use to your advantage, means that expressions can be written that have no clear and definite value. Restricting the use of the assignment and similar operators, or eliminating all side effects and unpredictable results, would have seriously lessened much of C’s power and appeal as a high-level assembly language.
Limited Run-time Monitors
C’s lack of checking in the run-time system can cause many mysterious and transient problems to go undetected. For example, the run-time system would not warn you if your application exceeded an array’s bounds. This is one of the costs of streamlining a compiler for the sake of speed and efficiency.
C Is Not for Children!
C’s tremendous range of features—from bit manipulation to high-level formatted I/O—and its relative consistency from machine to machine have led to its acceptance in science, engineering, and business applications. It has directly contributed to the wide availability of the UNIX operating system on computers of all types and sizes.
Like any other powerful tool, however, C imposes a heavy responsibility on its users. C programmers need to acquire a discipline very quickly, adopting various rules and conventions in order to make their programs understandable both to themselves, long after the programs were written, and to others trying to analyze the code for the first time. In C, programming discipline is essential. The good news is that it comes almost automatically with practice.

Books24x7.com, Inc 2000 –  


Visual C++ 6(c) The Complete Reference
Visual Studio 6: The Complete Reference
ISBN: B00007FYGA
EAN: N/A
Year: 1998
Pages: 207

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net