Raspberry Pi Computer Architecture Essentials
上QQ阅读APP看书,第一时间看更新

The C and C++ languages

Even if you are new to programming you may have come across C and C++ mentioned in literature, webpages, and text books. You'll often see C/C++ written. However, it is important to realize that while C++ is based upon C they are indeed different languages, and useful in different contexts.

We are going to start by giving a brief overview of these languages and explain a bit about them. Following this we will write some experimental programs and explore how the compiler works.

Let's start by delving a bit further into C.

C – a brief introduction

The C programming language has been around since 1970s and was closely tied with the development of the Unix operating system.

In 1972, the computer scientist Dennis Ritchie started the development of C in Assembly language on the PDP-11 Unix system. As we demonstrated in the previous section, Assembly language is converted to machine code, and Ritchie's C language represented another level of abstraction from the computer hardware and Assembly itself.

Shortly after, in February 1973, the C language could be found bundled with the Unix release and available for developers.

In the 1980s, due to its widespread adoption, the American National Standards Institute (ANSI) formed a committee known as X3J11 to adopt a standard for the C programming language. This would help to govern the direction of the language and formalize its specifications.

By 1990 the C standard championed by ANSI was adopted by the International Organization for Standardization (ISO) who would then help to steer its future path.

From these early days the C language has gone through several revisions and been ported to many computer architectures, including Linux on the Raspberry Pi 2. It has thus become a popular choice for application development due to its ubiquitous nature.

The Linux operating system, of which Raspbian is a flavor, is written in the C language. Therefore, if you wish to write applications at the operating system level, having a good command of the C language is invaluable.

One of the great features of C and a contributing factor to why it is popular for embedded device software development is its speed. Most C implementations are compiled directly to machine code and the software engineer has full control over what happens at the hardware level.

Later in this book we cover hardware development and programming, and the C language is something you will encounter when working on these projects.

Now that we have briefly touched upon C, let's take a look at C++.

A quick look at C++

The C++ programming language's origins can be found in the late 1970s with Danish computer scientist Bjarne Stroustrup. Stroustrup looked to implement a version of the C programming language that incorporated object-oriented features from the Simula programming language, such as classes.

At first, the language was known as C with classes and in 1983 adopted the name we are all familiar with, C++.

Throughout the 1980s, the book The C++ Programming Language acted as the main reference guide to the language. Following this the language went through several revisions and was adopted as an ISO standard in 1998.

While C++ is based upon C it does contain some notable differences due to not retaining complete source level compatibility with the original C language.

For those interested in a further look at these differences you can find a summary on Wikipedia at https://en.wikipedia.org/wiki/Compatibility_of_C_and_C%2B%2B.

Where C++ also differs from C is its inclusion of many OOP features such as the following:

  • Classes
  • Interfaces and abstract classes
  • Objects
  • Inheritance

You may be wondering why we are interested in both C and C++. After all, if the operating system is written in C, and C is good for many electronic projects, why look at C++?As you will discover in the Raspberry Pi world, hardware such as the Raspberry Pi to Arduino Connection Bridge uses a C++-based library.

Therefore, familiarizing yourself with the language will help you to implement third party libraries that contain many interesting features and functionality.

As we noted, since C++ is based upon the C language, in this chapter we will start by writing a simple C program only.

This will give you an introduction to the basic structure of a program and header files. In future chapters we will expand upon this to include C++ libraries, explore the differences between the languages when relevant, and look at how to include C header files in a C++ application.

Let's now delve into writing our first C application.

Our first C program

In order to write our first program we need three key things. These are similar to those needed when writing our Assembly language program:

  • A good text editor such as Vim
  • C libraries of re-usable code
  • The C compiler

The text editor you use will largely be driven by your own tastes. In the previous chapter of this book we briefly looked at Vim and also linked to a number of other text editors recommended on the Raspberry Pi website.

When writing our Assembly language application, you were presented the choice of using whichever editor you were comfortable with.

Another popular GUI-based text editor you may be interested in using is Geany. Feel free to skip this section if you would prefer not to use this editor.

Geany – a handy text editor and development environment

The Geany text editing environment provides support for integrating development tools such as Makefiles and compilers and provides a neat GUI for editing code files. This integration can help when you start to work on larger projects.

For example, you can hook up the GCC compiler to work in Geany and thus compile your applications and test them from within the text editor.

Note

Makefiles are a way of combining many commands, such as those needed to compile projects into a single file. These can then be run from the command line using the make application. You can read more on make at http://man7.org/linux/man-pages/man1/make.1.html.

If you are interested in testing this out, you can install it via the package manager:

sudo apt-get install geany

More information on the editor and its development tool support can be found at http://www.geany.org/Documentation/Manual.

Now, with whichever text editor you have chosen we are going to create a new C program. This will help us to explore the second and third bullet point from our previous list.

Creating a new C program

Our first task is to create a new folder on the Raspberry Pi 2 to store our source code in.

In the exercise in this section of the chapter we will store the code in a directory called c_programs. You can create this under the Pi user as follows:

mkdir /home/pi/c_programs

Once you have this directory created we can write our C program. Using whichever text editor you prefer, create a file called first_c_prog.c. For example, if you were using Vim, you would create the file as follows:

vim /home/pi/c_programs/first_c_prog.c

Users of Geany can create a new file from directly inside the IDE.

The following program demonstrates how we can enter a value into our program via the keyboard and then display it back to the user. Let's start by adding the first line at the top of the file:

#include <stdio.h>

This is an example of an include statement. Here we are telling the program to use the stdio.h library. This library contains standard input and output functions. Examples of functions in this program we will be using from this library include printf() and scanf().The next section of this chapter explains libraries in more detail. So for the moment let's move on and add the main body of our program:

int main(void)
{
  int a;
  printf("Please input an integer: ");
  scanf("%d", &a);
  printf("You entered the number: %d\n", a);
  return 0;
}

Each C program needs to contain a main() function. You'll remember from your Assembly program we also had a function called main. This is the entry point of the program.

The signature of our function is as follows:

int main(void)

This tells us that the main function has no variables passed to it but returns an integer value when it has finished running.

Within the braces of the program we have five lines of code.

The first line defines an integer variable with the name a. The second line uses a function that is included from the stdio.h library called printf(). This function allows us to print text to the screen.

In our case we are prompting the user to enter an integer value.

Following this, the scanf() function is used to take user input from the keyboard and store it in the a variable.

The %d you can see in the function tells us that the function is expecting an integer. Here we can also see the reference to the variable a uses the & symbol. In this instance, & is used to tell the scanf() function the location of the variable, rather than the variable's value.

The next thing we want to do is print out the value entered. This is done using the printf() function once again. Here we use %d to say we want to output an integer as part of the string. \n is used to denote a new line. Finally, you can see the a variable is included. This time we want its actual value so we do not include the &.

The value of a is then inserted into the string where %d is when the string is displayed.

The final line of code before the closing brace is the return statement. The return statement contains the integer 0 after it (and is why we prefixed int to the function name). This means our program executed without a problem, so we return 0 to show there is no error code.

In our Assembly program we returned the value 30. As you will see, this 0 value is also available via the echo command we were introduced to earlier.

Before running this program, we are going to return to the top of our program and explore libraries further.

C libraries – a trove of reusable code

As you saw in our first C program we included a header file: stdio.h.

Within the C language, many problems have already been solved, for example, how to take input from the keyboard and print it to the screen. These solved problems are then packaged as C code libraries and can be included via .h files, thus sharing the code between multiple source files.

Header files can be written by either the programmer working on a project, or included in the default system code that comes bundled with your operating system.

To include a header in your application you use the include statement, #include.

There are then two formats for how you specify the library to include. One uses angular brackets (<) and the other uses quotation marks (").

When you are including a system header such as stdio.h, then use angular brackets:

#include <stdio.h>

The compiler will then look in a list of standard system directories such as /usr/lib.

If you wish to include a header file you wrote yourself, then use quotations:

#include "mylib.h"

You can find a comprehensive list of system level header files at http://en.cppreference.com/w/c/header.

Strictly speaking, the header file tells the C compiler certain things, such as function declarations, but does not contain their definitions. The library file however contains the actual executable code referenced in the header file. When we explore the C compiler in the next section, we will explain how we include the executable code via the linker.

The simplest way to think of this is: the header tells us what exists and the library contains the code that does it.

The C (and C++) compiler

We now have the source code for our small program, but until it has been compiled it can't be run.

The compiler performs the task of taking a high level language such as C and decoding it into machine code. This machine code can then be read by the processor and is how the computer executes our program.

However, even after we have compiled our program successfully, it is still not ready to be run. There is another stage we need to consider—linking. You will recognize this from our earlier Assembly language program.

The linker is an important part of the process of building a C-based executable. It is responsible for taking separate object files and linking them together in order to create a single executable. This methodology allows us to take a compiled third party library, reference it in our code, and then include it via the linking method. Thus we do not need to recompile the third party library along with our code.

Unlike the steps required for Assembly, the preceding can usually be performed in a single command, which handles the linking and machine code generation.

In fact, the process of building an executable is even more complex than we have touched upon here. However, for the program you will be writing, understanding you need to invoke the compiler and link to third party objects should be sufficient.

For those interested in reading further can visit http://www.tenouk.com/ModuleW.html, which provides a greater breakdown.

As you saw previously, the GCC compiler is installed by default on Raspbian. You can read more about it at the gnu.org website, https://gcc.gnu.org/.

The GCC compiler supports a number of languages other than Assembly including C and C++. When we wish to compile a program we can use the gcc command in the terminal window to invoke the compiler.

You will be familiar with this from using it in the linking stage in your first Assembly program.

As you come to use the compiler there are a number of items you need to consider. These include the following:

  • The input file that is your C code
  • The output file that is your compiled program
  • Options for the linker to tell it which libraries to include

Taking the program we wrote, first_c_prog.c, we will now compile and run it so you can see gcc in action and explore the preceding bullet points.

Compiling and running our application

The following instructions assume you saved your C code into the c_programs directory.

Navigate into this directory:

cd /home/pi/c_programs

From here we will now invoke the GCC compiler using the following command:

gcc –o first_c_prog first_c_prog.c

This command is very simple, and we have not had to specify the linker. You may be wondering why this is, considering the fact we included the stdio header.

This is because certain functions are linked by default, such as those in libc, therefore we do not need to manually link them. As you explore the C language further, however, you will quickly come across instances where you have to link.

You can check which headers are available from the C standard library in each version of the C language at https://en.wikipedia.org/wiki/C_standard_library.

In this command we have addressed the first bullet point in the list, the input file that is our program. In our command it is the last parameter we pass in.

As we stated, we do not need to add any references to the linker, which would be the third bullet point.

Finally, the second bullet point is covered by –o first_c_prog, which tells us to output the executable called first_c_prog.

If you run ls in the directory, you should see the first_c_prog file.

You can now run this by typing:

./first_c_prog

If this executed successfully, you will be prompted to enter an integer. Once entering this you will see it output to the screen.

Tip

Try entering a non-integer such as an alphabet character and see what happens.

This concludes writing our first C program. Hopefully you will agree it was fairly easy to write!

Next we will look at the Python programming language. Python is a handy scripting and object-oriented programming language and uses C as its base, as you will see.