Hello, World! - The Basics - Programming: Principles and Practice Using C++ (2014)

Programming: Principles and Practice Using C++ (2014)

Part I: The Basics

2. Hello, World!

“Programming is learned by writing programs.”

—Brian Kernighan

Here, we present the simplest C++ program that actually does anything. The purpose of writing this program is to

• Let you try your programming environment

• Give you a first feel of how you can get a computer to do things for you

Thus, we present the notion of a program, the idea of translating a program from human-readable form to machine instructions using a compiler, and finally executing those machine instructions.


2.1 Programs

2.2 The classic first program

2.3 Compilation

2.4 Linking

2.5 Programming environments


2.1 Programs

To get a computer to do something, you (or someone else) have to tell it exactly — in excruciating detail — what to do. Such a description of “what to do” is called a program, and programming is the activity of writing and testing such programs.

In a sense, we have all programmed before. After all, we have given descriptions of tasks to be done, such as “how to drive to the nearest cinema,” “how to find the upstairs bathroom,” and “how to heat a meal in the microwave.” The difference between such descriptions and programs is one of degree of precision: humans tend to compensate for poor instructions by using common sense, but computers don’t. For example, “turn right in the corridor, up the stairs, it’ll be on your left” is probably a fine description of how to get to the upstairs bathroom. However, when you look at those simple instructions, you’ll find the grammar sloppy and the instructions incomplete. A human easily compensates. For example, assume that you are sitting at the table and ask for directions to the bathroom. You don’t need to be told to get up from your chair to get to the corridor, somehow walk around (and not across or under) the table, not to step on the cat, etc. You’ll not have to be told not to bring your knife and fork or to remember to switch on the light so that you can see the stairs. Opening the door to the bathroom before entering is probably also something you don’t have to be told.

In contrast, computers are really dumb. They have to have everything described precisely and in detail. Consider again “turn right in the corridor, up the stairs, it’ll be on your left.” Where is the corridor? What’s a corridor? What is “turn right”? What stairs? How do I go up stairs? (One step at a time? Two steps? Slide up the banister?) What is on my left? When will it be on my left? To be able to describe “things” precisely for a computer, we need a precisely defined language with a specific grammar (English is far too loosely structured for that) and a well-defined vocabulary for the kinds of actions we want performed. Such a language is called a programming language, and C++ is a programming language designed for a wide selection of programming tasks.

If you want greater philosophical detail about computers, programs, and programming, (re)read Chapter 1. Here, let’s have a look at some code, starting with a very simple program and the tools and techniques you need to get it to run.

2.2 The classic first program

Here is a version of the classic first program. It writes “Hello, World!” to your screen:

// This program outputs the message “Hello, World!” to the monitor

#include "std_lib_facilities.h"

int main() // C++ programs start by executing the function main
{
cout << "Hello, World!\n"; // output “Hello, World!”
return 0;
}

Think of this text as a set of instructions that we give to the computer to execute, much as we would give a recipe to a cook to follow, or as a list of assembly instructions for us to follow to get a new toy working. Let’s discuss what each line of this program does, starting with the line

cout << "Hello, World!\n"; // output “Hello, World!”

That’s the line that actually produces the output. It prints the characters Hello, World! followed by a newline; that is, after writing Hello, World!, the cursor will be placed at the start of the next line. A cursor is a little blinking character or line showing where you can type the next character.

Image

In C++, string literals are delimited by double quotes ("); that is, "Hello, World!\n" is a string of characters. The \n is a “special character” indicating a newline. The name cout refers to a standard output stream. Characters “put into cout” using the output operator << will appear on the screen. The name cout is pronounced “see-out” and is an abbreviation of “character output stream.” You’ll find abbreviations rather common in programming. Naturally, an abbreviation can be a bit of a nuisance the first time you see it and have to remember it, but once you start using abbreviations repeatedly, they become second nature, and they are essential for keeping program text short and manageable.

The end of that line

// output “Hello, World!”

is a comment. Anything written after the token // (that’s the character /, called “slash,” twice) on a line is a comment. Comments are ignored by the compiler and written for the benefit of programmers who read the code. Here, we used the comment to tell you what the beginning of that line actually did.

Comments are written to describe what the program is intended to do and in general to provide information useful for humans that can’t be directly expressed in code. The person most likely to benefit from the comments in your code is you — when you come back to that code next week, or next year, and have forgotten exactly why you wrote the code the way you did. So, document your programs well. In §7.6.4, we’ll discuss what makes good comments.

Image

A program is written for two audiences. Naturally, we write code for computers to execute. However, we spend long hours reading and modifying the code. Thus, programmers are another audience for programs. So, writing code is also a form of human-to-human communication. In fact, it makes sense to consider the human readers of our code our primary audience: if they (we) don’t find the code reasonably easy to understand, the code is unlikely to ever become correct. So, please don’t forget: code is for reading — do all you can to make it readable. Anyway, the comments are for the benefit of human readers only; the computer doesn’t look at the text in comments.

The first line of the program is a typical comment; it simply tells the human reader what the program is supposed to do:

// This program outputs the message “Hello, World!” to the monitor

Such comments are useful because the code itself says what the program does, not what we meant it to do. Also, we can usually explain (roughly) what a program should do to a human much more concisely than we can express it (in detail) in code to a computer. Often such a comment is the first part of the program we write. If nothing else, it reminds us what we are trying to do.

The next line

#include "std_lib_facilities.h"

is an “#include directive.” It instructs the computer to make available (“to include”) facilities from a file called std_lib_facilities.h. We wrote that file to simplify use of the facilities available in all implementations of C++ (“the C++ standard library”). We will explain its contents as we go along. It is perfectly ordinary standard C++, but it contains details that we’d rather not bother you with for another dozen chapters. For this program, the importance of std_lib_facilities.h is that we make the standard C++ stream I/O facilities available. Here, we just use the standard output stream, cout, and its output operator, <<. A file included using #include usually has the suffix .h and is called a header or a header file. A header contains definitions of terms, such as cout, that we use in our program.

How does a computer know where to start executing a program? It looks for a function called main and starts executing the instructions it finds there. Here is the function main of our “Hello, World!” program:

int main() // C++ programs start by executing the function main
{
cout << "Hello, World!\n;" // output “Hello, World!”
return 0;
}

Image

Every C++ program must have a function called main to tell it where to start executing. A function is basically a named sequence of instructions for the computer to execute in the order in which they are written. A function has four parts:

• A return type, here int (meaning “integer”), which specifies what kind of result, if any, the function will return to whoever asked for it to be executed. The word int is a reserved word in C++ (a keyword), so int cannot be used as the name of anything else (see §A.3.1).

• A name, here main.

• A parameter list enclosed in parentheses (see §8.2 and §8.6), here (); in this case, the parameter list is empty.

• A function body enclosed in a set of “curly braces,” { }, which lists the actions (called statements) that the function is to perform.

It follows that the minimal C++ program is simply

int main() { }

That’s not of much use, though, because it doesn’t do anything. The main() (“the main function”) of our “Hello, World!” program has two statements in its body:

cout << "Hello, World!\n"; // output “Hello, World!”
return 0;

First it’ll write Hello, World! to the screen, and then it will return a value 0 (zero) to whoever called it. Since main() is called by “the system,” we won’t use that return value. However, on some systems (notably Unix/Linux) it can be used to check whether the program succeeded. A zero (0) returned by main() indicates that the program terminated successfully.

A part of a C++ program that specifies an action and isn’t an #include directive (or some other preprocessor directive; see §4.4 and §A.17) is called a statement.

2.3 Compilation

Image

C++ is a compiled language. That means that to get a program to run, you must first translate it from the human-readable form to something a machine can “understand.” That translation is done by a program called a compiler. What you read and write is called source code or program text, and what the computer executes is called executable, object code, or machine code. Typically C++ source code files are given the suffix .cpp (e.g., hello_world.cpp) or .h (as in std_lib_facilities.h), and object code files are given the suffix .obj (on Windows) or .o (Unix). The plain word codeis therefore ambiguous and can cause confusion; use it with care only when it is obvious what’s meant by it. Unless otherwise specified, we use code to mean “source code” or even “the source code except the comments,” because comments really are there just for us humans and are not seen by the compiler generating object code.

Image

The compiler reads your source code and tries to make sense of what you wrote. It looks to see if your program is grammatically correct, if every word has a defined meaning, and if there is anything obviously wrong that can be detected without trying to actually execute the program. You’ll find that compilers are rather picky about syntax. Leaving out any detail of our program, such as an #include file, a semicolon, or a curly brace, will cause errors. Similarly, the compiler has absolutely zero tolerance for spelling mistakes. Let us illustrate this with a series of examples, each of which has a single small error. Each error is an example of a kind of mistake we often make:

// no #include here
int main()
{
cout << "Hello, World!\n";
return 0;
}

We didn’t include something to tell the compiler what cout was, so the compiler complains. To correct that, let’s add a header file:

#include "std_facilities.h"
int main()
{
cout << "Hello, World!\n";
return 0;
}

Unfortunately, the compiler again complains: we misspelled std_lib_facilities.h. The compiler also objects to this:

#include "std_lib_facilities.h"
int main()
{
cout << "Hello, World!\n;
return 0;
}

We didn’t terminate the string with a ". The compiler also objects to this:

#include "std_lib_facilities.h"
integer main()
{
cout << "Hello, World!\n";
return 0;
}

The abbreviation int is used in C++ rather than the word integer. The compiler doesn’t like this either:

#include "std_lib_facilities.h"
int main()
{
cout < "Hello, World!\n";
return 0;
}

We used < (the less-than operator) rather than << (the output operator). The compiler also objects to this:

#include "std_lib_facilities.h"
int main()
{
cout << 'Hello, World!\n';
return 0;
}

We used single quotes rather than double quotes to delimit the string. Finally, the compiler gives an error for this:

#include "std_lib_facilities.h"
int main()
{
cout << "Hello, World!\n"
return 0;
}

We forgot to terminate the output statement with a semicolon. Note that many C++ statements are terminated by a semicolon (;). The compiler needs those semicolons to know where one statement ends and the next begins. There is no really short, fully correct, and nontechnical way of summarizing where semicolons are needed. For now, just copy our pattern of use, which can be summarized as: “Put a semicolon after every expression that doesn’t end with a right curly brace (}).”

Why do we spend two pages of good space and minutes of your precious time showing you examples of trivial errors in a trivial program? To make the point that you — like all programmers — will spend a lot of time looking for errors in program source text. Most of the time, we look at text with errors in it. After all, if we were convinced that some code was correct, we’d typically be looking at some other code or taking the time off. It came as a major surprise to the early computer pioneers that they were making mistakes and had to devote a major portion of their time to finding them. It is still a surprise to most newcomers to programming.

Image

When you program, you’ll get quite annoyed with the compiler at times. Sometimes it appears to complain about unimportant details (such as a missing semicolon) or about things you consider “obviously right.” However, the compiler is usually right: when it gives an error message and refuses to produce object code from your source code, there is something not quite right with your program; that is, the meaning of what you wrote isn’t precisely defined by the C++ standard.

Image

Image

The compiler has no common sense (it isn’t human) and is very picky about details. Since it has no common sense, you wouldn’t like it to try to guess what you meant by something that “looked OK” but didn’t conform to the definition of C++. If it did and its guess was different from yours, you could end up spending a lot of time trying to figure out why the program didn’t do what you thought you had told it to do. When all is said and done, the compiler saves us from a lot of self-inflicted problems. It saves us from many more problems than it causes. So, please remember: the compiler is your friend; possibly, the compiler is the best friend you have when you program.

2.4 Linking

Image

A program usually consists of several separate parts, often developed by different people. For example, the “Hello, World!” program consists of the part we wrote plus parts of the C++ standard library. These separate parts (sometimes called translation units) must be compiled and the resulting object code files must be linked together to form an executable program. The program that links such parts together is (unsurprisingly) called a linker:

Image

Please note that object code and executables are not portable among systems. For example, when you compile for a Windows machine, you get object code for Windows that will not run on a Linux machine.

A library is simply some code — usually written by others — that we access using declarations found in an #included file. A declaration is a program statement specifying how a piece of code can be used; we’ll examine declarations in detail later (e.g., §4.5.2).

Errors found by the compiler are called compile-time errors, errors found by the linker are called link-time errors, and errors not found until the program is run are called run-time errors or logic errors. Generally, compile-time errors are easier to understand and fix than link-time errors, and link-time errors are often easier to find and fix than run-time errors and logic errors. In Chapter 5 we discuss errors and the ways of handling them in greater detail.

2.5 Programming environments

To program, we use a programming language. We also use a compiler to translate our source code into object code and a linker to link our object code into an executable program. In addition, we use some program to enter our source code text into the computer and to edit it. These are just the first and most crucial tools that constitute our programmer’s tool set or “program development environment.”

If you work from a command-line window, as many professional programmers do, you will have to issue the compile and link commands yourself. If instead you use an IDE (“interactive development environment” or “integrated development environment”), as many professional programmers also do, a simple click on the correct button will do the job. See Appendix C for a description of how to compile and link on your C++ implementation.

IDEs usually include an editor with helpful features like color coding to help distinguish between comments, keywords, and other parts of your program source code, plus other facilities to help you debug your code, compile it, and run it. Debugging is the activity of finding errors in a program and removing them; you’ll hear a lot about that along the way.

Working with this book, you can use any system that provides an up-to-date, standards-conforming implementation of C++. Most of what we say will, with very minor modifications, be true for all implementations of C++, and the code will run everywhere. In our work, we use several different implementations.

ImageDrill

So far we have talked about programming, code, and tools (such as compilers). Now you have to get a program to run. This is a crucial point in this book and in learning to program. This is where you start to develop practical skills and good programming habits. The exercises for this chapter are focused on getting you acquainted with your software development environment. Once you get the “Hello, World!” program to run, you will have passed the first major milestone as a programmer.

The purpose of a drill is to establish or reinforce your practical programming skills and give you experience with programming environment tools. Typically, a drill is a sequence of modifications to a single program, “growing” it from something completely trivial to something that might be a useful part of a real program. A traditional set of exercises is designed to test your initiative, cleverness, or inventiveness. In contrast, a drill requires little invention from you. Typically, sequencing is crucial, and each individual step should be easy (or even trivial). Please don’t try to be clever and skip steps; on average that will slow you down or even confuse you.

You might think you understand everything you read and everything your Mentor or instructor told you, but repetition and practice are necessary to develop programming skills. In this regard, programming is like athletics, music, dance, or any skill-based craft. Imagine people trying to compete in any of those fields without regular practice. You know how well they would perform. Constant practice — for professionals that means lifelong constant practice — is the only way to develop and maintain a high-level practical skill.

Image

So, never skip the drills, no matter how tempted you are; they are essential to the learning process. Just start with the first step and proceed, testing each step as you go to make sure you are doing it right.

Image

Don’t be alarmed if you don’t understand every detail of the syntax you are using, and don’t be afraid to ask for help from instructors or friends. Keep going, do all of the drills and many of the exercises, and all will become clear in due time.

So, here is your first drill:

1. Go to Appendix C and follow the steps required to set up a project. Set up an empty console C++ project called hello_world.

2. Type in hello_world.cpp, exactly as specified below, save it in your practice directory (folder), and include it in your hello_world project.

#include "std_lib_facilities.h"
int main() // C++ programs start by executing the function main
{
cout << "Hello, World!\n"; // output “Hello, World!”
keep_window_open(); // wait for a character to be entered
return 0;
}

The call to keep_window_open() is needed on some Windows machines to prevent them from closing the window before you have a chance to read the output. This is a peculiarity/feature of Windows, not of C++. We defined keep_window_open() in std_lib_facilities.h to simplify writing simple text programs.

How do you find std_lib_facilities.h? If you are in a course, ask your instructor. If not, download it from our support site www.stroustrup.com/Programming. But what if you don’t have an instructor and no access to the web? In that case (only), replace the #include directive with

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
inline void keep_window_open() { char ch; cin>>ch; }

This uses the standard library directly, will keep you going until Chapter 5, and will be explained in detail later (§8.7).

3. Compile and run the “Hello, World!” program. Quite likely, something didn’t work quite right. It very rarely does in a first attempt to use a new programming language or a new programming environment. Find the problem and fix it! This is a point where asking for help from a more experienced person is sensible, but be sure to understand what you are shown so that you can do it all by yourself before proceeding further.

4. By now, you have probably encountered some errors and had to correct them. Now is the time to get a bit better acquainted with your compiler’s error-detection and error-reporting facilities! Try the six errors from §2.3 to see how your programming environment reacts. Think of at least five more errors you might have made typing in your program (e.g., forget keep_window_open(), leave the Caps Lock key on while typing a word, or type a comma instead of a semicolon) and try each to see what happens when you try to compile and run those versions.

Review

Image

The basic idea of these review questions is to give you a chance to see if you have noticed and understood the key points of the chapter. You may have to refer back to the text to answer a question; that’s normal and expected. You may have to reread whole sections; that too is normal and expected. However, if you have to reread the whole chapter or have problems with every review question, you should consider whether your style of learning is effective. Are you reading too fast? Should you stop and do some of the Try this suggestions? Should you study with a friend so that you can discuss problems with the explanations in the text?

1. What is the purpose of the “Hello, World!” program?

2. Name the four parts of a function.

3. Name a function that must appear in every C++ program.

4. In the “Hello, World!” program, what is the purpose of the line return 0;?

5. What is the purpose of the compiler?

6. What is the purpose of the #include directive?

7. What does a .h suffix at the end of a file name signify in C++?

8. What does the linker do for your program?

9. What is the difference between a source file and an object file?

10. What is an IDE and what does it do for you?

11. If you understand everything in the textbook, why is it necessary to practice?

Most review questions have a clear answer in the chapter in which they appear. However, we do occasionally include questions to remind you of relevant information from other chapters and sometimes even relating to the world outside this book. We consider that fair; there is more to writing good software and thinking about the implications of doing so than fits into an individual chapter or book.

Terms

These terms present the basic vocabulary of programming and of C++. If you want to understand what people say about programming topics and to articulate your own ideas, you should know what each means.

//

<<

C++

comment

compiler

compile-time error

cout

executable

function

header

IDE

#include

library

linker

main()

object code

output

program

source code

statement

You might like to gradually develop a glossary written in your own words. You can do that by repeating exercise 5 below for each chapter.

Exercises

We list drills separately from exercises; always complete the chapter drill before attempting an exercise. Doing so will save you time.

1. Change the program to output the two lines

Hello, programming!
Here we go!

2. Expanding on what you have learned, write a program that lists the instructions for a computer to find the upstairs bathroom, discussed in §2.1. Can you think of any more steps that a person would assume, but that a computer would not? Add them to your list. This is a good start in “thinking like a computer.” Warning: For most people, “go to the bathroom” is a perfectly adequate instruction. For someone with no experience with houses or bathrooms (imagine a stone-age person, somehow transported into your dining room) the list of necessary instructions could be very long. Please don’t use more than a page. For the benefit of the reader, you may add a short description of the layout of the house you are imagining.

3. Write a description of how to get from the front door of your dorm room, apartment, house, whatever, to the door of your classroom (assuming you are attending some school; if you are not, pick another target). Have a friend try to follow the instructions and annotate them with improvements as he or she goes along. To keep friends, it may be a good idea to “field test” those instructions before giving them to a friend.

4. Find a good cookbook. Read the instructions for baking blueberry muffins (if you are in a country where “blueberry muffins” is a strange, exotic dish, use a more familiar dish instead). Please note that with a bit of help and instruction, most of the people in the world can bake delicious blueberry muffins. It is not considered advanced or difficult fine cooking. However, for the author, few exercises in this book are as difficult as this one. It is amazing what you can do with a bit of practice.

• Rewrite those instructions so that each individual action is in its own numbered paragraph. Be careful to list all ingredients and all kitchen utensils used at each step. Be careful about crucial details, such as the desired oven temperature, preheating the oven, the preparation of the muffin pan, the way to time the cooking, and the need to protect your hands when removing the muffins from the oven.

• Consider those instructions from the point of view of a cooking novice (if you are not one, get help from a friend who does not know how to cook). Fill in the steps that the book’s author (almost certainly an experienced cook) left out for being obvious.

• Build a glossary of terms used. (What’s a muffin pan? What does preheating do? What do you mean by “oven”?)

• Now bake some muffins and enjoy your results.

5. Write a definition for each of the terms from “Terms.” First try to see if you can do it without looking at the chapter (not likely), then look through the chapter to find definitions. You might find the difference between your first attempt and the book’s version interesting. You might consult some suitable online glossary, such as www.stroustrup.com/glossary.html. By writing your own definition before looking it up, you reinforce the learning you achieved through your reading. If you have to reread a section to form a definition, that just helps you to understand. Feel free to use your own words for the definitions, and make the definitions as detailed as you think reasonable. Often, an example after the main definition will be helpful. You may like to store the definitions in a file so that you can add to them from the “Terms” sections of later chapters.

Postscript

Image

What’s so important about the “Hello, World!” program? Its purpose is to get us acquainted with the basic tools of programming. We tend to do an extremely simple example, such as “Hello, World!,” whenever we approach a new tool. That way, we separate our learning into two parts: first we learn the basics of our tools with a trivial program, and later we learn about more complicated programs without being distracted by our tools. Learning the tools and the language simultaneously is far harder than doing first one and then the other. This approach to simplifying learning a complex task by breaking it into a series of small (and more manageable) steps is not limited to programming and computers. It is common and useful in most areas of life, especially in those that involve some practical skill.