CodeMusings

Kick back and get started at your own pace.

Skip to Content

Overview

The C programming language is a static, weakly typed, procedural, general-purpose programming language. The principle designer of the language was Dennis M. Ritchie (September 1941—October 2011), who was working at Bell Labs [Ritchie]. The C programming language is responsible for a large amount of software that runs our world today.

Hello, world!

C needs a little help to say hello. The <stdio.h> header gets loaded into the translation unit by the preprocessor, and is, among other things, responsible for declaring the function prototypes for the standard I/O functions.

For now, you can think of the functionality of the preprocessor as an advanced cut-and-paste processor. It's oversimplified, but preprocessor directives, like #include <stdio.h> are replaced by the text of the header file.

hello.c

  1. #include <stdio.h>
  2.  
  3. int main(void)
  4. {
  5. puts("Hello, world!");
  6. return 0;
  7. }

History

Ritchie and Thompson working at Bell Labs

Dennis Ritchie and Ken Thompson working on the PDP-11 in 1972 [CNN].

During the years 1969 through 1973, the C language came into being, and was developed in tandem with the UNIX operating system. The C programming language was designed with simplicity in mind [Ritchie]. Its grammar lends itself well to mapping to the natural machine. In retrospect, C can actually be seen as an influence on how many machines were developed.

1985 UNIX AT&T Model 7300 PC, designed by Convergent Technologies

A 1985 AT&T Model 7300 Convergent Technologies PC, running UNIX.


Photo from oldcomputers.net, and used with permission.

C was instrumental in spreading UNIX, as it allowed UNIX to be distributed more widely by abstracting away the gritty details of the machine. The concept of making software able to run in multiple environments is portability. UNIX's influence spread to most modern day operating systems, such as Windows, Macs, Linux, and BSD. You'll find C programs written for environments such as large computer clusters, all the way down to microwaves, and an innumerable amount of environments in between.

Due to the simplicity of C, it aided in its spread as a commonly used high level programming language. It didn't take long for its use to spread beyond the confines of Bell Labs. In Dennis Ritchie's account of the history of C's development, he describes the growth of the language after becoming sufficiently refined to use to write UNIX on a PDP-11:

The success of our portability experiment on the Interdata 8/32 soon led to another by Tom London and John Reiser on the DEC VAX 11/780. This machine became much more popular than the Interdata, and Unix and the C language began to spread rapidly, both within AT&T and outside.

Design

The design of C was intentionally spartan; its lack of a large feature set has allowed it to fit in many environments. The official definition of the language is governed by the ISO standards group. Some common compilers are GCC (GNU's C compiler), Clang, and Visual C++.

In the first edition of K&R, or the first, definitive definition of C, published by Brian Kernighan and Dennis Ritchie, C is summed up very well:

C is a general-purpose programming language which features economy of expression, modern control flow and data structures, and a rich set of operators. C is not a "very high level" language, nor a "big" one, and is not specialized to any particular area of application. But its absence of restrictions and its generality make it more convenient and effective for many tasks than supposedly more powerful languages.

Type System

C is a statically and weakly typed language. Its type system was designed with the mindset that type declaration syntax should reflect how objects are used in the code. While some features that grew out of this intent were well-meaning, they sometimes led to more confusion in the end. Although the primitive integral types are fairly simple and tend to map well to machine sizes, C also allows you to make custom types, which can become very complicated. In the absence of sensible typedef usage, one may end up with unwieldly type declarations. The typedef stoarge-class specifier allows programmers to alias types [ISO/IEC §6.7.8]. An example should make it a little clearer:

  1. typedef const char *Film[2];
  2. Film favorites[] = {
  3. {
  4. "George Méliès",
  5. "A Trip to the Moon"
  6. },
  7. {
  8. "Martin Scorsese",
  9. "Hugo"
  10. }
  11. };
  12.  
  13. for (size_t i = 0, j = sizeof favorites / sizeof *favorites; i < j; ++i) {
  14. printf("Title: %s\nDirector: %s\n\n", favorites[i][1], favorites[i][0]);
  15. }

Here, we make it a little easier to declare our type, which contains arrays and pointers. If we're not careful, it's not impossible to end up with type declarations that instead look like:

char (*(*x())[5])();

Luckily, utilizing the typedef storage-class specifier, allows breaking down the process of creating complicated types. Cryptic type declarations has led to the creation of a well-known tool called cdecl, which converts complicated type declarations like the above into English.

C does have generic typing, after a fashion. It allows void*, or pointers to void. It involves deferring the resolution of the type of the object to which the pointer points until the compilation and linking phases. In other words, you're essentially promising the compiler that you'll have the necessary information about the size of the object at which the pointer is pointing at a later point. This crucial information may even be in a different file. The upshot is that it lets programmers avoid rewriting the same code to handle different types of objects.

Good for Beginners?

Although the C programming language is minimalistic, you still need knowledge about how to run and manage your compiler. If you plan for your program to utilize features from your desktop environment, the file system, and other facilities offered by the environment, you need to learn these things separately, which can sometimes be quite a bit of work.

I found C very fun to learn. Mastering pointers was a great personal accomplishment. You can do quite a bit of learning with just standard C. When I progressed to learning how C was implemented, I was able to increase my understanding about how computers work at a lower level.

I would still recommend first starting off with a language like Python before diving right into C. In the case of Python, you'll find that the interpreter is actually written in C (and written very well). However, if diving right into the gritty details of your machine doesn't deter you, have fun diving in!

References

  1. ^ - ISO/IEC 9899:201x. Programming languages—C. Committee Draft (N1570). April 12, 2011.
  2. ^ - Metz, Cade. Dennis Ritchie: The Shoulders Steve Jobs Stood on. Accessed: 3 October 2014.
  3. ^ - Ritchie, Dennis M. The Development of the C Language. Accessed: 3 October 2014.