C (programming language)


C is a general-purpose programming language created in the 1970s by Dennis Ritchie. By design, C gives the programmer relatively direct access to the features of the typical CPU architecture, customized for the target instruction set. It has been and continues to be used to implement operating systems, device drivers, and protocol stacks, but its use in application software has been decreasing. C is used on computers that range from the largest supercomputers to the smallest microcontrollers and embedded systems.
A successor to the programming language B, C was originally developed at Bell Labs by Ritchie between 1972 and 1973 to construct utilities running on Unix. It was applied to re-implementing the kernel of the Unix operating system. During the 1980s, C gradually gained popularity. It has become one of the most widely used programming languages, with C compilers available for practically all modern computer architectures and operating systems. The book The C Programming Language, co-authored by the original language designer, served for many years as the de facto standard for the language. C has been standardized since 1989 by the American National Standards Institute and, subsequently, jointly by the International Organization for Standardization and the International Electrotechnical Commission.
C is an imperative procedural language, supporting structured programming, lexical variable scope, and recursion, with a static type system. It was designed to be compiled to provide low-level access to memory and language constructs that map efficiently to machine instructions, all with minimal runtime support. Despite its low-level capabilities, the language was designed to encourage cross-platform programming. A standards-compliant C program written with portability in mind can be compiled for a wide variety of computer platforms and operating systems with few changes to its source code.
Although neither C nor its standard library provide some popular features found in other languages, it is flexible enough to support them. For example, object orientation and garbage collection are provided by external libraries GLib Object System and Boehm garbage collector, respectively.
Since 2000, C has typically ranked as the most or second-most popular language in the TIOBE index.

Characteristics

The C language exhibits the following characteristics:
  • Free-form source code
  • Semicolons terminate statements
  • Curly braces group statements into blocks
  • Executable code is contained in functions
  • Parameters are passed by value; pass by-reference is achieved by passing a pointer to a value
  • Relatively small number of keywords
  • Control flow constructs, including if, for, do, while, and switch
  • Arithmetic, bitwise, and logic operators, including
  • Multiple assignments may be performed in a single statement
  • User-defined identifiers are not distinguished from keywords
  • A variable declared inside a block is accessible only in that block and only below the declaration
  • A function return value can be ignored
  • A function cannot be nested inside a function, but some translators support this
  • Run-time polymorphism may be achieved using function pointers
  • Supports recursion
  • Data typing is static, but weakly enforced; all variables have a type, but implicit conversion between primitive types weakens the separation of the different types
  • User-defined data types allow for aliasing a data type specifier
  • Syntax for array definition and access is via square bracket notation, for example month. Indexing is defined in terms of pointer arithmetic. Whole arrays cannot be copied or compared without custom or library code
  • User-defined structure types allow related data elements to be passed and copied as a unit although two structures cannot be compared without custom code to compare each field
  • User-defined union types support overlapping members, allowing multiple data types to share the same memory location
  • User-defined enumeration types support aliasing integer values
  • Lacks a string type but has syntax for null-terminated strings with associated handling in its standard library
  • Supports low-level access to computer memory via pointers
  • Supports procedure-like construct as a function returning void
  • Supports dynamic memory via standard library functions
  • Includes the C preprocessor to perform macro definition, source code file inclusion, and conditional compilation
  • Supports modularity in that files are processed separately, with visibility control via static and extern attributes
  • Minimized functionality in the core language while relatively complex functionality such as I/O, string manipulation, and mathematical functions supported via standard library functions
  • Resulting compiled code has relatively straightforward needs on the underlying platform, making it desirable for operating and embedded systems

    "Hello, world" example

The "Hello, World!" program example that appeared in the first edition of K&R has become the model for an introductory program in most programming textbooks. The program prints "hello, world" to the standard output.
The original version was:

main

A more modern version is:

  1. include
int main

The first line is a preprocessor directive, indicated by #include, which causes the preprocessor to replace that line of code with the text of the stdio.h header file, which contains declarations for input and output functions including printf. The angle brackets around stdio.h indicate that the header file can be located using a search strategy that selects header files provided with the compiler over files with the same name that may be found in project-specific directories.
The next code line declares the entry point function main. The run-time environment calls this function to begin program execution. The type specifier int indicates that the function returns an integer value. The void parameter list indicates that the function consumes no arguments. The run-time environment actually passes two arguments, but this implementation ignores them. The ISO C standard requires syntax that either is void or these two argumentsa special treatment not afforded to other functions.
The opening curly brace indicates the beginning of the code that defines the function.
The next line of code calls the C standard library function printf with the address of the first character of a null-terminated string specified as a string literal. The text \n is an escape sequence that denotes the newline character which when output in a terminal results in moving the cursor to the beginning of the next line. Even though printf returns an int value, it is silently discarded. The semicolon ; terminates the call statement.
The closing curly brace indicates the end of the main function. Prior to C99, an explicit return 0; statement was required at the end of main function, but since C99, the main function implicitly returns 0 upon reaching its final closing curly brace.

History

Early developments

The origin of C is closely tied to the development of the Unix operating system, originally implemented in assembly language on a PDP-7 by Dennis Ritchie and Ken Thompson, incorporating several ideas from colleagues. Eventually, they decided to port the operating system to a PDP-11. The original PDP-11 version of Unix was also developed in assembly language.

B

Thompson wanted a programming language for developing utilities for the new platform. He first tried writing a Fortran compiler, but he soon gave up the idea and instead created a cut-down version of the recently developed systems programming language called BCPL. The official description of BCPL was not available at the time, and Thompson modified the syntax to be less 'wordy' and similar to a simplified ALGOL known as SMALGOL. He called the result B, describing it as "BCPL semantics with a lot of SMALGOL syntax". Like BCPL, B had a bootstrapping compiler to facilitate porting to new machines. Ultimately, few utilities were written in B because it was too slow and could not take advantage of PDP-11 features such as byte addressability.
Unlike BCPL's // comment marking comments up to the end of the line, B adopted /* comment */ as the comment delimiter, more akin to PL/1, and allowing comments to appear in the middle of lines.

New B and first C release

In 1971 Ritchie started to improve B, to use the features of the more-powerful PDP-11. A significant addition was a character data type. He called this New B. Thompson started to use NB to write the Unix kernel, and his requirements shaped the direction of the language development.
Through to 1972, richer types were added to the NB language. NB had arrays of int and char, and to these types were added pointers, the ability to generate pointers to other types, arrays of all types, and types to be returned from functions. Arrays within expressions were effectively treated as pointers. A new compiler was written, and the language was renamed C.
The C compiler and some utilities made with it were included in Version 2 Unix, which is also known as Research Unix.

Structures and Unix kernel re-write

At Version 4 Unix, released in November 1973, the Unix kernel was extensively re-implemented in C. By this time, the C language had acquired some powerful features such as struct types.
The preprocessor was introduced around 1973 at the urging of Alan Snyder and also in recognition of the usefulness of the file-inclusion mechanisms available in BCPL and PL/I. Its original version provided only included files and simple string replacements: #include and #define of parameterless macros. Soon after that, it was extended, mostly by Mike Lesk and then by John Reiser, to incorporate macros with arguments and conditional compilation.
Unix was one of the first operating system kernels implemented in a language other than assembly. Earlier instances include the Multics system and Master Control Program for the Burroughs B5000 in 1961. In and around 1977, Ritchie and Stephen C. Johnson made further changes to the language to facilitate portability of the Unix operating system. Johnson's Portable C Compiler served as the basis for several implementations of C on new platforms.