How C Programming Works


The C programming language gives you more versatility than many other languages, including greater control over your computer's memory.
The C programming language gives you more versatility than many other languages, including greater control over your computer's memory.
iStockphoto/Thinkstock

The C programming language is incredibly popular, and it's easy to see why. Programming in C is efficient and gives the programmer a great deal of control. Many other programming languages like C++, Java and Python were developed using C.

Chances are increasing each day that if you're a programmer, you won't use C exclusively for your work. However, there are several learning C is highly beneficial, even if you don't use it regularly. Here's why:

You'll be able to read and write code for software that can be used on many different types of computer platforms, including everything from small microcontrollers to desktop, laptop and mobile operating systems.

You'll better understand what high-level languages are doing behind the scenes, such as memory management and garbage collection. This understanding can help you write programs that work more efficiently.

If you're an information technology (IT) specialist, you could also benefit from learning C. IT professionals often write, maintain and run scripts as part of their job. A script is a list of instructions for a computer's operating system to follow. To run certain scripts, the computer sets up a controlled execution environment called a shell. Since most operating systems run shells based on C, C shell is a popular scripting adaptation of C used by IT pros.

This article covers the history behind C, looks at why C is so important, shows examples of some basic C code and explores some important features of C, including data types, operations, functions, pointers and memory management. Though this article isn't an instruction manual for programming in C, it does cover what makes C programming unique in a way that goes beyond those first few chapters of the average C programming guide.

Let's start by looking at where the C programming language came from, how it has developed and the role it has in software development today.

What is C?

The simplest way to define C is to call it a computer programming language, meaning you can write software with it that a computer can execute. The result could be a large computer application, like your Web browser, or a tiny set of instructions embedded in a microprocessor or other computer component.

The language C was developed in the early 1970s at Bell Laboratories, primarily credited to the work of Ken Thompson and Dennis Ritchie. Programmers needed a more user-friendly set of instructions for the UNIX operating system, which at the time required programs written in assembly language. Assembly programs, which speak directly to a computer's hardware, are long and difficult to debug, and they required tedious, time-consuming work to add new features [source: King].

Thompson's first attempt at a high-level language was called B, a tribute to the system programming language BCPL on which it was based. When Bell Labs acquired a Digital Equipment Corporation (DEC) UNIX system model PDP-11, Thompson reworked B to better fit the demands of the newer, better system hardware. Thus, B's successor, C, was born. By 1973, C was stable enough that UNIX itself could be rewritten using this innovative new higher-level language [source: King].

Before C could be used effectively beyond Bell Labs, other programmers needed a document that explained how to use it. In 1978, the book "The C Programming Language" by Brian Kernighan and Dennis Ritchie, known by C enthusiasts as K&R or the "White Book," became the definitive source for C programming. As of this writing, the second edition of K&R, originally published in 1988, is still widely available. The original, pre-standard version of C is called K&R C based on that book.

To ensure that people didn't create their own dialects over time, C developers worked through the 1980s to create standards for the language. The U.S. standard for C, American National Standards Institute (ANSI) standard X3.159-1989, became official in 1989. The International Organization for Standardization (ISO) standard, ISO/IEC 9899:1990, followed in 1990. The versions of C after K&R reference these standards and their later revisions (C89, C90 and C99). You might also see C89 referred to as "ANSI C," "ANSI/ISO C" or "ISO C."

C and its use in UNIX was just one part of the boom in operating system development through the 1980s. For all its improvements over its predecessors, though, C was still not effortless to use for developing larger software applications. As computers became more powerful, demand increased for an easier programming experience. This demand prompted programmers to build their own compilers, and thus their own new programming languages, using C. These new languages could simplify coding complex tasks with lots of moving parts. For example, languages like C++ and Java, both developed from C, simplified object-oriented programming, a programming approach that optimizes a programmer's ability to reuse code.

Now that you know a little background, let's look at the mechanics of C itself.

Editing and Compiling C Code

C is what's referred to as a compiled language, meaning you have to use a compiler to turn the code into an executable file before you can run it. The code is written into one or more text files, which you can open, read and edit in any text editor, such as Notepad in Windows, TextEdit on a Mac, and gedit in Linux. An executable file is something the computer can run (execute). The compiler checks the code for errors and, if it seems to be error-free, creates an executable file.

Before we look at what goes into the C code, let's be sure we can find and use a C compiler. If you're using Mac OS X and most Linux distributions (such as Ubuntu), you can add a C compiler to your computer if you install the development tools software for that particular OS. These free C compilers are command line tools, which means you'll typically run them from a command prompt in a terminal window. The command to run one of these C compilers is "cc" or "gcc" plus some command line options and arguments, which are other words typed after the command before you press Enter.

If you're using Microsoft Windows, or you would prefer to use a graphical user interface rather than a command line, you can install an integrated development environment (IDE) for C programming. An IDE is a single interface where you can write your code, compile it, test it and quickly find and fix errors. For Windows, you could purchase Microsoft Visual C++ software, an IDE for both C and C++ programming. Another popular IDE is Eclipse, a free Java-based IDE that runs on Windows, Mac and Linux and has extensions available for compiling C and many other programming languages.

For C, as for other computer programming languages, the version of the compiler you use is very important. You always want to use a version of the C compiler that's as new or newer than the version of the C language you're using in your program. If you're using an IDE, be sure to adjust your settings to make sure the IDE is using your target C version for the program you're working on. If you're at a command line, you can add a command line argument to change the version as in the following command:

gcc –std c99 –o myprogram.exe myprogram.c

In the command above, "gcc" is the call to run the compiler and everything else is a command line option or argument. The "-std" option was added followed by "c99" to tell the compiler to use the C99 standard version of C during its compiling. The "-o" option was added followed by "myprogram.exe" to request that the executable, the compiler's output file, to be named myprogram.exe. Without "-o" the executable is automatically named a.out instead. The final argument "myprogram.c" indicates the text file with the C code to be compiled. In short, this command is saying, "Hey, gcc, compile myprogram.c using the C99 C programming standard and put the results in a file named myprogram.exe." Browse the Web for a complete list of options you can use with your particular compiler, whether it's gcc or something else.

With your compiler installed, you're ready to program in C. Let's start by taking a look at the basic structure of one of the simplest C programs you could write.

The Simplest C Program

Let's look at a simple C program and use it both to understand the basics of C and the C compilation process. If you have your own computer with a C compiler installed as described earlier, you can create a text file named sample.c and use it to follow along while we step through this example. Note that if you leave off the .c in the file name, or if your editor appends .txt to the name, you'll probably get some sort of error when you compile it.

Here's our sample program:

/* Sample program */

#include <stdio.h>

int main()

{

printf("This is output from my first program!\n");

return 0;

}

When compiled and executed, this program instructs the computer to print out the line "This is output from my first program!" and then stop. You can't get much simpler than that! Now let's take a look at what each line is doing:

Line 1 -- This is one way to write comments in C, between /* and */ on one or more lines.

Line 2 -- The #include command tells the compiler to look at other sources for existing C code, particularly libraries, which are files that include common reusable instructions. The references a standard C library with functions for getting input from a user and for writing output to the screen. We'll look at libraries a more closely later.

Line 3 -- This line the first line of a function definition. Every C program has at least one function, or a block of code representing something the computer should do when the program runs. The function performs its task and then produces a byproduct, called a return value, that can be used by other functions. At a minimum, the program has a function called main like the one shown here with a return value with the data type int, which means integer. When we examine functions more later, you'll see what the empty parentheses mean.

Lines 4 and 7 -- The instructions within a function are enclosed in braces. Some programmers start and end a brace-enclosed block on separate lines as shown here. Others will put the open-brace ({) at the end of the first line of the function definition. Though lines of code in the program don't have to be typed on separate lines, programmers typically put each instruction on a separate line, indented with spaces, to make the code easier to read and edit later.

Line 5 -- This is a function call to a function named printf. That function is coded in the stdio.h library included from Line 1, so you don't have to write it yourself. This call to printf tells it what to print to the screen. The \n at the end, within the quotes, isn't printed, though; it's an escape sequence which instructs printf to move the cursor to the next line on the screen. Also, as you can see, every line in the function must end with a semi-colon.

Line 6 -- Every function that returns a value must include a return statement like this one. In C, the main function must always have an integer return type, even though it's not used within the program. Note that when you're running a C program, though, you're essentially running its main function. So, when you're testing the program, you can tell the computer to show the return value from running the program. A return value of 0 is preferred since programmers typically look for that value in testing to confirm the program ran successfully.

When you're ready to test your program, save the file and compile and run the program. If you're using the gcc compiler at a command line, and the program is in a file called sample.c, you can compile it with the following command:

gcc -o sample.exe sample.c

If there are no errors in the code, you should have a file named sample.exe in the same directory as sample.c after running this command. The most common error is a syntax error, meaning that you've mistyped something, such as leaving off a semicolon at the end of a line or not closing quotes or parentheses. If you need to make changes, open the file in your text editor, fix it, save your changes and try your compile command again.

To run the sample.exe program, enter the following command. Note the ./ which forces the computer to look at the current directory to find the executable file:

./sample.exe

Those are the basics of coding and compiling for C, though there's a lot more you can learn about compiling from other C programming resources. Now, let's open the box and see what pieces C has for building programs.

Common Programming Concepts in C

Let's take a look at how to put some of the common programming concepts into practice in your C code. The following is a quick summary of these concepts:

Functions -- As stated earlier, a function is a block of code representing something the computer should do when the program runs. Some languages call these structures methods, though C programmers don't typically use that term. Your program may define several functions and call those functions from other functions. Later, we'll take a closer look at the structure of functions in C.

Variables -- When you run a program, sometimes you need the flexibility to run the program without knowing what the values are ahead of time. Like other programming languages, C allows you to use variables when you need that flexibility. Like variables in algebra, a variable in computer programming is a placeholder that stands for some value that you don't know or haven't found yet.

Data types -- In order to store data in memory while your program is running, and to know what operations you can perform on that data, a programming language like C defines certain data types it will recognize. Each data type in C has a certain size, measured in binary bits or bytes, and a certain set of rules about what its bits represent. Coming up, we'll see how important it is choose the right data type for the task when you're using C.

Operations -- In C, you can perform arithmetic operations (such as addition) on numbers and string operations (such as concatenation) on strings of characters. C also has built-in operations specifically designed for things you might want to do with your data. When we check out data types in C, we'll take a brief look at the operations, too.

Loops -- One of the most basic things a programmer will want to do is repeat an action some number of times based on certain conditions that come up while the program is running. A block of code designed to repeat based on given conditions is called a loop, and the C language provides for these common loop structures: while, do/while, for, continue/break and goto. C also includes the common if/then/else conditionals and switch/case statements.

Data structures -- When your program has a lot of data to handle, and you need to sort or search through that data, you'll probably use some sort of data structure. A data structure is a structured way of representing several pieces of data of the same data type. The most common data structure is an array, which is just an indexed list of a given size. C has libraries available to handle some common data structures, though you can always write functions and set up your own structures, too.

Preprocessor operations -- Sometimes you'll want to give the compiler some instructions on things to do with your code before compiling it into the executable. These operations include substituting constant values and including code from C libraries (which you saw in the sample code earlier).

C also requires programmers to handle some concepts which many programming languages have simplified or automated. These include pointers, memory management, and garbage collection. Later pages cover the important things to know about these concepts when programming in C.

This quick overview of concepts may seem overwhelming if you're not already a programmer. Before you move on to tackle a dense C programming guide, let's take a user-friendly look at the core concepts among those listed above, starting with functions.

Functions in C

Most computer programming languages allow you to create functions of some sort. Functions let you chop up a long program into named sections so that you can reuse those sections throughout the program. Programmers for some languages, especially those using object-oriented programming techniques, use the term method instead of function.

Functions accept parameters and return a result. The block of code that comprises a function is its function definition. The following is the basic structure of a function definition:

<return type> <function name>(<parameters>)

{

<statements>

return <value appropriate for the return type>;

}

At a minimum, a C program has one function named main. The compiler will look for a main function as the starting point for the program, even if the main function calls other functions within it. The following is the main we saw in the simple C program we looked at before. It has a return type of integer, takes no parameters, and has two statements (instructions within the function), one of which is its return statement:

int main()

{

printf("This is output from my first program!\n");

return 0;

}

Functions other than main have a definition and one or more function calls. A function call is a statement or part of a statement within another function. The function call names the function it's calling followed by parentheses. If the function has parameters, the function call must include corresponding values to match those parameters. This additional part of the function call is called passing parameters to the function.

But what are parameters? A parameter for a function is a piece of data of a certain data type that the function requires to do its work. Functions in C can accept an unlimited number of parameters, sometimes called arguments. Each parameter added to a function definition must specify two things: its data type and its variable name within the function block. Multiple parameters are be separated by a comma. In the following function, there are two parameters, both integers:

int doubleAndAdd(int a, int b)

{

return ((2*a)+(2*b));

}

Next, let's continue our look at functions by zooming out to look at how they fit within a larger C program.

Function Prototypes

In C, you can add a function definition anywhere within the program (except within another function). The only condition is that you must tell the compiler in advance that the function exists somewhere later in the code. You'll do this with a function prototype at the beginning of the program. The prototype is a statement that looks similar to the first line of the definition. In C, you don't have to give the names of the parameters in the prototype, only the data types. The following is what the function prototype would look like for the doubleAndAdd function:

int doubleAndAdd(int, int);

Imagine function prototypes as the packing list for your program. The compiler will unpack and assemble your program just as you might unpack and assemble a new bookshelf. The packing list helps you ensure you have all the pieces you need in the box before you start assembling the bookshelf. The compiler uses the function prototypes in the same way before it starts assembling your program.

If you're following along with the sample.c program we looked at earlier, open and edit the file to add a function prototype, function definition and function call for the doubleAndAdd function shown here. Then, compile and run your program as before to see how the new code works. You can use the following code as a guide to try it out:

#include <stdio.h>

int doubleAndAdd(int, int);

int main()

{

printf("This is output from my first program!\n");

printf("If you double then add 2 and 3, the result is: %d \n", doubleAndAdd(2,3));

return 0;

}

int doubleAndAdd(int a, int b)

{

return ((2*a)+(2*b));

}

So far we've looked at some basic structural elements in a C program. Now, let's look at the types of data you can work with in a C program and what operations you can perform on that data.

Data Types and Operations in C

From your computer's point of view, your program is all just a series of ones and zeros. Data types in C tell the computer how to use some of those bits.
From your computer's point of view, your program is all just a series of ones and zeros. Data types in C tell the computer how to use some of those bits.
Hemera/Thinkstock

From your computer's perspective, data is nothing but a series of ones and zeros representing on and off states for the electronic bits on your hard drive or in your computer's processor or memory. It's the software you're running on a computer that determines how to make sense of those billions of binary digits. C is one of few high-level languages that can easily manipulate data at the bit level in addition to interpreting the data based on a given data type.

A data type is a small set of rules that indicate how to make sense of a series of bits. The data type has a specific size plus its own way of performing operations (such as adding and multiplying) on data of that type. In C, the size of the data type is related to the processor you're using. For example, in C99, a piece of data of the integer data type (int) is 16 bits long in a 16-bit processor while for 32-bit and 64-bit processors it's 32 bits long.

Another important thing for C programmers to know is how the language handles signed and unsigned data types. A signed type means that one of its bits is reserved as the indicator for whether it's a positive or negative number. So, while an unsigned int on a 16-bit system can handle numbers between 0 and 65,535, a signed in on the same system can handle numbers between -32,768 and 32,767. If an operation causes an int variable to go beyond its range, the programmer has to handle the overflow with additional code.

Given these constraints and system-specific peculiarities in C data types and operations, C programmers must choose their data types based on the needs of their programs. Some of the data types they can choose are the primitive data types in C, meaning those built in to the C programming language. Look to your favorite C programming guide for a complete list of the data types in C and important information about how to convert data from one type to another.

C programmers can also create data structures, which combine primitive data types and a set of functions that define how the data can be organized and manipulated. Though the use of data structures is an advanced programming topic and beyond the scope of this article, we will take a look at one of the most common structures: arrays. An array is a virtual list containing pieces of data that are all the same data type. An array's size can't be changed, though its contents can be copied to other larger or smaller arrays.

Though programmers often use arrays of numbers, character arrays, called strings, have the most unique features. A string allows you to save something you might say (like "hello") into a series of characters, which your C program can read in from the user or print out on the screen. String manipulation has such a unique set of operations, it has its own dedicated C library (string.h) with your typical string functions.

The built-in operations in C are the typical operations you'd find in most programming languages. When you're combining several operations into a single statement, be sure to know the operator precedence, or the order in which the program will perform each operation in a mathematical expression. For example, (2+5)*3 equals 21 while 2+5*3 equals 17, because C will perform multiplication before addition unless there are parentheses indicating otherwise.

If you're learning C, make it a priority to familiarize yourself with all of its primitive data types and operations and the precedence for operations in the same expression. Also, experiment with different operations on variables and numbers of different data types.

At this point, you've scratched the surface of some important C basics. Next, though, let's look at how C enables you to write programs without starting from scratch every time.

Don't Start from Scratch, Use Libraries

Libraries are very important in C because the C language supports only the most basic features that it needs. For example, C doesn't contain input-output (I/O) functions to read from the keyboard and write to the screen. Anything that extends beyond the basics must be written by a programmer. If the chunk of code is useful to multiple different programs, it's often put into a library to make it easily reusable.

In our discussion of C so far, we've already seen one library, the standard I/O (stdio) library. The #include line at the beginning of the program instructed the C compiler to loaded the library from its header file named stdio.h. C maintainers include standard C libraries for I/O, mathematical functions, time manipulation and common operations on certain data structures, such as a string of characters. Search the Web or your favorite C programming guide for information about the C89 standard library and the updates and additions in C99.

You, too, can write C libraries. By doing so, you can split your program into reusable modules. This modular approach not only makes it easy to include the same code in multiple programs, but it also makes for shorter program files which are easier to read, test and debug.

To use the functions within a header file, add a #include line for it at the beginning of your program. For standard libraries, put the name of the library's corresponding header file between greater-than and less-than signs (). For libraries you create yourself, put the name of the file between double quotes. Unlike statements in other parts of your C program, you don't have to put a semicolon at the end of each line. The following shows including one of each type of library:

#include <math.h>

#include "mylib.h"

A comprehensive C programming source should provide the instructions you need to write your own libraries in C. The function definitions you'll write are not any different whether they're in a library or in your main program. The difference is that you'll compile them separately in something called an object file (with a name ending in .o), and you'll create a second file, called a header file (with a name ending in .h) which contains the function prototypes corresponding to each function in the library. It's the header file you'll reference in your #include line in each main program that uses your library, and you'll include the object file as an argument in the compiler command each time you compile that program.

The C features we've explored so far are typical in other programming languages, too. Next, though, we'll talk about how C manages your computer's memory.

Some Pointers about Pointers in C

When your C program is loaded into memory (typically the random-access memory, or RAM, in your computer), each piece of the program is associated with an address in memory. This includes the variables you're using to hold certain data. Each time your program calls a function, it loads that function and all of its associated data into memory just long enough to run that function and return a value. If you pass parameters to the function, C automatically makes a copy of the value to use in the function.

Sometimes when you run a function, though, you want to make some permanent change to the data at its original memory location. If C makes a copy of data to use in the function, the original data remains unchanged. If you want to change that original data, you have to pass a pointer to its memory address (pass by reference) instead of passing its value to the function (pass by value).

Pointers are used everywhere in C, so if you want to use the C language fully you have to have a good understanding of pointers. A pointer is a variable like other variables, but its purpose is to store the memory address of some other data. The pointer also has a data type so it knows how to recognize the bits at that memory address.

When you look at two variables side-by-side in C code, you may not always recognize the pointer. This can be a challenge for even the most experienced C programmers. When you first create a pointer, though, it's more obvious because there must be an asterisk immediately before the variable name. This is known as the indirection operator in C. The following example code creates an integer i and a pointer to an integer p:

int i;

int *p;

Currently there is no value assigned to either i or p. Next, let's assign a value to i and then assign p to point to the address of i.

i = 3;

p = &i;

Here you can see the ampersand (&) used as the address operator immediately before i, meaning the "address of i." You don't have to know what that address is to make the assignment. That's good, because it will likely be different every time you run the program! Instead, the address operator will determine the address associated with that variable while the program is running. Without the address operator, the assignment p=i would assign p the memory address of 3, literally, rather than the memory address of the variable i.

Next, let's look at how you can use pointers in C code and the challenges you'll want to be prepared for.

Using Pointers Correctly in C

If you want to become proficient in C programming, you'll need a firm grasp of how to effectively use pointers in your code.
If you want to become proficient in C programming, you'll need a firm grasp of how to effectively use pointers in your code.
©iStockphoto.com/DSGpro

Once you have a pointer, you can use that in place of a variable of the same data type in operations and function calls. In the following example, the pointer to i is used instead of i within a larger operation. The asterisk used with the p (*p) indicates that the operation should use the value that p is pointing to at that memory address, not the memory address itself:

int b;

b = *p + 2;

Without pointers, it's nearly impossible to divide tasks into functions outside of main in your C program. To illustrate this, consider you've created a variable in main called h that stores the user's height to the nearest centimeter. You also call a function you've written named setHeight that prompts the user to set that height value. The lines in your main function might look something like this:

int h;

setHeight(h); /* There is a potential problem here. */

This function call will try to pass the value of h to setHeight. However, when the function finishes running, the value of h will be unchanged because the function only used a copy of it and then discarded it when it finished running.

If you want to change h itself, you should first ensure that the function can take a pointer to an existing value rather than a new copy of a value. The first line of setHeight, then, would use a pointer instead of a value as its parameter (note the indirection operator):

setHeight(int *height) { /* Function statements go here */ }

Then, you have two choices for calling setHeight. The first is to use the address operator for h as the passed parameter (&h). The other is to create a separate pointer to h and pass that instead. The following shows both options:

setHeight(&h); /* Pass the address of h to the function */

int *p;

p = &h;

setHeight(p); /* Pass a separate pointer to the address of h to the function */

The second option reveals a common challenge when using pointers. The challenge is having multiple pointers to the same value. This means that any change in that one value affects all its pointers at once. This could be a good or bad thing, depending on what you're trying to accomplish in your program. Again, mastering the use of pointers is an important key to mastering C programming. Practice with pointers as much as possible so you'll be ready to face these challenges.

The C features we've explored so far are typical in other programming languages, too. Next, though, we'll look at C's demands for careful memory management.

The Importance of Memory Management in C

One of the things that makes C such a versatile language is that the programmer can scale down a program to run with a very small amount of memory. When C was first written, this was an important feature because computers weren't nearly as powerful as they are today. With the current demand for small electronics, from mobile phones to tiny medical devices, there's a renewed interest in keeping the memory requirements small for some software. C is the go-to language for most programmers who need a lot of control over memory usage.

To better understand the importance of memory management, consider how a program uses memory. When you first run a program, it loads into your computer's memory and begins to execute by sending and receiving instructions from the computer's processor. When the program needs to run a particular function, it loads that function into yet another part of memory for the duration of its run, then abandons that memory when the function is complete. Plus, each new piece of data used in the main program takes up memory for the duration of the program.

If you want more control over all this, you need dynamic storage allocation. C supports dynamic storage allocation, which is the ability to reserve memory as you need it and free that memory as soon as you're finished using it. Many programming languages have automatic memory allocation and garbage collection that handle these memory management tasks. C, though, allows (and in some cases requires) you to be explicit about memory allocation with the following key functions from the standard C library:

  • malloc -- Short for memory allocation, malloc is used to reserve a block of memory of a given size to story a certain type of data your program needs to process. When you use malloc, you're creating a pointer to the allocated memory. This isn't necessary for a single piece of data, such as one integer, which is allocated as soon as you first declare it (as in int i). However, it is an important part of creating and managing data structures such as arrays. Alternate memory allocation options in C are calloc, which also clears the memory when it's reserved, and realloc, which resizes previously reserved memory.
  • free -- Use free to force your program to free the memory previously assigned to a given pointer.

Best practice when using malloc and free is that anything you allocate should be freed. Whenever you allocate something, even in a temporary function, it remains in memory until the operating system cleans up the space. To ensure that memory is free and ready to use immediately, though, you should free it before the current function exits. This memory management means you can keep your program's memory footprint to a minimum and avoid memory leaks. A memory leak is a program flaw in which it continues using more and more memory until there's none left to allocate, causing the program to stall or crash. On the other hand, don't get so anxious about freeing memory that you free up, and thus lose, something that you need later in the same function.

Throughout this article, you've learned some of the basic structure and core concepts of the C programming language. We've looked at its history, the characteristics it has in common with other programming languages and the important features that make it a unique and versatile option for coding software. Launch over to the next page for lots more information, including some programming guides that will carry you further on your journey into C.

Related Articles

More Great Links

Sources

  • Kernighan, Brian W., and Ritchie, Dennis M. "C Programming Language, Second Edition." Prentice Hall. 1988.
  • King, K.N. "C Programming: A Modern Approach, Second Edition." W.W. Norton & Company, Inc. 2008.