The C Programming Language

C is a programming language, i.e. a language with which computer programs are written.

Programming describes the craft of teaching a computer to carry out a desired activity, a clearly defined process. As in any process, there is raw material in programming that is processed with appropriate tools to achieve a desired result. The raw material can be described using the terms data, values and information. The programming language is the tool.

Programming can be understood as controlling a flow of data. In several consecutive modules, data is read in, processed and then output, with the output data being read in again by subsequent modules, and so on and so forth.

This flow is the basic motivation of programming and, as with all programming languages, can also be observed in all development phases of the language C.

From Electricity to Bits and Bytes

For a long time, electricity was considered purely as a supplier of energy: It is generated by generators, transported through wires and consumed in resistors like light bulbs. This construct is summarized under the name electrics. In contrast to this, electrONics<> deals with the use of a measurable quantity of electricity, for example the voltage.

It is not long since the first electronic circuits were invented: A method by which electric current can be distributed in a controlled manner to different lines. The joining together of several circuits and lines led to the first electronic devices: simple controls such as automatic door openers, timers or the flashing lights of a car. These control elements always convert some kind of input signals, such as the press of a button, into output signals by linking different circuits in a more or less complicated manner. If a combination of circuits serves a specific purpose, it is integrated (packed) into a chip as a so-called integrated circuit, which as a whole performs the desired function.

Electronic components such as chips are called hardware because of their physical tangibility. Over time, the demands on hardware increased and the connections in the chips became more and more complicated. Finally, in order to be able to perform functions of any complexity, the programmable chip was invented: A chip that can not only perform a specific function, but a whole set of basic commands, including addition and subtraction, for example. Along with an electronic module that can memorize information (and hence is appropriately called memory), arbitrarily complex functional processes can be carried out using a single chip. This is still referred to today as the CPU, central processing unit, or simply: Processor.

In a processor of a modern computer, two states are specified based on the voltage, in which there exists either more or less potential of power to flow than a certain threshold. These two states, power and non-power, define the basic unit bit of a modern computer, the states being better known as 1 and 0. Combined states are created by lining up several bits: Eight bits together make one byte, which means that 256 different states are possible, more bits correspondingly result in more states. Anything that can be represented by a state is called data (singular: a date).

Machine Language and Assembler

A processor does not inherently know how to handle data. Whether the date 11001000 represents the positive number 200 or the negative number -56 is irrelevant for a processor, it always works with pure data. In earlier times, a programmer therefore had the task of instructing the processor which manipulations it should carry out so that the data was processed correctly (EDP = electronic data processing).

In order for a processor to know exactly what it is supposed to process, it needs instructions, a code that specifies exactly when which input data is to be linked with which method. The compilation of a such code is called software and has the task of controlling the hardware. A sequence of instructions for a processor is called a machine program, which is written in the only language that the processor can understand: Machine language. Each type of processor has its own machine language that only it understands. It is fundamentally incomprehensible for a human being, since it consists only of binary values, which can at best be interpreted as numbers.

In the old days, programmers therefore had to transmit numerical values to a processor in order to achieve a specific functionality. Since this is difficult for a human to handle, the so-called assembler was invented, a program that converts halfway human words into the desired numerical values. These words are called mnemonics, which means memory aids. The language created by these words, like the conversion program itself, is also called assembler. The following is an example of an assembler program:

pushl  %ebp
movl  %esp, %ebp
subl  $24, %esp
movl  $1, -20(%ebp)
movl  $1, -16(%ebp)
movl  -16(%ebp), %eax
addl  -20(%ebp), %eax
movl  %eax, -12(%ebp)
movl  $0, %eax
leave
ret

Since each type of processor has its own machine language, each type of processor also has its own assembly language. Processors continue to evolve to this day, and the way data is organized has changed over and over again. This would mean that a programmer would have to rewrite code for each type of processor. To prevent this, new programming languages have been developed that never change, but translate the code into any desired assembler in the background using a compiler and/or interpreter. Since such languages are above all assemblers, they are called high-level languages. An example of a high-level language is C.

The Language C

While with assembler the programmer had to explicitly instruct the processor how to store and process data, with C this work is done by a compiler. However, the programmer must also tell the compiler how the data is to be interpreted structurally. This is the definition of a value: Data with a structural interpretation. In C, the structural interpretation is determined by a type.

Depending on the type, a compiler produces different, but precisely the right machine code for the structural interpretation. Since all values are assigned a type in C, storing them as data is predetermined unambiguously. During programming, the main task is therefore more to correctly relate the values to one another, to give them meaning. The number 200 could represent the number of elements in an array or the count variable of a loop. A value with a meaning is called information. The handling of information is called information technology (IT).

As soon as the structure of data is known, it can be worked with. A computer can calculate values. Here the true meaning of the word computer is revealed: To compute = to calculate. A computer is made to perform mathematical calculations. In C, the processing of values is realized using operators. Each operator (an addition, for example) takes a certain number of input values, performs some processing, and returns a value. The output of this calculation is again a value, i.e. a date with a type. This means that each operator can act as an input value itself.

By arranging or nesting operators, so-called expressions are created. If an expression fulfills a self-contained purpose, it is referred to as a so-called statement. The programmer gives more or less complex commands to the computer by means of a statement. For this reason, the language C is classified as a command language (or imperative language).

Several consecutive statements are processed sequentially. These parts of the code are the ones on which the processor ultimately processes data, calculates, is productive. At certain points, however, the processor is told to jump to a different point in the code, for example because it should do something different depending on the input value. Such a change in command flow is called a control structure.

When there is a large number of consecutive statements and control structures with complex, complicated, confusing relationships, that particular piece software is referred to as spaghetti code. Such kind of software is generally undesired. In order to prevent it, multiple statements and control structures can be wrapped as a so-called function which represents a complex functional unit that again produces an output from input values. Such functions can thereafter simply be called at any arbitrary place in the software.

All statements, control structures and functions are written in text files, which is called code or more precisely source code.

In order for an executable program to be created from the written code, the source code is first translated into assembler and then into machine language using a compiler. More complex programs also consist of several source codes and usually link to existing libraries. In order to combine several source codes and to control how the individual parts are to be coordinated with one another, C has what is known as a preprocessor, which can be controlled using a large number of so-called directives directly in the source code. At the end of a translation there is a so-called linker which links all translated parts and creates a program that can be run directly on the processor.

C also allows to write a program in a clear and intuitive form. For example, all available data can be given a name, which is called a variable. Working with values is made easier by allowing mathematical operations to be written using symbols such as , -, * and /. Control structures can be presented in an understandable and even visually supporting form. The same program as in the assembler example above looks like this in C:

int main(){
  int a = 1;
  int b = 1;
  int c = a + b;
  return 0;
}

With the C programming language, a tool was created to be able to carry out data manipulations quickly and in an orderly manner. The language is not always easy due to its proximity to assembler, but it is very practical for the die-hard programmer. Many things that programmers often have to write have been simplified with C. Many well-known commercial software packages as well as the common computer systems have been programmed in C in their basis. The C language can still compete with other languages today, especially through the extension with C++ to object-oriented programming.

More about C

The story of C ends here on this page. It is noted here that language C emerged from language B, which first appeared around 1969. C was developed by Dennis Ritchie in 1972.

The language C has been standardized according to ANSI and ISO, with the three standards C90, C99 and C11 particularly noted on this page. The number stands for the publication year of the standard (i.e. 1990, 1999 and 2011). The C90 standard is sometimes also referred to as ANSI C or C89, which denotes one and the same standard, but C90 is ISO certified. It is a standard for code that should also run with older compilers. Currently (at the time of writing this entry) C11 is the standard supported by most existing compilers. A next standard C23 is in the works.

Next Chapter: Values and Type System