(Notes from Codefinity Course — Introduction to C++)
C++ is a low-level programming language, designed more for the purpose of efficiently controlling the hardware it's running on, and with less concern for human readability.
C++ is flexiable in that it allows you to work at both the lower levels for hardware control and at higher levels for managing classes and objects. C++ is used in cases where it is necessary to manipulate memory and maximize calculation speed.
C++ has a wide range of libraries and compilers, so it serves many functions, and runs on many machines and operating systems. It is used for game development, robotics, and embedded systems, where optimization is main goal.
Here is some code in C++ that prints "Hello World!":
main.cpp |
1 | #include <iostream> | |
2 | ||
3 | int main() | |
4 | { | |
5 | using namespace std; | |
6 | ||
7 | //printing "Hello World!" | |
8 | cout << "Hello World!" << endl; | |
9 | ||
10 | return 0; | |
11 | } |
Comment: #include <> creates a connection to libraries. The preprocessor directive #include <iostream> folds in the library named iostream. The function int main() {} is the central (and required) function through which the main program runs. namespace std; declares the object space (in this case, the standard namespace) from which the objects cout and endl are called. // is the comment indicator. return 0; is the "exit status" of the program - that is, the program ends with this statement.
Preprocessor directives are commands that give instructions to the preprocessor, which is a a tool that performs text transformations on the source code before it's compiled. Preprocessor directives begin with the # symbol, and one of the most common preprocessor directives is the #include command. The standard files that the preprocessor includes are bracketed with "less than" and "greater than" symbols (<>), as for example in the command:
#include <iostream>
Comment: The iostream file being included by this command contains code that enables the program to read input from the keyboard and display output to the screen.
The best way to explain a namespace is to describe the problem it avoids. Imagine that you are working with a team of developers and two or more of you happen to select the same name for a function. The program will fail because of the conflict. To avoid this, you declare a private "namespace" — a logical space in which a function will have only the meaning you assign to it. Later, in the main function, you declare what namespace you are using so the function call will not be ambiguous. This creation of a namespace and its later invocation (with "using namespace [namespace_name]") will look like the following:
main.cpp |
1 | #include <iostream> | |
2 | ||
3 | using namespace std; | |
4 | ||
5 | namespace myNamespace | |
6 | { | |
7 | void someFunction() | |
8 |  { | |
9 |  cout << "This is my function." << endl; | |
10 |  } | |
11 | } | |
12 | ||
13 | namespace myTeammates_namespace | |
14 | { | |
15 | void someFunction() | |
16 |  { | |
17 |  cout << "This is my teammate's function." << endl; | |
18 |  } | |
19 | } | |
20 | ||
21 | int main() | |
22 | { | |
23 | using namespace myNamespace; | |
24 | ||
25 | someFunction(); | |
26 | ||
24 | return 0; | |
22 | } |
Code Comments: Notice that the functions in myNamespace and myTeammates_namespace are both named someFunction(). However, this won't cause a conflict because each declaration of those functions is preceded by the declaration of the two private namespaces. When the main function specifies using namespace myNamespace; it's clear that the function created in that specific namespace is the one being invoked.
In C++ there is a standard namespace that contains commonly used commands like cout and endl ("character output" and "end of line"). When you declare the use of the standard namespace in the following way...
using namespace std;
...you are connecting a large number of commands that you may not need (enlarging the code unnecessarily). There are approximately 92 commands in the standard namespace. So instead, for example, if you only need cout and endl you can use the following declarations instead:
using std:cout;
using std:endl;
You can also invoke a namespace and one of its functions right where you use it in the following way:
std::cout << "Hello, World!" << std::endl;
Declaring and initiating variables in C++ is done in a fairly common manner, so I will only mention a few details. You can declare and initiate a variable in the same expression as follows:
int intVariable = 21;
You can declare multiple variables of the same data type in one line as follows:
int intVariable1 = 1, intVariable2 = 2, intVariable3 = 3;
Since economy (and speed) is a virtue in C++, it should be noted that C++ uses both float and double data types. Doubles use 64 bits (8 bytes) of memory, which is useful when precision of up to 15 or 16 decimals is needed. Floats reserve half as much memory — 32 bits (4 bytes) — and are preferable when precision, say, to 1/10,000 is sufficient. Note that even when a float or double is initiated to zero (0), it reserves all the memory that a long decimal would. Also note that floating point variables must store the digits in front of the decimal point, as well as the digits after it. For example, the number 1,234,567.89 will not fit in a float, which is limited to seven digits regardless of which side of the decimal they are on.
On a similar note, there are three types of integers in C++ that use different amounts of memory — the short, int, and long. The following table displays their sizes:
Data Type | Range | Size |
---|---|---|
short | -32,768 to 32,767 | 2 bytes |
int | -2,147,483,648 to 2,147,483,648 | 4 bytes |
long | -9,223,372,036,854,775,808 to 9,223,372,036,854,775,808 | 8 bytes |
Obviously, if you plan to store relatively smaller numbers in a particular field, you can choose the smaller type of integer. However, be careful to choose the right data type. If the range of the type is exceeded, the compiler will not tell you this, and you will may get an incorrect value without warning.
If you try to assign a decimal number to an integer, the decimals will be trimmed. For example, the expression int intNumber = 3.14 will store the 3 only.
To store a string in a variable, you must include the string module with a preprocessor directive ("#include <string>") as in the following example:
main.cpp |
1 | #include <iostream> | |
2 | #include <string> | |
3 | ||
4 | int main() | |
5 | { | |
6 | using std::cout; | |
7 | using std::string; | |
8 | ||
9 | //declare string variable | |
10 | string strVariable = "TEXT\n"; | |
11 | ||
12 | //display string variable | |
13 | cout << strVariable; | |
14 | ||
15 | return 0; | |
16 | } |
Comment: The "/n" following the word "TEXT" in the example above is an "escape sequence." It opens the next line and moves the cursor there. It is the same as endl
Strings can also hold numbers (as strings) when they are demarked with quotation marks, as in the following example:
string strVariable = "2023";
You can concatenate strings with the "+" symbol, as in the following example:
//declare string variables |
string strVar1 = "Hello "; |
string strVar2 = "World!"; |
//display concatenated string variables |
cout << strVar1 + strVar2 << endl; |
Comment: The code snippet above (preceded by the appropriate preprocessor directives and namespace/function declarations) will output: "Hello World!"
You can find the length of a string stored in a string variable by using the length() method, as in the following example:
main.cpp |
1 | #include <iostream> | |
2 | #include <string> | |
3 | ||
4 | int main() | |
5 | { | |
6 | using std::cout; | |
7 | using std::string; | |
8 | ||
9 | //declare and initiate the string variable | |
10 | string strCompanyName = "Aulon Arch"; | |
11 | ||
12 | //use the length() method and display the result | |
13 | cout << strCompanyName.length(); | |
14 | ||
15 | return 0; | |
16 | } |
Comment: The code above returns "10" as the length (including the space between the two words). In C++, a method is a function that is part of a class. The method, in this case, is termed a class member. It is called by using the point operator (.) in front of it.
Comment: Most of the examples of code above end with "return 0" at the end of the main function. This specifies that if the main function runs successfully, a value 0 will be returned to the operating system. (If the code fails, a value of 1 will be returned.) If the header of the main function is written as "int main()", you need "return 0" at the end of the main function. But if the header is written as "void main()" then you don't need to specify the return value. It will be 0 by default.
An array is a list of items (numbers, strings, etc.) stored with a single variable name that has a numerical index identifying each item in the list. In C++, you define an array as follows:
int intPrimeArray[5];
To initialize an array, you specify all of its elements in curly braces:
int intPrimeArray[5] = {1, 2, 3, 5, 7}
To refer to a particular element in the array, you use the variable name with the index number of the item (starting with an index of 0). The following code illustrates these rules:
main.cpp |
1 | #include <iostream> | |
2 | ||
3 | int main() | |
4 | { | |
5 | using std::cout; | |
6 | ||
7 | //declare and initiate an array of small prime numbers | |
8 | int intPrimeArray[5] = {1, 2, 3, 5, 7}; | |
9 | ||
10 | //print the fifth element in the array (using index 4 when starting with 0 | |
11 | cout << intPrimeArray[4]; | |
12 | ||
13 | return 0; | |
14 | } |
The code above will print "7".
You update the items in the array by index, as follows:
intPrimeArray[4] = -7;
Arrays can be elements of other arrays, known as multidimensional arrays. The scale of a multidimensional array is indicated with two pairs of square brackets. The first brackets specifies the number of elements in the upper array, and the second set of brackets the number of elements in the lower array:
int intMultiArray[][]
Here's a sample of code declaring and initiating a multidimensional array:
main.cpp |
1 | #include <iostream> | |
2 | ||
3 | int main() | |
4 | { | |
5 | using std::cout; | |
6 | using std::endl; | |
7 | ||
8 | //declare and initiate a multidimensional array | |
9 | int intDeepArray[4][3] = { {1, 11, 111}, | |
10 | { {2, 22, 222}, | |
11 | td> | { {3, 33, 333}, |
12 | td> | }; |
13 | ||
14 | //print the number 22 | |
15 | cout << intDeepArray[1][1]; | |
16 | ||
17 | return 0; | |
18 | } |
Comment: This is somewhat obvious, but note that the indexes of both the upper and lower arrays begin with 0, therefore the second element in the second subarray is indicated with the indexes of [1][1].
You can declare variables that cannot be updated, but hold their value under all conditions. The following declares a single constant:
const double dblPi = 3.14159265359
You can declare a list of constants (an enumeration) as follows:
enum intBookPageLength |
{ |
book1 = 356, |
book2 = 86, |
book3 = 1503, |
book4 = 118 |
}; |