C programming language
From Freepedia
The C programming language is a standardized imperative computer programming language developed in the early 1970s by Ken Thompson and Dennis Ritchie for use on the UNIX operating system. It has since spread to many other operating systems, and is one of the most widely used programming languages. C is prized for its efficiency, and is the most popular programming language for writing system software, though it is also used for writing applications. It is also commonly used in computer science education, despite not being designed for novices.
Contents |
Features
Overview
C is a relatively minimalist programming language that operates close to the hardware, and is more similar to assembly language than to most high-level languages. Indeed, C is sometimes referred to as "portable assembly", reflecting its important difference from low-level languages such as assembly languages: C code can be compiled to run on almost any computer, more than any other language in existence, while any given assembly language runs on at most a few very specific models of computers. For these reasons C has been called a medium-level language.
C was created with one important goal in mind: to make it easier to write large programs with fewer errors in the procedural programming paradigm, but without encumbering the writer of the C compiler by complex language features.
To this end, C has the following important features:
- A simple core language, with important functionality such as math functions or file handling provided by sets of library routines instead
- Focus on the procedural programming paradigm, with facilities for programming in a structured style
- A simple type system which prevents many operations that are not meaningful
- Use of a preprocessor language, the C preprocessor, for tasks such as defining macros and including multiple source code files
- Low-level unchecked access to computer memory via the use of pointers
- A minimalistic set of keywords
- Parameters that are passed either by value or by reference via an explicitly managed pointer.
- Function pointers, which allow for a rudimentary form of closures and polymorphism
- Lexical variable scoping
- Records, or user-defined aggregate datatypes (
structs) which allow related data to be combined and manipulated as a whole
Some features that C lacks that are found in other languages include:
- Type safety
- Automatic garbage collection
- Classes or objects with behavior (see object-oriented programming)
- An advanced type system
- Closures
- Nested functions
- Generic programming
- Overloading and operator overloading
- Native support for multithreading and networking
Although the list of useful features C lacks is long, this has in a way been important to its acceptance, because it allows new compilers to be written quickly for it on new platforms, and because it keeps the programmer in close control of what the program is doing. This is what often allows C code to run more efficiently than many other languages. Typically only hand-tuned assembly language code runs faster, since it has full control of the machine, but advances in C compilers, and new complexity in modern processors, have gradually narrowed this gap.
One consequence of C's wide acceptance and efficiency is that the compilers, libraries, and interpreters of other higher-level languages are often implemented in C.
"hello, world" example
The following simple application appeared in the first edition of K&R, and has become a standard introductory program in most programming textbooks, regardless of language. The program prints out "hello, world" to standard output, which is usually a terminal or screen display. However, it might be a file or some other hardware device, including the bit bucket, depending on how standard output is mapped at the time the program is executed.
main()
{
printf("hello, world\n");
}
The above program will compile correctly on most modern compilers that are not in compliance mode. However, it produces several warning messages when compiled with a compiler that conforms to the ANSI C standard. Additionally, the code will not compile if the compiler strictly conforms to the C99 standard, as a return value of type int will no longer be assumed if the source code has not specified otherwise. These messages can be eliminated with a few minor modifications to the original program:
#include <stdio.h>
int main(void)
{
printf("hello, world\n");
return 0;
}
What follows is a line-by-line analysis of the above program:
#include <stdio.h>
This first line of the program is a preprocessing directive, #include. This causes the preprocessor — the first tool to examine source code when it is compiled — to substitute for that line the entire text of the file or other entity to which it refers. In this case, the header stdio.h — which contains the definitions of standard input and output functions — will replace that line. The angle brackets surrounding stdio.h indicate that stdio.h can be found using an implementation-defined search strategy. Double quotes may also be used for headers, thus allowing the implementation to supply (up to) two strategies. Typically, angle brackets are used for headers supplied by the implementation, and double quotes for "in-house" headers.
int main(void)
This next line indicates that a function named main is being defined. The main function serves a special purpose in C programs. When they are executed, main() is the first function called. The portion of the code that reads int indicates that the return value — the value to which the main function will evaluate — is an integer. The portion that reads (void) indicates that the main function takes no arguments. See also void.
{
This opening curly brace indicates the beginning of the definition of the main function.
printf("hello, world\n");
This line calls — looks up and then executes the code for — a function named printf, which was declared in the included header stdio.h. In this call, the printf function is passed — provided with — a single argument, the address of the first character in the string literal "hello, world\n". The sequence that reads \n is an escape sequence that is translated to the EOL—or end-of-line—character, which is intended to move the output device's current position indicator to the beginning of the next line. The return value of the printf function is of type int, but no use was made of it so it will be quietly discarded.
return 0;
This line terminates the execution of the main function and causes it to return the integral value 0.
}
This closing curly brace indicates the end of the code for the main function.
If the above code were compiled, it would do the following:
- Print the string "hello, world" onto the standard output device (typically but by no means always a terminal),
- Move the current position indicator to the beginning of the next line,
- Then return the integer zero to the application's executor.
Types
C has a type system similar to that of other ALGOL descendants such as Pascal, although different in a number of ways. There are types for integers of various sizes, both signed and unsigned, floating-point numbers, characters, enumerated types (enum), records (struct), and untagged unions (union).
C makes extensive use of pointers, a very simple type of reference that stores the address of a memory location. Pointers can be dereferenced to retrieve the data stored at that address. The address can be manipulated with regular assignment and pointer arithmetic. At runtime, a pointer represents a memory address. At compile-time, it is a complex type that represents both the address and the type of the data. This allows expressions including pointers to be type-checked. Pointers are used for many different purposes in C. Text strings are commonly represented with a pointer to an array of characters. Dynamic memory allocation, which is described below, is performed using pointers.
A null pointer has a reserved value indicating that it points to no valid location. These are useful for indicating special cases such as the next pointer in the final node of a linked list. Dereferencing a null pointer causes unpredictable behavior. Pointers to type void also exist, and point to objects of unknown type. These are particularly useful for generic programming. Since the size and type of the objects they point to is not known they cannot be dereferenced, but they can be converted to other types of pointers.
Array types in C are of a fixed, static size known at compile-time; this isn't too much of a hindrance in practice, since one can allocate blocks of memory at runtime using the standard library and treat them like arrays. Unlike many other languages, C typically represents arrays just as it does pointers: as a memory address with associated data type. In this case, index values are translated into memory addresses by computing an offset from the base address of the array. The array index is not checked against the array bounds, which can result in illegal memory accesses. This may reveal confidential data, corrupt data, or cause run-time errors or exceptions, depending on the situation and the detailed run time environment.
C also supplies multi-dimensional arrays. The index values of the arrays are assigned in row-major order. Semantically these arrays function like arrays of arrays, but physically they are stored as a single one-dimensional array with computed offsets.
C is often used in low-level systems programming, where it may be necessary to treat an integer as a memory address, a double-precision value as an integer, or one type of pointer as another. For such cases C provides casting, which forces the explicit conversion of a value from one type to another. The use of casts sacrifices some of the safety normally provided by the type system.
Data storage
One of the most important functions of a programming language is to provide facilities for managing memory and the objects that are stored in memory. C provides three distinct ways to allocate memory for objects:
- Static memory allocation: space for the object is provided in the binary at compile-time; these objects have an extent (or lifetime) as long as the binary which contains them exists
- Automatic memory allocation: temporary objects can be stored on the stack, and this space is automatically freed and reusable after the block they are declared in is left
- Dynamic memory allocation: blocks of memory of any desired size can be requested at run-time using the library function
malloc()from a region of memory called the heap; these blocks are reused after the library functionfree()is called on them
These three approaches are appropriate in different situations and have various tradeoffs. For example, static memory allocation has no allocation overhead, automatic allocation has a small amount of overhead during initialization, and dynamic memory allocation can potentially have a great deal of overhead for both allocation and deallocation. On the other hand, stack space is typically much more limited than either static memory or heap space, and only dynamic memory allocation allows allocation of objects whose size is only known at run-time. Most C programs make extensive use of all three.
Where possible, automatic or static allocation is usually preferred because the storage is managed by the compiler, freeing the programmer of the error-prone hassle of manually allocating and releasing storage. Unfortunately, many data structures can grow in size at runtime; since automatic and static allocations must have a fixed size at compile-time, there are many situations in which dynamic allocation must be used. Variable-sized arrays are a common example of this (see "malloc" for an example of dynamically allocated arrays).
Syntax
Main article: C syntax
Unlike languages like Fortran 77, C is free-form, allowing programmers to use arbitrary whitespace (rather than rigid lines) in laying out their code. Comments can be included either between the delimiters /* and */, or (in C99) following // until the end of the line.
Each source file contains declarations and function definitions. Function definitions, in turn, contain declarations and statements. Declarations either define new types using keywords such as struct, union, and enum, or assign types to and reserve storage for new variables, usually by writing the type followed by the variable name. Keywords such as char and int, as well as the pointer-to symbol *, specify built-in types. Sections of code are enclosed in braces ({ and }) to indicate the extent to which declarations and control structures apply.
As an imperative language, C depends on statements to do most of the work. Most statements are expression statements which simply cause an expression to be evaluated -- and, in the process, cause variables to receive new values or values to be printed. Control-flow statements are also available for conditional or iterative execution, constructed with reserved keywords such as if, else, switch, do, while, and for. Arbitrary jumps are possible with goto. A variety of built-in operators perform primitive arithmetic, logical, comparative, bitwise, and array indexing operations and assignment. Expressions can also call functions, including a large number of standard library functions, for performing many common tasks.
Criticism
A popular saying, repeated by such notable language designers as Bjarne Stroustrup, is that "C makes it easy to shoot yourself in the foot." [1] In other words, C permits many operations that are generally not desirable, and thus many simple errors made by a programmer are not detected by the compiler or even when they occur at runtime. This leads to programs with unpredictable behavior and security holes. The safe C dialect Cyclone addresses some of these problems.
Part of the reason for this is to avoid compile- and run-time checks that were too expensive when C was originally designed. Another reason is the desire to keep C as efficient and flexible as possible; the more powerful a language, the more difficult it is to prove things about programs written in it. Some checks were also relegated to external tools, such as those discussed in Compiler-external static-checking tools below.
Memory allocation
One problem with C is that automatically and dynamically allocated objects are not initialized; they initially have whatever value is present in the memory space they are assigned. This value is highly unpredictable, and can vary between two machines, two program runs, or even two calls to the same function. If the program attempts to use such an uninitialized value, the results are usually unpredictable. Many modern compilers try to detect and warn about this problem, but both false positives and false negatives occur.
Another common problem is that heap memory cannot be reused until it is explicitly released by the programmer with free(). The result is that if the programmer accidentally forgets to free memory, but continues to allocate it, more and more memory will be consumed over time. This is called a memory leak. Conversely, it is possible to release memory too soon, and then continue to use it. Because the allocation system can reuse the memory at any time for unrelated reasons, this results in insidiously unpredictable behavior. These issues in particular are ameliorated in languages with automatic garbage collection.
Pointers
Pointers are one primary source of danger; because they are unchecked, a pointer can be made to point to any object of any type, including code, and then written to, causing unpredictable effects. Although most pointers point to safe places, they can be moved to unsafe places using pointer arithmetic, the memory they point to may be deallocated and reused (dangling pointers), they may be uninitialized (wild pointers), or they may be directly assigned any value using a cast or through another corrupt pointer. Another problem with pointers is that C freely allows conversion between any two pointer types. Other languages attempt to address these problems by using more restrictive reference types.
Arrays
Although C has native support for static arrays, it does not verify that array indexes are valid (bounds checking). For example, one can write to the sixth element of an array with five elements, yielding generally undesirable results. This is called a buffer overflow. This has been notorious as the source of a number of security problems in C-based programs. On the other hand, since bounds checking elimination technology was largely nonexistent when C was defined, bounds checking came with a severe performance penalty, particularly in numerical computation. It was also believed to be inconsistent with C's minimalist approach.
Multidimensional arrays are necessary in numerical algorithms (mainly from applied linear algebra) to store matrices. The structure of the C array is very well adapted and fit for this particular task, provided one is prepared to count one's indices from 0 instead of 1. This issue is discussed in the book Numerical Recipes in C, Chap. 1.2, page 20 ff (read online). In that book there is also a solution based on negative addressing which introduces other dangers.
Variadic functions
Yet another common problem are variadic functions, which take a variable number of arguments. Unlike other prototyped C functions, checking the arguments of variadic functions at compile-time is not mandated by the standard, and is impossible in general without additional information. If the wrong type of data is passed, the effect is unpredictable, and often fatal. Variadic functions also handle null pointer constants in an unexpected way. For example, the printf family of functions supplied by the standard library, used to generate formatted text output, is notorious for its error-prone variadic interface, which relies on a format string to specify the number and type of trailing arguments.
Type-checking of variadic functions from the standard library is a quality of implementation issue, however, and many modern compilers do in particular type-check printf calls, producing warnings if the argument list is inconsistent with the format string. However, not all printf calls can be checked statically, since the format string can be built at runtime, and other variadic functions typically remain unchecked.
Syntax
Although mimicked by many languages because of its widespread familiarity, C's syntax has been often targeted as one of its weakest points. For example, Kernighan and Ritchie say in the second edition of The C Programming Language, "C, like any other language, has its blemishes. Some of the operators have the wrong precedence; some parts of the syntax could be better." Bjarne Stroustrup has also derided C++'s syntax, which is very similar to that of C: "Within C++, there is a much smaller and cleaner language struggling to get out. [...] the C++ semantics is much cleaner than its syntax." [2] Some specific problems worth noting are:
- A function prototype which does not specify any parameters actually implicitly allows any set of parameters, a syntax problem introduced for backward compatibility with K&R C, which lacked prototypes.
- Some questionable choices of operator precedence, as mentioned by Kernighan and Ritchie above, such as
==binding more tightly than&and|in expressions likex & 1 == 0. - The use of the
=operator, used in mathematics for equality, to indicate assignment, leading to unintended assignments in comparisons and a false impression that assignment is transitive. Having=denote assignment and==equality was a deliberate decision by Ritchie, who noted that assignment occurs much more often than comparisons. - A lack of infix operators for complex objects, particularly for string operations, making programs which rely heavily on these operations difficult to read.
- Heavy reliance on punctuation-based symbols even where this is arguably less clear, such as "&&" and "||" instead of "and" and "or".
- The un-intuitive declaration syntax, particularly for function pointers. In the words of language researcher Damian Conway speaking about the very similar C++ declaration syntax:
- Specifying a type in C++ is made difficult by the fact that some of the components of a declaration (such as the pointer specifier) are prefix operators while others (such as the array specifier) are postfix. These declaration operators are also of varying precedence, necessitating careful bracketing to achieve the desired declaration. Furthermore, if the type ID is to apply to an identifier, this identifier ends up at somewhere between these operators, and is therefore obscured in even moderately complicated examples (see Appendix A for instance). The result is that the clarity of such declarations is greatly diminished.
- Ben Werther & Damian Conway. A Modest Proposal: C++ Resyntaxed. Section 3.1.1. 1996.
Maintenance problems
There are other problems in C that don't directly result in bugs or errors, but make it harder for inexperienced programmers to build a robust, maintainable, large-scale system. Examples of these include:
- A fragile system for importing definitions (
#include) that relies on literal text inclusion and redundantly keeping prototypes and function definitions in sync, and drastically increases build times. - A cumbersome compilation model that forces manual dependency tracking and inhibits compiler optimizations between modules (except by link-time optimization).
- A weak type system that lets many clearly erroneous programs compile without errors.
- The difficulty of creating opaque structures, which results in programs that tend to violate information hiding.
Compiler-external static-checking tools
Tools have been created to help C programmers avoid these errors in many cases.
Automated source code checking and auditing is fruitful in any language, and for C many such tools exist such as Lint. A common practice is to use Lint to detect questionable code when a program is first written. Once a program passes Lint, it is then compiled using the C compiler.
There are also compilers, libraries and operating system level mechanisms for performing array bounds checking, buffer overflow detection and automatic garbage collection, that are not a standard part of C.
Cproto is a program that will read a C source file and output prototypes of all the functions within the source file. This program can be used in conjuction with the "make" command to create new files containing prototypes each time the source file has been changed. These prototype files can be included by the original source file (e.g., as "filename.p"), which reduces the problems of keeping function definitions and source files in agreement.
It should be recognized that these tools are not a panacea. Because of C's flexibility, some types of errors involving misuse of variadic functions, out-of-bound array indexing, and incorrect memory management cannot be detected on some architectures without incurring a significant performance penalty. However, some common cases can be recognized and accounted for.
History
Early developments
The initial development of C occurred at AT&T Bell Labs between 1969 and 1973; according to Ritchie, the most creative period occurred in 1972. It was named "C" because many of its features were derived from an earlier language called "B". Accounts differ regarding the origins of the name "B": Ken Thompson credits the BCPL programming language, but he had also created a language called Bon in honor of his wife Bonnie.
There are many legends as to the origin of C and its related operating system, Unix, including:
- The development of C was the result of the programmers' desire to play Space Travel. They had been playing it on their company's mainframe, but being underpowered and having to support about 100 users, Thompson and Ritchie found they didn't have sufficient control over the spaceship to avoid collisions with the wandering space rocks. Thus, they decided to port the game to an idle PDP-7 in the office. But it didn't have an operating system (OS), so they set about writing one. Eventually they decided to port the operating system to the office's PDP-11, but this was onerous since all the code was in assembly language. They decided to use a higher-level portable language so the OS could be ported easily from one computer to another. They looked at using B, but it lacked functionality to take advantage of some of the PDP-11's advanced features. So they set about creating the new language, C.
- The justification for obtaining the original computer that was used to develop Unix was to create a system to automate the filing of patents. The original version of Unix was developed in assembly language. Later, the C language was developed in order to rewrite the operating system.
By 1973, the C language had become powerful enough that most of the UNIX kernel, originally written in PDP-11/20 assembly language, was rewritten in C. This was one of the first operating system kernels implemented in a language other than assembly, earlier instances being the Multics system (written in PL/I), TRIPOS (written in BCPL), and MCP (Master Control Program) for Burroughs B5000 written in ALGOL in 1961.
K&R C
In 1978, Ritchie and Brian Kernighan published the first edition of The C Programming Language. This book, known to C programmers as "K&R", served for many years as an informal specification of the language. The version of C that it describes is commonly referred to as "K&R C." (The second edition of the book covers the later ANSI C standard, described below.)
K&R introduced the following features to the language:
-
structdata types -
long intdata type -
unsigned intdata type - The
=+operator was changed to+=, and so forth (=+was confusing the C compiler's lexical analyzer; for example,i =+ 10compared withi = +10).
K&R C is often considered the most basic part of the language that is necessary for a C compiler to support. For many years, even after the introduction of ANSI C, it was considered the "lowest common denominator" that C programmers stuck to when maximum portability was desired, since not all compilers were updated to fully support ANSI C, and reasonably well-written K&R C code is also legal ANSI C.
In these early versions of C, only functions that returned a non-integer value needed to be declared before use. A function used without any previous declaration was assumed to return an integer. Example call requiring previous declaration:
long int SomeFunction();
int CallingFunction()
{
long int ret;
ret = SomeFunction();
}
Example call not requiring previous declaration:
int SomeOtherFunction()
{
return 0;
}
int CallingFunction()
{
int ret;
ret = SomeOtherFunction();
}
Since the K&R prototype did not include any information about function arguments, function parameter type checks were not performed, although some compilers would issue a warning message if a function was called with the wrong number of arguments.
In the years following the publication of K&R C, several "unofficial" features were added to the language, supported by compilers from AT&T and some other vendors. These included:
-
voidfunctions andvoid *data type - functions returning
structoruniontypes -
structfield names in a separate name space for each struct type - assignment for
structdata types -
constqualifier to make an object read-only - a standard library incorporating most of the functionality implemented by various vendors
- enumerations
- the single-precision
floattype
ANSI C and ISO C
During the late 1970s, C began to replace BASIC as the leading microcomputer programming language. During the 1980s, it was adopted for use with the IBM PC, and its popularity began to increase significantly. At the same time, Bjarne Stroustrup and others at Bell Labs began work on adding object-oriented programming language constructs to C. The language they produced, called C++, is now the most common application programming language on the Microsoft Windows operating system; C remains more popular in the Unix world. Another language developed around that time is Objective-C which also adds object oriented programming to C. While, now, not as popular as C++, it is used to develop Mac OS X's Cocoa applications.
In 1983, the American National Standards Institute (ANSI) formed a committee, X3J11, to establish a standard specification of C. After a long and arduous process, the standard was completed in 1989 and ratified as ANSI X3.159-1989 "Programming Language C". This version of the language is often referred to as ANSI C, or sometimes C89 (to distinguish it from C99).
In 1990, the ANSI C standard (with a few minor modifications) was adopted by the International Organization for Standardization (ISO) as ISO/IEC 9899:1990. This version is sometimes called C90. Therefore, the terms "C89" and "C90" refer to essentially the same language.
One of the aims of the ANSI C standardization process was to produce a superset of K&R C, incorporating many of the unofficial features subsequently introduced. However, the standards committee also included several new features, such as function prototypes (borrowed from C++), and a more capable preprocessor.
ANSI C is now supported by almost all the widely used compilers. Most of the C code being written nowadays is based on ANSI C. Any program written only in standard C is guaranteed to perform correctly on any platform with a conforming C implementation. However, many programs have been written that will only compile on a certain platform, or with a certain compiler, due to (i) the use of non-standard libraries, such as for graphical displays, and (ii) some compilers' not adhering to the ANSI C standard, or its successor, in their default mode, or (iii) reliance on the exact size of certain datatypes as well as on the endianness of the platform.
You can use the __STDC__ macro to split your code into ANSI and K&R sections.
#if __STDC__ extern int getopt(int,char * const *,const char *); #else extern int getopt(); #endif
Some suggest using "#if __STDC__", like above, over "#ifdef __STDC__" because some compilers set __STDC__ to zero to indicate non-ANSI compliance.
C99
After the ANSI standardization process, the C language specification remained relatively static for some time, whereas C++ continued to evolve. (Normative Amendment 1 created a new version of the C language in 1995, but this version is rarely acknowledged.) However, the standard underwent revision in the late 1990s, leading to the publication of ISO 9899:1999 in 1999. This standard is commonly referred to as "C99". It was adopted as an ANSI standard in March 2000.
The new features in C99 include:
- inline functions
- variables can be declared anywhere (as in C++), rather than only after another declaration or the start of a compound statement
- several new data types, including
long long int(to reduce the pain of the looming 32-bit to 64-bit transition), an explicit boolean data type, and acomplextype representing complex numbers - variable-length arrays
- support for one-line comments beginning with
//, like in BCPL or C++, and which many C compilers have previously supported as an extension - several new library functions, such as
snprintf() - several new header files, such as
stdint.h
Interest in supporting the new C99 features appears to be mixed. Whereas GCC and several other compilers now support most of the new features of C99, the compilers maintained by Microsoft and Borland do not, and these two companies do not seem to be interested in adding such support.
Relation to C++
The C++ programming language was originally derived from C. However, not every C program is a valid C++ program. As C and C++ have evolved independently, there has been an increase in the number of incompatibilities between the two languages [3]. The latest revision of C, C99, created a number of additional conflicting features. The differences make it hard to write programs and libraries that are compiled and function correctly as either C or C++ code, and confuse those who program in both languages. The disparity also makes it hard for either language to adopt features from the other one.
Bjarne Stroustrup, the creator of C++, has repeatedly suggested [4] that the incompatibilities between C and C++ should be reduced as much as possible in order to maximize inter-operability between the two languages. Others have argued that since C and C++ are two different languages, compatibility between them is useful but not vital; according to this camp, efforts to reduce incompatibility should not hinder attempts to improve each language in isolation.
Today, the primary differences (as opposed to the additions of C++, such as classes, templates, namespaces, overloading) between the two languages are:
-
inline— inline functions are in the global scope in C++, and in the file (so-called "static") scope in C. In simple terms, this means that in C++, any definition of any inline function (but irrespective of C++ function overloading) must conform to C++'s "One Definition Rule" or ODR, requiring that either there be a single definition of any inline function or that all definitions be semantically equivalent; but that in C, the same inline function could be defined differently in different translation units (translation unit typically refers to a file). - The
boolkeyword in C99 is in its own header,<stdbool.h>. Previous C standards did not define a boolean type, and various (incompatible) methods were used to simulate a boolean type. - Character constants (enclosed in single quotes) have the size of an
intin C and acharin C++. That is to say, in C,sizeof('a') == sizeof(int); in C++,sizeof('a') == sizeof(char). Nevertheless, even in C they will never exceed the values that acharcan store, so(char)'a'is a safe conversion. - Additional keywords were introduced in C++, and thus they cannot be used as identifiers as they could in C. (for example,
try,catch,template,new,delete, ...) - In C++, the compiler automatically creates a "tag" for every
struct,unionorenum, sostruct S {};in C++ is equivalent totypedef struct S {} S;in C.
C99 adopted some features that first appeared in C++. Among them are:
- Mandatory prototype declarations for functions
- The
inlinekeyword - The removal of the "implicit int" return value
Intermediate language
C is used as an intermediate language by some high-level languages (Eiffel, Sather, Esterel) which do not output object or machine code, but output C source code only, to submit to a C compiler, which then outputs finished object or machine code. This is done to gain portability and optimization. C compilers, often many, exist for most or all processors and operating systems, and most C compilers output well optimized object or machine code. Thus, any language that outputs C source code suddenly becomes very portable, and able to yield optimized object or machine code. Unfortunately, C is designed as a programming language, not as a compiler target language, so is not ideal for use as an intermediate language, leading to development of C-based intermediate languages, such as C--.
See also
- C preprocessor
- C standard library
- C library
- C string
- C syntax
- C variable types and declarations
- List of articles with C programs
- Objective-C
- C++
- Operators in C and C++
- Programming tools: Cygwin, Dev-C/C++, DJGPP, GNU Compiler Collection, LCC, Linker, make, SPlint, Small-C, C--
- Pascal and C
References
- Brian Kernighan, Dennis Ritchie: The C Programming Language. Also known as K&R — The original book on C.
- 1st, Prentice Hall 1978; ISBN 0-131-10163-3. Pre-ANSI C.
- 2nd, Prentice Hall 1988; ISBN 0-131-10362-8. ANSI C.
- ISO/IEC 9899. The official C:1999 standard, along with defect reports and a rationale. As of 2005 the latest version is ISO/IEC 9899:TC2.
- Samuel P. Harbison, Guy L. Steele: C: A Reference Manual. This book is excellent as a definitive reference manual, and for those working on C compilers. The book contains a BNF grammar for C.
- 4th, Prentice Hall 1994; ISBN 0-133-26224-3.
- 5th, Prentice Hall 2002; ISBN 0-130-89592-X.
- Derek M. Jones: The New C Standard: A Cultural and Economic Commentary, Addison-Wesley, ISBN 0-201-70917-1, online material
- Robert Sedgewick: Algorithms in C, Addison-Wesley, ISBN 0-201-31452-5 (Part 1–4) and ISBN 0-201-31663-3 (Part 5)
- William H. Press, Saul A. Teukolsky, William T. Vetterling, Brian P. Flannery: Numerical Recipes in C (The Art of Scientific Computing), ISBN 0-521-43108-5
External links
- C
- comp.lang.c Frequently Asked Questions
- The Development of the C Language by Dennis M. Ritchie
- Programming in C (document collection at Lysator)
- C Programming( course at University of Strathclyde Computer Centre)
- International Obfuscated C Code Contest
- Programming C at Wikibooks
- The New C Standard: An economic and cultural commentary — an unpublished book about "detailed analysis of the International Standard for the C language"
- ISO/IEC 9899 (pdf)
- C99
- Open source development using C99 — Is your C code up to standard? by Peter Seebach
- Are you Ready For C99?
- Article "Incompatibilities Between ISO C and ISO C++" by David R. Tribble
- Forums
| Major programming languages (more) (edit) | |||
|
Industrial: ABAP | Ada | AWK | Assembly | C | C++ | C# | COBOL | Common Lisp | Delphi | Eiffel | Fortran | Java | JavaScript | Lisp | Magik | Objective-C | Pascal | Perl | PHP | PL/SQL | PowerBuilder | Python | Ruby | SAS | Smalltalk | Tcl | Visual Basic | VB.NET | Visual FoxPro
|



