C++ requires users to specify the data type of each variable before it is used. The primary C++ built-in atomic data types are: integer (int), floating point (float), double precision floating point (double), Boolean (bool), and character (char). There is also a special type which holds a memory location called pointer. C++ also has collection or compound data types, which will be discussed in a future chapter.
It must be mutable so that it can change at any time.
Incorrect, Atomic data types are not required to be mutable.
Its memory size cannot be too big, relating to how atoms are naturally very small.
Incorrect, The data type can be any size, but you’re close. (hint: atomic data types got their name when scientists thought atoms were the smallest things in existence.)
It must be statically allocated so it cannot change in size.
Incorrect, atomic data types have nothing to do with being static or dynamic.
It cannot be broken down any smaller while still being easily operable.
Correct, the atomic data type actually got its name when scientists thought atoms were the smallest things in existence. That is why they are data types that cannot be broken down.
The standard arithmetic operations, +, -, *, and / are used with optional parentheses to force the order of operations away from normal operator precedence.
When two integers are divided in C++, the integer portion of the quotient is returned and the fractional portion is removed. i.e. When two integers are divided, integer division is used. To get the whole quotient, declaring one of the numbers as a float will convert the entire result into floating point.
When declaring numeric variables in C++, modifiers like short, long, and unsigned can optionally be used to help to ensure space is used as efficiently as possible.
Boolean data types are named after George Boole who was an English mathematician, so the word “Boolean” should be capitalized. However, the Boolean data type in C++ uses the keyword bool which is not capitalized. The possible state values for a C++ Boolean are lower case true and false.
C++ uses the standard Boolean operators, “and” is given by && , “or” is given by ||, and “not” is given by !. Note that the internally stored values representing true and false are actually 1 and 0 respectively. Hence, we see this in output as well.
Boolean data objects are also used as results for comparison operators such as equality (==) and greater than (>). In addition, relational operators and logical operators can be combined together to form complex logical questions. Table 1.9.4 shows the relational and logical operators with examples shown in the session that follows.
When a C++ variable is declared space in memory is set aside to hold this type of value. A C++ variable can optionally be initialized in the declaration by using a combination of a declaration and an assignment statement.
The declaration int theSum = 0; creates a variable called theSum and initializes it to hold the data value of 0. The right-hand side of each assignment statement is evaluated and the resulting data value is “assigned” to the variable named on the left-hand side. Here the type of the variable is integer.
In C++, the data type cannot change. This is a characteristic of C++’s static typing. A variable can hold ever only one type of data. Pitfall: C++ will often simply try to do the assignment you requested without complaining. Note what happened in the code above in the final output.
We know that variables in a computer program are used to label data with a descriptive identifier so that the data can be accessed and used by that computer program. How C++ variables are implemented is worthy of discussion.
In C++ the value of each variable is stored directly in memory without the need for either a reference or an object. This makes access faster, but it is one of the reasons we need to declare each variable because different types take differing amounts of space in memory!
But, we can also identify the memory location of the variable, which is sometimes very valuable. This address may change each time the program is run. In C++, this will always look odd because it will be the actual memory address written in a hexadecimal code which is a base 16 code like 0x7ffd93f25244.
Variables are stored in memory locations which are dependent upon the run itself. If you repeatedly run the above code you may see the location change.
When declaring a pointer in C++ that will “point” to the memory address of some data type, you will use the same rules of declaring variables and data types. The key difference is that there must be an asterisk (*) between the data type and the identifier.
However, the first declaration is preferable because it is clearer to the programmer that the variable is in fact a pointer because the asterisk is closer to the variable name.
Now that we know how to declare pointers, how do we give them the address of where the value is going to be stored? One way to do this is to have a pointer refer to another variable by using the address-of operator, which is denoted by the ampersand symbol, &. The address-of operator & does exactly what it indicates, namely it returns the address.
Image illustrating the memory representation of two variables in C++, showing how a pointer and its associated value are stored in memory. The table is divided into three rows: Variable Names, Stored Values, and Memory Address. The variable "varN" is shown with its value of 100, stored at memory address 0x60. The pointer variable "ptrN" stores the memory address of "varN" (0x60), and its stored value is displayed as 0x80.
Subsubsection1.9.4.3Accessing Values from Pointers
So, once you have a C++ pointer, how do you access the values associated with that location? You use the asterisk before the pointer variable, which goes to that address, effectively dereferencing the pointer, meaning that it will find the location of the value stored where the pointer was pointing.
Compiling and running the above code will have the program output the value in varN, what is in ptrN (the memory address of varN), and what value is located at that memory location.
Image illustrating the concept of a dangling pointer reference in C++ due to incorrect pointer assignment. The diagram shows a pointer variable "ptrN" pointing to memory address 100. However, the value at this memory address is undefined or unknown (represented by a "?" in the memory box). At the same time, the variable "varN" correctly stores the value 100 in its allocated memory. This mismatch occurs because the pointer "ptrN" was assigned the value of "varN" directly, without using the address-of operator (&). As a result, "ptrN" does not point to the actual memory location of "varN" but instead refers to an unintended location, which may lead to undefined behavior.
You don’t know what is stored in location 100 in memory, and
that location is outside of your segment (area in memory reserved for your program), so the operating system will jump in with a message about a “segmentation fault”. Although such an error message looks bad, a “seg fault” is in fact, a helpful error because unlike the elusive logical errors, the reason is fairly localized.
The null pointer in C++ points to nothing and is often denoted by the value nullptr. In older C code, you will often find the value NULL or even 0 used to represent this concept. Numerically, nullptr has the value of 0. nullptr pointer is often used in conditions and/or in logical operations.
Listing 1.9.11 demonstrates how nullptr is used. The variable ptrx initially has the address of x when it is declared. On the first iteration of the loop, it is assigned the value of nullptr (i.e. 0) thereby ending the loop: