A common example of using raw arrays and pointers is the
implementation of a custom string class.
I avoided using strings in this course on purpose because I think that
they would just introduce additional complexity. If you need to work with
strings in C++, the standard library will provide you with a lot of
useful classes for string management.
However,
there are still some things that I think you should know
about legacy implementation of strings,
especially when working with string literals.
In essence, the string is just an array of characters, even in C++. C
language doesn't have a special data type for managing strings, so the
programmers had to rely on using arrays of characters. And this legacy is
still hidden under the layers of abstraction in C++. Char arrays are not
used that often in C++, and when they are, they're usually not used to
represent strings.
You will see an example of this in the next module.
This is how we can initialize an array of characters.
Each character literal needs to be wrapped in a single quote, like this.
Character encoding is a complex topic, but the most basic code that we
assign to characters is ASCII. ASCII table will associate a special
number to every kind of basic character.
So in essence, characters are just integers.
But when you tell the compiler that your value is char,
it will print out this character instead of a number.
I can replace this S character with the number associated with the
capital letter S from the ASCII table, and this code would still work.
The character literals are just there to make it easier for us
programmers. Technically, you wouldn't call this array a string until you
add the null character at the end of it.
The null character is this special type of character which looks like
this, \0, but you can also replace it with a number 0 since this is
the ASCII code for this character. This is required because C had
special string library which expected all strings to have this null
character at the end.
All of these special utility functions would usually have to look
through different kinds of strings, and it was easier to just stop when
you find a null character than to manage the string logic in a more
complicated way. You can still see this legacy in C++ if you work
closely with string literals. String literals need to be wrapped inside
of these double quotes.
So when the compiler sees this, it will create a string in a constant
read‑only part of memory and store these characters inside of it.
So this literal actually creates a const array of
characters in a constant part of memory.
You can see that if I hover over it,
my editor tells me that this is an array of seven characters. But
doesn't this word have only six characters? Well,
actually, since this is a string,
C++ will automatically add the null character at the end
of it, so that is why we always need space for one more
character to create a literal.
You can use literals to initialize an array of characters on the stack.
I created this simple program with two arrays of characters.
The first one is initialized with a character list, and the
second one is initialized with a string literal.
Then I will change the second character from each array from t two
p and print both of the arrays to the terminal.
When I compile this program,
the first thing that you will notice is that these arrays
are actually printed on the screen.
Usually, when we try to print an array identifier,
we would get back memory address.
But since cout is aware that this is an array of characters,
it assumes that we want to print it out in a form of a string.
Since this string literal already has an allocated space in memory,
I would like to use it without creating a new array of characters.
I am mentioning this because in the next module, we will use a
pointer to pass a string literal to a function.
Since this literal is in a constant part of memory,
we need to add this const keyword here before the pointer declaration.
However, this will now make the string unmodifiable.
You can only read these values, which makes sense since we are pointing to
read‑only memory. But how did we manage to change the second character
when we assigned this literal to an array? This is because arrays
initialized with a string literal actually occupy their own space on the
stack and then copy all of the characters from this literal into their own
respective elements.
So when we decided to change one of the characters,
we are actually changing a cloned array on the stack,
not the string literal itself.
And this is all that I think you should know about the old implementation and
string literals because C++ has a special string class for managing strings.
Actually, it has more of them, but we need to include the string library to get
the access. The standard string class is a template specialization of the more
primitive basic string class,
which will basically manage an array of characters behind the scenes.
String class implements a lot of optimization on its own.
The small string optimization technique will usually store short strings
in a small buffer on the stack, while longer strings will be allocated on
the heap, so this is another reason why I didn't want to introduce this
underlying complexity when talking about heap and pointers. This course
is not about strings.
I just had to mention this connection to the array of
characters. But if you want to use strings in C++, always
use one of the standard classes.