Introduction

In the previous tutorial, we talked about strings.  Strings a way to store text in a C++ program.

 

In this tutorial, we are going to talk about constants.  The obvious application of constants is when you need to store a number like pi.  The value of pi never changes, so storing it to a variable that can change is a bit dangerous.  Someone could come along and change the value of pi to 3 and then your program might not work as well as you would like after that.  Constants can also let the caller of a function know that you won’t change the data that is passed in as well as not changing any variables stored on a class.  This is extremely powerful and should be used as frequently as possible!

Constant Value

So, the first example is storing pi:

 

const double PI = 3.14159;

 

Now if someone tries to do something like this:

 

PI = 5; // Compiler Error

 

Then an error will be generated and they won’t be able to compile.  This is great because it prevents someone from changing a value that shouldn’t change.  (The intent is usually not malicious, it is just an honest mistake and this helps catch it before it becomes a problem.)

Constant Arrays

Arrays can also be declared as a constant:

 

const double data[] = { 1.0, 2.0, 3.0 };

 

Again, the values of the array cannot be changed:

 

data[2] = 5; // Compiler Error

Constant Pointers

Things get a little more exciting with pointers.  Remember that pointers are just a reference to a location in memory. Therefore there are two things that we would want to keep track of whether or not it is constant: the pointer value (a memory address), and the value at the memory address that the pointer is referencing.

 

The following syntax means that the value that the pointer is pointing to is constant:

 

const double* ptr = Π

 

This means that you can’t change the value of PI through the use of the pointer:

 

*ptr = 1.0; // Compiler Error

 

This is really good because it means that someone can’t use a pointer as a secret way to change the value of PI.

 

The value of ptr can still change, even though the value that it points to cannot change:

 

const double E  = 2.71828;

ptr = &E;

 

Now *ptr is equal to e, rather than pi.  This is because we can still change the address that ptr points to.

 

In order to make sure that ptr never changes, we need to add a second const:

 

const double* const ptr = Π

 

Now when we try to set ptr to e, we get an error:

 

ptr = &E; // Compiler Error

 

So, as a quick recap, the const before the double*means that the value that the pointer points to is constant and a const after the double* means that the value of the pointer (memory address) is constant.

Enforcing Const

The compiler does a really good job of ensuring that once a value is declared as const, it can’t accidentally be changed.  So, if you have declared a const double, you can’t set it to a non-const pointer:

 

double* ptr = Π // Compiler Error

 

This is good because it makes it very clear that PI cannot be changed.  There is no guessing as to whether the value that the pointer is pointing to is constant or not.

 

Another interesting nuance is that you can create a pointer to a constant value, when the value isn’t constant:

 

double v = 1.0;

const double* p = &v;

 

This means that you can change the value of v through the v variable but not through the pointer p:

 

v = 2.0;

*p = 3.0; // Compiler Error

 

At first this might not seem too useful, but it comes in handy when writing functions because it means that you can pass a non-constant value into a function that takes a constant value.

Const Functions

Parameters to a function can be declared as constant as well:

 

int fun(const int& value)

{

return 5 * value;

}

 

This tells the caller that the value that is passed in will not be changed by the function.  This a great piece of information to let the caller know.

 

Additionally, the value passed in doesn’t have to be const:

 

int three = 3;

int output = fun(three);

 

The const in the function arguments just says that the function will not modify the value being passed in.

 

With classes, you can also add the const keyword after the function:

 

class MyClass

{

private:

int _value;


 

public:

void NoChanges() const

{

}

};

 

This means that the function will not change any variables in the class.  So, doing something like this would generate an error:

 

void NoChanges() const

{

_value = 1.0; // Compiler Error

}

Summary

In this tutorial, we learned about constants which are a way to signal that the value of something will not change.  This is incredibly powerful because it makes the intentions of your code very clear.

 

In the next tutorial, we will discuss hash tables.  The best way to think about hash tables is that they are like arrays, except that the index doesn’t have to be a small, positive integer; it can be anything. This makes them an extremely powerful and versatile container.

 

If you have any questions or comments about what was covered here, post them to the comments.  I watch them closely and will respond and try to help you out.

Tutorial Index

01 - Hello Raspberry Pi

02 - Reading User Input

03 - If Statement

04 - For Loops

05 - While Loops

06 - Functions

07 - Data Types

08 - Arrays

09 - Structures

10 - Classes

11 - Pointers

12 - Dynamic Arrays

13 - Linked List

14 - Linked List Operations

15 - STL List/Vector

16 - Templates

17 - Inheritance

18 - File I/O

19 - Strings

20 - Constants

21 - Hash Tables