When was c programming language invented




















C was originally developed for use with the Unix [a trademark of Bell Labs] operating system, which is largely written in C, so part of the success of the language is due to the acceptance of Unix.

C, however, has spread far beyond Unix systems in the past few years, and a booming compiler industry has sprung up around it. It has proven satisfactory for other applications as well, including data base systems, telephone switching systems, numerical analysis, engineering programs, and a great deal of text-processing software.

Article :. Even if structures were thought of more abstractly, and the space for pointers could be hidden somehow, how could I handle the technical problem of properly initializing these pointers when allocating a complicated object, perhaps one that specified structures containing arrays containing structures to arbitrary depth?

The solution constituted the crucial jump in the evolutionary chain between typeless BCPL and typed C. It eliminated the materialization of the pointer in storage, and instead caused the creation of the pointer when the array name is mentioned in an expression. The rule, which survives in today's C, is that values of array type are converted, when they appear in expressions, into pointers to the first of the objects making up the array. This invention enabled most existing B code to continue to work, despite the underlying shift in the language's semantics.

More important, the new language retained a coherent and workable if unusual explanation of the semantics of arrays, while opening the way to a more comprehensive type structure. The second innovation that most clearly distinguishes C from its predecessors is this fuller type structure and especially its expression in the syntax of declarations. NB offered the basic types int and char , together with arrays of them, and pointers to them, but no further ways of composition. Generalization was required: given an object of any type, it should be possible to describe a new object that gathers several into an array, yields it from a function, or is a pointer to it.

For each object of such a composed type, there was already a way to mention the underlying object: index the array, call the function, use the indirection operator on the pointer. Analogical reasoning led to a declaration syntax for names mirroring that of the expression syntax in which the names typically appear.

In all these cases the declaration of a variable resembles its usage in an expression whose type is the one named at the head of the declaration. The scheme of type composition adopted by C owes considerable debt to Algol 68, although it did not, perhaps, emerge in a form that Algol's adherents would approve of. The central notion I captured from Algol was a type structure based on atomic types including structures , composed into arrays, pointers references , and functions procedures.

Algol 68's concept of unions and casts also had an influence that appeared later. After creating the type system, the associated syntax, and the compiler for the new language, I felt that it deserved a new name; NB seemed insufficiently distinctive. I decided to follow the single-letter style and called it C, leaving open the question whether the name represented a progression through the alphabet or through the letters in BCPL.

Their tardy introduction explains an infelicity of C's precedence rules. Its original version was exceedingly simple, and provided only included files and simple string replacements: include and define of parameterless macros. Soon thereafter, it was extended, mostly by Mike Lesk and then by John Reiser, to incorporate macros with arguments and conditional compilation. The preprocessor was originally considered an optional adjunct to the language itself.

Indeed, for some years, it was not even invoked unless the source program contained a special signal at its beginning. This attitude persisted, and explains both the incomplete integration of the syntax of the preprocessor with the rest of the language and the imprecision of its description in early reference manuals. By early , the essentials of modern C were complete.

The language and compiler were strong enough to permit us to rewrite the Unix kernel for the PDP in C during the summer of that year. Although it did not describe some additions that soon became common, this book served as the language reference until a formal standard was adopted more than ten years later.

Although we worked closely together on this book, there was a clear division of labor: Kernighan wrote almost all the expository material, while I was responsible for the appendix containing the reference manual and the chapter on interfacing with the Unix system. During , the language grew a bit: the type structure gained unsigned, long, union, and enumeration types, and structures became nearly first-class objects lacking only a notation for literals.

Equally important developments appeared in its environment and the accompanying technology. Writing the Unix kernel in C had given us enough confidence in the language's usefulness and efficiency that we began to recode the system's utilities and tools as well, and then to move the most interesting among them to the other platforms.

As described in [Johnson 78a], we discovered that the hardest problems in propagating Unix tools lay not in the interaction of the C language with new hardware, but in adapting to the existing software of other operating systems. The language changes during this period, especially around , were largely focused on considerations of portability and type safety, in an effort to cope with the problems we foresaw and observed in moving a considerable body of code to the new Interdata platform.

C at that time still manifested strong signs of its typeless origins. Pointers, for example, were barely distinguished from integral memory indices in early language manuals or extant code; the similarity of the arithmetic properties of character pointers and unsigned integers made it hard to resist the temptation to identify them.

The unsigned types were added to make unsigned arithmetic available without confusing it with pointer manipulation. To encourage people to pay more attention to the official language rules, to detect legal but suspicious constructions, and to help find interface mismatches undetectable with simple mechanisms for separate compilation, Steve Johnson adapted his pcc compiler to produce lint [Johnson 79b], which scanned a set of files and remarked on dubious constructions.

Although by the middle s Unix was in use by a variety of projects within the Bell System as well as a small group of research-oriented industrial, academic, and government organizations outside our company, its real growth began only after portability had been achieved.

During the s the use of the C language spread widely, and compilers became available on nearly every machine architecture and operating system; in particular it became popular as a programming tool for personal computers, both for manufacturers of commercial software for these machines, and for end-users interested in programming.

At the start of the decade, nearly every compiler was based on Johnson's pcc ; by there were many independently-produced compiler products. By it was clear that C needed formal standardization. While it foreshadowed the newer approach to structures, only after it was published did the language support assigning them, passing them to and from functions, and associating the names of members firmly with the structure or union containing them.

Finally, the incipient use of C in projects subject to commercial and government contract meant that the imprimatur of an official standard was important.

Thus at the urging of M. From the beginning, the X3J11 committee took a cautious, conservative view of language extensions. In the old style, external functions were declared like this: double sin ; which says only that sin is a function returning a double that is, double-precision floating-point value.

In the new style, this better rendered double sin double ; to make the argument type explicit and thus encourage better type checking and appropriate conversion. Even this addition, though it produced a noticeably better language, caused difficulties. The inevitable compromise was as good as it could have been, though the language definition is complicated by permitting both forms, and writers of portable software must contend with compilers not yet brought up to standard.

X3J11 also introduced a host of smaller additions and adjustments, for example, the type qualifiers const and volatile , and slightly different type promotion rules. Nevertheless, the standardization process did not change the character of the language. In particular, the C standard did not attempt to specify formally the language semantics, and so there can be dispute over fine points; nevertheless, it successfully accounted for changes in usage since the original description, and is sufficiently precise to base implementations on it.

Thus the core C language escaped nearly unscathed from the standardization process, and the Standard emerged more as a better, careful codification than a new invention. More important changes took place in the language's surroundings: the preprocessor and the library. The preprocessor performs macro substitution, using conventions distinct from the rest of the language. Its interaction with the compiler had never been well-described, and X3J11 attempted to remedy the situation.

X3J11 correctly believed that a full and careful description of a standard C library was as important as its work on the language itself. The C language itself does not provide for input-output or any other interaction with the outside world, and thus depends on a set of standard procedures. Thus, the X3J11 committee spent much of its time designing and documenting a set of library routines required to be available in all conforming implementations.

By the rules of the standards process, the current activity of the X3J11 committee is confined to issuing interpretations on the existing standard. As the name implies, many of these possible extensions are intended to make the language more suitable for numerical use: for example, multi-dimensional arrays whose bounds are dynamically determined, incorporation of facilities for dealing with IEEE arithmetic, and making the language more effective on machines with vector or other advanced architectural features.

Not all the possible extensions are specifically numerical; they include a notation for structure literals. C and even B have several direct descendants, though they do not rival Pascal in generating progeny.

One side branch developed early. When Johnson returned to Bell Labs in , he was disconcerted to find that the language whose seeds he brought to Canada had evolved back home; even his own yacc program had been rewritten in C, by Alan Snyder. Two ideas are most characteristic of C among languages of its class: the relationship between arrays and pointers, and the way in which declaration syntax mimics expression syntax.

They are also among its most frequently criticized features, and often serve as stumbling blocks to the beginner. In both cases, historical accidents or mistakes have exacerbated their difficulty. The most important of these has been the tolerance of C compilers to errors in type. As should be clear from the history above, C evolved from typeless languages.

It did not suddenly appear to its earliest users and developers as an entirely new language with its own rules; instead we continually had to adapt existing programs as the language developed, and make allowance for an existing body of code. Compilers in , and even well after, did not complain about usages such as assigning between integers and pointers or using objects of the wrong type to refer to structure members. Moreover, some rules designed to ease early transitions contributed to later confusion.

The notation survived in part for the sake of compatibility, in part under the rationalization that it would allow programmers to communicate to their readers an intent to pass f a pointer generated from an array, rather than a reference to a single integer. Unfortunately, it serves as much to confuse the learner as to alert the reader. None of these are the same language. So, how did C begin? The C programming language came out of Bell Labs in the early s. Derived from the typeless language BCPL, it evolved a type structure; created on a tiny machine as a tool to improve a meager programming environment.

However, not many utilities were ever written in B due to its slow nature and inability to take advantage of PDP features in the operating system. This led to Ritchie improving on B, and thus creating C. The development of C was to become the basis for Unix.

The language and compiler were strong enough to permit us to rewrite the Unix kernel for the PDP in C during the summer of the year.



0コメント

  • 1000 / 1000