Why does this program work?

The program in question is the following:

1
2
3
4
5
6
7
8
9
10
11
    string text[] = {"one", "two", "three"};

    string * pText = text;

    cout << ptext << endl; // address of text[0]
    cout << *pText << endl; // value of text[0]

    for(int i = 0; i<3; i++)
        cout << pText[i] << " " << flush;

    cin.get();


It is my understanding that when you set a pointer equal to an array (using assignment statement), the pointer then contains the address of the 0th element of that array, and thus, dereferencing that pointer will give you the value of the 0th element of the array. This is demonstrated clearly in lines 5 and 6.

Its for this reason that I can't understand why the for loop works. What is up with pText[i]?

If pText contains the address of the 0th element, how does this iteration work?
Last edited on
Try i[pText]. You will be very surprised.

Standard says that expression x[y] is threated as *(x+y). So nothing surprising here.
In your expression, either x or y must be a pointer, correct?

So you are saying that pText[i] is treated is *(pText + i)? In other words, first the pointer is incremented by i, and then it is dereferenced.

If thats true, I can understand why i[pText] also works, as that would be equivalent to *(i + pText) which is the same as the first expression.

Im not understanding why this code prints what it does.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <string>

using namespace std;

int main()
{
    char str[] = "This is a test";

    char * pStart; // declaring pointer to a chart

    pStart = str; // store value of str[0] inside pointer

    cout << pStart << endl; // why doesn't this print out an address value?
    cout << *pStart << endl; // this prints out letter "T" as expected 


What I dont understand is why line 14 is printing out the entire phrase "This is a test". Doesn't setting a pointer equal to an array store the address of the 0th element in that pointer. This is a char array so I was expecting line 14 to print out an address.

Anyone care to explain this please?
There is an overload for char* which prints a c-string.
When you assign a 1d array to a pointer of the same type then the array "decays" to a pointer to the address of the first element.

As MiiNiPaa has already said, there is an overload of operator<< for (const) char*, which is provided to handle C null-terminated strings (so if your char array is not null terminate you will have problems!)

Andy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>

using namespace std;

int main()
{
    char str[32] = "This is a test"; // now with size (needed for array pointer)

    char * pStart; // declaring pointer to a char

    char (*pArray)[32]; // declaring pointer to array

    pStart = str; // store address (not value) of str[0] inside pointer
    pArray = &str; // store address of array (rather than first element)

    cout << static_cast<void*>(pStart) << endl; // print address of first array element
    cout << pStart << endl; // print null terminated string due to << overload
    cout << *pStart << endl; // this prints out letter 'T' as expected 

    cout << pArray << endl; // this prints out address of array
    cout << *pArray << endl; // this prints out string again
    cout << **pArray << endl; // this prints out 'T' again

    return 0;
}

Last edited on
I never really understood this....

I dont understand overloading yet so is there a simpler explanation for this?
Last edited on
outputting char* gives you string. This is a special case because char* is commongly used to store strings and that is what most people expect.
Last edited on
cout knows what a c-string is and shows it accordingly.
Assumes rather than knows. "C-string" is a convention that a char* points to an array of characters, where there is null value after the last letter of the text. There can be other legit uses for a char* pointer, where there is neither no array or no null at end, but functions that expect C-string should never be called with such pointers.


Function overloading.

Each function must have an unique signature. The calling code has signature of the function embedded and exactly one function implementation in the object files may have that signature. In the last phase of compilation a linker tool connects function calls to the implementations of those functions, producing the executable program.

In C language the name alone was the signature. One did need a different name for each mathematical operation that you could do for more than one numerical type. For example logarithm: logf for floats, log for doubles and logl for long doubles. Inventing names that do not collide, yet mean something, was not fun.

The C++ language does include the types of the parameters to signature of the function. Therefore, log(float), log(double) and log(long double) are three unique functions even though they all have name "log". The reuse of same name is "overloading".

In std::cout << foo; the << is an operator and operator is a function. There are many functions that all have "name" << and the left operand is "ostream" (the type of cout". The functions do differ by the type of the right operand. If the "foo" has type const char * (char* can implicitly convert to const char*), then the signature matches the function that expects a C-string and prints readable text.

Some (but not all) of those << functions are listed here: http://www.cplusplus.com/reference/ostream/ostream/operator%3C%3C/
Last edited on
Topic archived. No new replies allowed.