Understanding strings as pointers in C++

Viewed 108

I have troubles understanding strings as pointers. Apparently a string is understood as a pointer which points to the first address of the string. So using the "&"-operator I should receive the address of the first character of the string. Here's a small example:

#include "stdafx.h"
#include <iostream>
using namespace std;

int main(){
    char text[101]; 
    int length;
    cout << "Enter a word: ";
    cin >> text;
    length = strlen(text);
    for (int i = 0; i <= length; i++) {
        cout << " " << &text[i];
    }
    return 0;
}

When entering a word such as "Hello", the output is: "Hello ello llo lo o". Instead I expected to receive the address of each character of "Hello". When I use the cast long(&text[i]) it works out fine. But I don't understand why. Without the cast, apparently the "&"-operator gives the starting address of the string to be printed. Using a cast it gives the address of every character separately. Maybe sb. can explain this to me - I'd be really grateful!

3 Answers

&text[i] is equivalent to text + i and that shifts the pointer along the char[] array by i places using pointer arithmetic. The effect is to start the cout on the (i)th character, with the overload of << to a const char* called. That outputs all characters from the starting point up to the NUL-terminator.

text[i] however is a char type, and the overload of << to a char is called. That outputs a single character.

In C++, if you want a string, then use std::string instead. You can still write cin >> text; if text is a std::string type! Your code is also then not vulnerable to overrunning your char buffer.

To print the address of an array element, you could do:

cout << " " << (void*)&text[i];

This:

cout << " " << &text[i];

is equivalent to this:

cout << " " << text + i;

which means that you ask to print the string, starting from index i.

If you have a character array storing a string as for example

char text[] = "Hello";

then the array is initialized like

char text[] = { 'H', 'e', 'l', 'l', 'o', '\0' };

In this statement

std::cout << text;

there is used operator << overloaded for the type const char * and the array text is converted implicitly to pointer to its first element.

You could write instead

std::cout << &text[0];

because in the both statements the expressions text and &text[0] have type char *.

The operator overloaded for the type const char * outputs characters starting from the address at the pointer until a zero character is encountered.

So if instead of the statement

std::cout << &text[0];

you'll write

std::cout << &text[1];

then the only thing that is changed is the starting address of the string and nothing more. That is in fact you are outputting string that is represented like

{ 'e', 'l', 'l', 'o', '\0' }

If to write

std::cout << &text[2];

that is if the pointer in the right side of the expression is moved one position right then it means that you'll deal with the string

{ 'l', 'l', 'o', '\0' }

and so on.

That is the operator << overloaded like

template<class traits>
basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&,
const char*);

just outputs entities pointed to by the second parameter as strings.

If you want to output the value of the pointer itself instead of the string pointed to by the pointer you should use another overloaded operator << declared like

basic_ostream<charT, traits>& operator<<(const void* p);

Tp invoke it you should write for example

std::cout << ( void * )text;

or

std::cout << ( void * )&text[i];

where i is some index.

Instead of the C casting you can use C++ casting like

std::cout << static_cast<void *>( &text[i] );
Related