About this book

The C programming language has been around for a long time — the canonical reference for it is the book written by its creators, Kernighan and Ritchie [1978]. Since then, C has been used in an incredible number of applications. Programs and systems written in C are all around us: in personal computers, phones, cameras, set-top boxes, refrigerators, cars, mainframes, satellites ... basically in any modern device that has a programmable interface.

In contrast to the ubiquitous presence of C programs and systems, good knowledge of and about C is much more scarce. Even experienced C programmers often appear to be stuck in some degree of self-inflicted ignorance about the modern evolution of the C language. A likely reason for this is that C is seen as an “easy to learn” language, allowing a programmer with little experience to quickly write or copy snippets of code that at least appear to do what it’s supposed to. In a way, C fails to motivate its users to climb to higher levels of knowledge.

This book is intended to change that general attitude, so it is organized in levels that reflect familiarity with the C language and programming in general. This structure may go against some habits of the book’s readers; in particular, it splits some difficult subjects (such as pointers) across levels in order to not swamp readers too early with the wrong information. We’ll explain the book’s organization in more detail shortly.

Generally, although many universally applicable ideas will be presented, that would also be valid for other programming languages (such as Java, Python, Ruby, C#, or C++) the book primarily addresses concepts and practices that are unique to C or are of particular value when programming in the C language.

C versions

As the title of this book suggests, today’s C is not the same language as the one originally designed by its creators, Kernighan and Ritchie (usually referred to as K&R C). In particular, it has undergone an important standardization and extension process, now driven by ISO, the International Standards Organization. This led to the publication of a series of C standards in 1989, 1999, 2011, and 2018, commonly referred to as C89, C99, C11, and C17. The C standards committee puts a lot of effort into guaranteeing backward compatibility such that code written for earlier versions of the language, say C89, should compile to a semantically equivalent executable with a compiler that implements a newer version. Unfortunately, this backward compatibility has had the unwanted side effect of not motivating projects that could benefit greatly from the new features to update their code base.

In this book, we will mainly refer to C17, as defined in JTC1/SC22/WG14 [2018], but at the time of this writing some compilers don’t implement this standard completely. If you want to compile the examples in this book, you will need at least a compiler that implements most of C99. For the changes that C11 added to C99, using an emulation layer such as my macro package P99 might suffice; the package is available at http://p99.gforge.inria.fr.

C and C++

Programming has become a very important cultural and economic activity, and C remains an important element in the programming world. As in all human activities, progress in C is driven by many factors: corporate or individual interest, politics, beauty, logic, luck, ignorance, selfishness, ego, sectarianism (add your primary motivation here). Thus the development of C has not been and cannot be ideal. It has flaws and artifacts that can only be understood with their historical and societal context.

An important part of the context in which C developed was the early appearance of its sister language, C++. One common misconception is that C++ evolved from C by adding its particular features. Although this is historically correct (C++ evolved from a very early C), it is not particularly relevant today. In fact, C and C++ separated from a common ancestor more than 30 years ago and have evolved separately ever since. But this evolution of the two languages has not taken place in isolation; they have exchanged and adopted each other’s concepts over the years. Some new features, such as the recent addition of atomics and threads, have been designed in close collaboration between the C and C++ standard committees.

Nevertheless, many differences remain, and generally all that is said in this book is about C, not C++. Many code examples that are given will not even compile with a C++ compiler. So we should not mix sources of both languages.

Takeaway A

C and C++ are different: don’t mix them, and don’t mix them up.

Note that when you are working through this book, you will encounter many lines marked like that one. These are takeaways that summarize features, rules, recommendations, and so on. There is a list of these takeaways toward the end of the book, which you might use as a cheat sheet.

Requirements

To be able to profit from this book, you need to fulfill some minimal requirements. If you are uncertain about any of these, please obtain or learn them first; otherwise, you might waste a lot of time.

First, you can’t learn a programming language without practicing it, so you must have a decent programming environment at your disposal (usually on a PC or laptop), and you must master it to some extent. This environment can be integrated (an IDE) or a collection of separate utilities. Platforms vary widely in what they offer, so it is difficult to advise on specifics. On Unix-like environments such as Linux and Apple’s macOS, you will find editors such as emacs and vim, and compilers such as c99, gcc, and clang.

You must be able to do the following:

  1. Navigate your file system. File systems on computers are usually organized hierarchically in directories. You must be able to navigate through these to find and manipulate files.
  2. Edit programming text. This is different from editing a letter in a word processing environment. Your environment, editor, or whatever it is called should have a basic understanding of the programming language C. You will see that if you open a C file (which usually has the file extension .c). It might highlight some keywords or help you indent your code according to the nestedness of {} brackets.
  3. Execute a program. The programs you will see here are very basic at first and will not offer you any graphical features. They need to be launched in the command line. An example of such a program that is launched that way is the compiler. On Unix-like environments, the command line is usually called a shell and is launched in a (or the) console or terminal.
  4. Compile programming text. Some environments provide a menu button or a keyboard shortcut for compilation. An alternative to that is to launch the compiler in the command line of a terminal. This compiler must adhere to recent standards; don’t waste your time with a compiler that does not conform.

If you have never programmed before, this book will be tough. Knowing some of the following will help: Basic, C (historical versions), C++, Fortran, R, bash, JavaScript, Java, MATLAB, Perl, Python, Scilab, and so on. But perhaps you have had some other programming experience, maybe even without noticing. Many technical specifications actually come in some sort of specialized language that can be helpful as an analogy: for example, HTML for web pages and LaTeX for document formatting.

You should have an idea of the following concepts, although their precise meanings may be a bit different in C than in the context where you learned them:

  1. Variables — Named entities that hold values
  2. Conditionals — Doing something (or not) subject to a precise condition
  3. Iteration — Doing something repeatedly for a specified number of times or until a certain condition is met

Source code

Many of the programming code snippets that are presented in this book are available for download as a .zip archive from the book’s website at

This allows you to view them in context and to compile them and try them out. The archive also contains a Makefile with a description of the components that are needed to compile these files. It is centered around Linux or, more generally, POSIX systems, but it may also help you to find out what you need when you are on a different system.

Exercises and challenges

Throughout this book, you’ll see exercises that are meant to get you thinking about the concepts being discussed. These are probably best done directly along with your reading. Then there is another category called “challenges.” These are generally more demanding. You will need to do some research to even understand what they are about, and the solutions will not come all by themselves: they will require effort. They will take more time, sometimes hours or, depending on your degree of satisfaction with your work, even days. The subjects covered in these challenges are the fruit of my own personal bias toward “interesting questions” from my personal experience. If you have other problems or projects in your studies or your work that cover the same ground, they should do equally well. The important aspect is to train yourself by first searching for help and ideas elsewhere, and then to get your hands dirty and get things done. You will only learn to swim if you jump into the water.

Organization

This book is organized in levels, numbered from 0 to 3. The starting level 0, named “Encounter,” will summarize the very basics of programming with C. Its principal role is to remind you of the main concepts we have mentioned and familiarize you with the special vocabulary and viewpoints that C applies.[1] By the end of it, even if you don’t have much experience in programming with C, you should be able to understand the structure of simple C programs and start writing your own.

1

One of C’s special viewpoints is that indexing starts at 0, and not at 1 as in Fortran.

The “Acquaintancelevel 1 details most principal concepts and features such as control structures, data types, operators, and functions. It should give you a deeper understanding of the things that are going on when you run your programs. This knowledge should be sufficient for an introductory course in algorithms and other work at that level, with the notable caveat that pointers are not yet fully introduced.

The “Cognitionlevel 2 goes to the heart of the C language. It fully explains pointers, familiarizes you with C’s memory model, and allows you to understand most of C’s library interface. Completing this level should enable you to write C code professionally; it therefore begins with an essential discussion about the writing and organization of C programs. I personally would expect anybody who graduated from an engineering school with a major related to computer science or programming in C to master this level. Don’t be satisfied with less.

The “Experiencelevel 3 then goes into detail about specific topics, such as performance, reentrancy, atomicity, threads, and type-generic programming. These are probably best discovered as you go, which is when you encounter them in the real world. Nevertheless, as a whole, they are necessary to round off the discussion and to provide you with full expertise in C. Anybody with some years of professional programming in C or who heads a software project that uses C as its main programming language should master this level.

About the author

Jens Gustedt completed his studies of mathematics at the University of Bonn and Berlin Technical University. His research at that time covered the intersection between discrete mathematics and efficient computation. Since 1998, he has been working as a senior scientist at the French National Institute for Computer Science and Control (INRIA), first in the LORIA lab, Nancy, and since 2013 in the ICube lab, Strasbourg.

Throughout his career, most of his scientific research has been accompanied by the development of software, at the beginning mostly in C++, and then later exclusively in C. He now serves AFNOR as an expert on the ISO committee JTC1/SC22/WG14 and is co-editor of the C standard document ISO/IEC 9899:2018. He also has a successful blog that deals with programming in C and related topics: https://gustedt.wordpress.com.