The C Programming Language was initially developed by Denis Ritchie using a Unix system in 1972. This was varied and modified until a standard was defined by Brian Kernighan and Dennis Ritchie in 1978 in 'The C Programming Language'. By the early 80's many versions of C language were available which were inconsistent with each other in many aspects. This led to a standard being defined by ANSI in 1983. It is this standard this set of notes primarily addresses.
Why use C ?
Industry Presence : Over the last decade C has become one of the most widely used development languages in the software industry. Its importance is not entirely derived from its use as a primary development language but also because of its use as an interface language to some of the newer “visual” languages and of course because of its relationship with C++.
Middle Level : Being a Middle level language it combines elements of high level languages with the functionality of assembly language. C supports data types and operations on data types in much the same way as higher level languages as well as allowing direct manipulation of bits, bytes, words and addresses as is possible with low level languages.
Portability : With the availability of compilers for almost all operating systems and hardware platforms it is easy to write code on one system which can be easily ported to another as long as a few simple guidelines are followed.
Flexibility : Supporting its position as the mainstream development language C can be interfaced readily to other programming languages.
Malleable : C, unlike some other languages, offers little restriction to the programmer with regard to data types -- one type may be coerced to another type as the situation dictates. However this feature can lead to sloppy coding unless the programmer is fully aware of what rules are being bent and why.
Speed : The availability of various optimising compilers allow extremely efficient code to be generated automatically.
C Programming Environment :
Program development is nowadays carried out in specifically designed software systems or workbenches with editing, compilation, linking, debugging and execution facilities built in. In this course we will be making use of a Microsoft system but the features found in this are to be found in one form or another in almost all modern systems.
The first phase of development involves the creation and editing of a file containing the appropriate C instructions which will be stored using a file extension of .c normally to invoke the C compiler, e.g. fname.c.
The next step is to take the C program and to compile it into object code or machine language code. The C compiler includes the aforementioned preprocessor which is called automatically before the code translation takes place. This preprocessor acts on special commands or directives from the programmer to manipulate the text of the C code before compilation commences. These directives might involve including other source files in the file to be compiled, replacing special symbols with specific replacement text, etc. Once this is done the C code is translated into object code and stored in a file with the extension .obj, e.g. fname.obj.
The final phase in building the executable program is called linking. After the compilation stage the C code has been translated into machine recognisable code but is in a somewhat unconnected state. The program invariably contains references to standard library functions or functions contained in other libraries or modules which must be connected to the C program at link time. This simply involves linking the machine code for these functions with the program’s object code to complete the build process and produce an executable file with an extension .exe e.g. fname.exe.
The executable program can be loaded and run from within the programming environment itself or may be run from the host environment directly. If it executes as expected that is the end of the task. However if this does not happen it may require the use of the debugger to isolate any logical problems. The debugger allows us to step through the code instruction by instruction or up to predefined break-points and to look at the values of variables in the code in order to establish where errors are introduced.