Hello World
Sections
The Code§
#include <print>
int main(int argc, char* argv[])
{
std::print("Hello World!");
return 0;
}
Execution Direction and Semicolon§
Several quick pieces of knowledge to lay out first.
Firstly, in general, unless you explicitly tell the program otherwise, code will execute from top to bottom. Thus, when we are reading or reviewing code, we should generally do the same: read from top to bottom.
Secondly, C++ requires a semicolon (;) at the end of most statements.
A statement is essentially an instruction that the program can execute. Not every line of code is a statement, and therefore not every line needs a semicolon.
Don't worry about memorizing exactly what is and isn't a statement right now. It will become clear very quickly as we continue.
Print Function and Console§
Without understanding why just yet, accept the fact that whenever you call the function std::print(), it can output text to the console.
For basic understanding, the console is an interface for you to interact with a program using text.
Therefore, std::print() is used to output text to the console.
Entry Point§
Don't worry if you do not understand the code yet. This is why you are here.
But first, let's understand how a computer runs a program in general.
No matter what language you write in or what you are trying to make, your computer needs to know where the program starts.
This is what we call the entry point: the point where the computer begins executing your program.
In C++, the entry point is a function called main.
This is the part:
int main()
{
...
}
When the program is executed, the execution of the program begins by calling main().
Function§
What is a Function?§
When explaining the entry point, we mentioned that main is a function.
So, what is a function?
Assuming you have some high-school knowledge of mathematics, you have probably seen functions such as:
sin(x)
cos(x)
It does not matter whether you know how to calculate their values by hand. At the very least, you know that a function can take an input and produce an output.
For example:
sin(30°) = 0.5
The exact same general concept exists in programming.
When your computer runs your program, it calls main().
For those who do not have high-school knowledge of functions, think of a function as a black box.
You give it some input, it performs some operation, and it gives you an output.
You do not necessarily need to know how the operation is performed internally. You only need to know what the function does.
For example:
sin(30°) = 0.5
Here, 30° is the input and 0.5 is the output.
The purpose of sin() is to calculate the sine of the given angle.
How is that calculation actually performed?
Not important for now. As long as you understand what goes into the function and what comes out of it, you understand the basic idea of a function.
Syntax for a Function§
A simplified representation of a function looks like this:
type functionName(type argument)
{
calculations
return result;
}
This is only a conceptual representation. Do not literally type it into your program.
functionName is an arbitrary name that you choose for your function.
For example:
sin
cos
print
blablabla
These are all possible names in principle, as long as they follow C++'s naming rules and do not conflict with something that already exists in the relevant scope.
In the case of the entry point, the name is main, because C++ specifically requires the program's entry point to be a function called main.
The exact same concept applies to the argument name.
Note
print Function
You can create a function called print, but you should generally avoid creating names that conflict with existing functions, especially when you are using the standard library. C++ already provides std::print(), so creating another print can make it unclear which function you are referring to.
Type and Argument§
A type is something such as:
int
float
std::string
Assuming you are a total beginner, I do not expect you to memorize or understand every type available in C++ yet.
Just remember that types are not arbitrary in the same way function names are. C++ has specific types and rules for how they can be used.
For now, think of a type as describing what kind of data you are working with.
For example:
intrepresents an integer.floatrepresents a floating-point number.std::stringrepresents text.
C++ needs to know what type you are working with when you define a function, both for its return value and for its arguments.
For a rough analogy, imagine that you want to determine the visual score of a room based on the colors of its walls and floor.
You might imagine a function like this:
Score Validate(Color wallColor, Color floorColor)
{
if the wallColor is black and the floorColor is white:
return 10;
if the wallColor is red and the floorColor is green:
return 1;
... etc.
}
This is not valid C++ code. It is only an analogy.
The important part is the structure:
Score
Validate
Color wallColor
Color floorColor
The function takes two pieces of information:
wallColor
floorColor
and returns a value representing the score.
The types tell C++ what kind of data those things are.
Now look at your main function:
int main(int argc, char* argv[])
It can also have arguments.
We will discuss argc and argv later. They are commonly used when building command-line programs.
Return Value§
As you can see above, a function can give an output by using the return statement.
For example:
int zero()
{
return 0;
}
This is a function that returns 0 every time it is called.
Now look at the return value of main:
return 0;
Returning 0 from main conventionally means that the program finished successfully.
A non-zero return value conventionally indicates that the program ended with some kind of error or abnormal status.
For example:
int main()
{
return -1;
}
Even though this may be intentional, the program is still returning a non-zero value, so the environment running the program will generally interpret it as a failure.
Exactly what happens with that value depends on how and where the program is being run.
Declaration, Definition, Invocation§
You might ask:
"The code above makes no sense. We defined a function, but nothing happens."
Exactly.
What we have currently is only the definition of the function.
The definition tells the computer:
"If someone asks me to perform this function, this is how I will calculate the result."
It does not mean:
"Perform the function right now."
For example, suppose we define:
Score Validate(Color wallColor, Color floorColor)
{
...
}
This tells C++ how to calculate the score.
It does not ask:
"What is the score for my room?"
To actually ask that question, we need to invoke, or call, the function.
For example:
Validate(black, white);
This invokes the function and gives it the information it needs.
If the function is defined to return 10 for a black wall and white floor, the function will return 10.
We will see what we can do with that returned value later.
So far, we have explained definition and invocation.
But what is a declaration?
A declaration tells C++ that something exists without giving its full implementation.
For example:
Score Validate(Color wallColor, Color floorColor);
This tells C++:
There exists a function called
Validate. It takes twoColorarguments and returns aScore.
The actual definition can then appear somewhere else:
Score Validate(Color wallColor, Color floorColor)
{
...
}
This is useful because we do not always want to put the entire implementation of a function before every place where we want to use it.
For example, a function may be very large, or its implementation may be placed in another source file.
Include and Namespace§
#include and namespaces are unrelated topics, but they are both short enough to introduce here.
Include§
#include <print>
This tells the preprocessor to literally insert the contents of the print header at the location of the #include statement.
For example, imagine we had:
bracel.cpp
{
and:
bracer.cpp
}
Then we could theoretically write:
int main()
#include <bracel.cpp>
return 0;
#include <bracer.cpp>
and the result after inclusion would effectively become:
int main()
{
return 0;
}
This demonstrates why the location of an #include matters.
Whatever the included file contains gets inserted at that location before the rest of the compilation process.
In our actual program:
#include <print>
makes the contents of the <print> header available to the rest of our source file.
That is why we can use:
std::print()
after including it.
The <print> header is part of the C++ standard library and was introduced in C++23.
Namespace§
Now look at:
std::print()
and:
std::string
What is the std:: doing?
It is a namespace qualifier.
Think of a namespace as a grouping mechanism.
For example, imagine two different groups both have something called print:
GroupA
print
GroupB
print
If you simply write:
print()
there is no way to tell from the name alone which print you mean.
A namespace allows us to distinguish them:
GroupA::print()
GroupB::print()
The C++ standard library places its names inside the namespace std.
Therefore:
std::print()
means:
The
stdnamespace.
Similarly:
std::string
means:
The
stringtype that belongs to thestdnamespace.
You might then wonder:
"Why don't we put
std::in front of everything?"
Simply because not everything comes from the std namespace.
For example:
int main()
does not have std:: in front of either int or main.
int is a fundamental C++ type, while main is the specially defined entry-point function.
Other names can also come from your own code or from other libraries, each potentially having its own namespace.
If you prefer not to write std:: everywhere, C++ allows you to write:
#include <print>
using namespace std;
int main()
{
print("Hello World!");
}
The statement:
using namespace std;
tells C++ that when resolving names in this scope, names from the std namespace may be used without explicitly writing std::.
However, this can introduce name conflicts, especially in larger programs. For now, it is better to get used to writing:
std::print()
std::string
explicitly.
Comment§
A comment is something that the compiler ignores. It is written for humans rather than for the computer.
There are two common forms of comments.
The first is a line comment:
// This is a comment.
Everything after // on that line is treated as a comment.
For example:
int main()
{
// This is a comment.
}
The second is a block comment:
/*
This is a block comment.
Everything between the opening
and closing markers is a comment.
*/
A block comment can span multiple lines.
For now, I will be using comments throughout this book to make the code easier to understand.
Conclusion§
Putting everything we have learned together:
#include <print>
// Literally includes the contents of the <print> header here.
int main(int argc, char* argv[])
// The entry point of the program.
// Execution begins here.
// argc and argv are arguments that can be used for command-line input.
{
std::print("Hello World!");
// Calls the print function inside the std namespace.
// "Hello World!" is passed to the function as its argument.
// The function outputs the text to the console.
return 0;
// Returns 0 from main, conventionally indicating
// that the program completed successfully.
}
There is already quite a lot happening in this tiny program:
#include <print>literally inserts the contents of the<print>header at that location.mainis the entry point of the program.intis the return type ofmain.argcandargvare arguments ofmain.{and}define the body of the function.std::print()calls theprintfunction inside thestdnamespace."Hello World!"is the argument passed tostd::print().return 0;returns a value frommainand conventionally indicates successful completion.;terminates statements that require semicolons.//introduces a comment that is ignored by the compiler.
Discussion
No comments yet — yours could open the discussion.