Character arrays are designated by
1 |
type variableName[count]; |
Hence, we make an array of characters called “myName” with 10 elements:
1 2 3 |
int main(int argc, const char * argv[]) { //character array char myName[10] = "Ricky"; |
Any left over elements that are not taken up by the initialization will have ” or NULL filled in.
Using pointer to display string
myName is actually a const pointer to the first element of the array. When we use cout to display char arrays, it displays all the data from the pointer up until the terminating NULL. Since our pointer is currently at the beginning of the array (R), cout will display the full name Ricky.
1 |
std::cout << "my name is: " << myName << std::endl; |
Adding a byte (1) to the pointer will display one character further down the array. Note that a char is equal a byte.
Adding n bytes will display characters further down the array.
1 2 3 4 |
std::cout << "my name is: " << myName + 1 << std::endl; std::cout << "my name is: " << myName + 2 << std::endl; std::cout << "my name is: " << myName + 3 << std::endl; std::cout << "my name is: " << myName + 4 << std::endl; |
Result:
my name is: Ricky
my name is: icky
my name is: cky
my name is: ky
my name is: y
Using address of element to display string
myName[0] gets you the first element ‘R’.
If you use &myName[0], it gets you the ADDRESS of the first element. Hence, the compiler will display all data from that address up to a NULL. Hence &myName[0] will display ‘Ricky’ also.
1 2 3 4 5 |
std::cout << "&myName[0] displays: " << &myName[0] << ", myName[0] is: " << myName[0] << std::endl; std::cout << "&myName[1] displays: " << &myName[1] << ", myName[1] is: " << myName[1] << std::endl; std::cout << "&myName[2] displays: " << &myName[2] << ", myName[2] is: " << myName[2] << std::endl; std::cout << "&myName[3] displays: " << &myName[3] << ", myName[3] is: " << myName[3] << std::endl; std::cout << "&myName[4] displays: " << &myName[4] << ", myName[4] is: " << myName[4] << std::endl; |
Result:
&myName[0] displays: Ricky, myName[0] is: R
&myName[1] displays: icky, myName[1] is: i
&myName[2] displays: cky, myName[2] is: c
&myName[3] displays: ky, myName[3] is: k
&myName[4] displays: y, myName[4] is: y
What if the element is NULL?
A better way to display an element is to check for NULL
1 2 3 4 |
if(!myName[4]) std::cout << "myName[4] is null" << std::endl; else std::cout << "&myName[4] displays:" << &myName[4] << ", myName[4] is: " << myName[4] << std::endl; |
In our case index 5 and on would give us a NULL.
Getting the address
Use void pointer to get the memory location.
std::cout << (void*)&myName[0] << std::endl;
std::cout << (void*)&myName[1] << std::endl;
std::cout << (void*)&myName[2] << std::endl;
std::cout << (void*)&myName[3] << std::endl;
std::cout << (void*)&myName[4] << std::endl;
std::cout << (void*)&myName[5] << std::endl;
Result:
0x7fff5fbff86e
0x7fff5fbff86f
0x7fff5fbff870
0x7fff5fbff871
0x7fff5fbff872
0x7fff5fbff873
Remember that hex is 0 - 9, a - f and each increment is a byte.
Hence
R is at address 0x7fff5fbff86e
i is at address 0x7fff5fbff86f
c is at address 0x7fff5fbff860
k is at address 0x7fff5fbff861
…
where each char is a byte. Also notice that the string terminating NULL also has a address at 0x7fff5fbff873.