Constants and Literals
In programming, a constant is a value that may not be changed during the program’s execution.
There are two types of constants in C++:
- Named Constants: are constant values that have an identifier. (usually just called constants)
- Literal Constants: are constant values that are not associated with an identifier.
1. Constants:
There are three types of named constants:
- constant variables
- object-like macros with substitution text:
- enumerated constants (TBD)
1.1. Constant Variables
If we know a value wont change it's best practice to make it a constant. It also helps with compiler optimization.
A constant variable is declared by adding the keyword const next to the object's type:
const double gravity {9.8};
Const variables MUST be initialized when you define them.
Function parameters can be constant (void print(const int x)) but it's usually not used because if it's passed by value we don't really care if it changes since it's just a copy that will be destroyed at the end of the function. Also const return values are useless.
1.2. Object-like macros with substitution text
#define MY_NAME "Foo"
int main(){
std::cout << MY_NAME;}
When the preprocessor finds MY_NAME it replaces it with the constant value "Foo"
It's almost always best to prefer constant variables over object-like macros with substitution text because they can replace parts of the code that you don't expect, and also aren't affected by scope.
2. Literals:
Literals are values that are inserted directly into the code: return 5;
Just how objects have a type, the type of a literal can be deduced from the literal's value.
| Literal Value | Default Literal Type |
|---|---|
| integer (5) | int |
| boolean | bool |
| floating point (5.5) | double |
| character | char |
| string | const char[] |
If the default type of a literal is not desired, you can change the type by adding a suffix. Here are the most common:
| Data Type | Suffix |
|---|---|
| unsigned int | u |
| long | L |
| unsigned long | ul |
| long long | LL |
| unsigned long long | uLL |
| float | f |
| long double | L |
| std::string | s |
| std::string_view | sv |
The suffixes for string live in the std::string_literals directive, which is one of the rare cases where using a 'using' directive is ok. (using namespace std::string_literals)
Note that most of them (except s and sv) are not case sensitive (e.g. both u and U work for unsigned int). Since lowercase L can look like lowercase I in some fonts, most people prefer using uppercase for long types.
To use a hexadecimal literal, add suffix 0x.
From C++14 onwards, the suffix 0b also exists for binary literals. Also ' as a digit separator.