Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pointer to char vs pointer to arrays

Tags:

c++

char

pointers

I thought I had a decent knowledge of pointers until I decided to review some so called trivial examples.

One thing I know is that when declaring an array say:

int arr[2] {3, 5};

arr will hold the value of the first element in the array so attempting to print that (cout << arr) gives obviously the address of arr[0]. Even thought my program uses pointers it's still similar.

My question is why can I print h and have bonjour as output, but I can't do the same with p?

It also looks like when I increment h++ and print it again I get onjour. How are pointers different with char?

#include <iostream>
#include <string>

int main()
{
    char* h = "bonjour";
    int k[4]{3, 4, 5, 6};
    int * p = k;

    std::cout << "Hello, "<< h << "!\n";
}
like image 866
Bobby Avatar asked Dec 14 '22 11:12

Bobby


2 Answers

When you stream h, you are using this overload:

template< class Traits >
basic_ostream<char,Traits>& operator<<( basic_ostream<char,Traits>& os,  
                                        const char* s );

But when you stream p, you are using this one:

basic_ostream& operator<<( const void* value );

The former will print every byte until it gets to a \0, the latter will simply print the address. That is - there's simply a special case for const char* that you're taking advantage of.

like image 99
Barry Avatar answered Dec 26 '22 00:12

Barry


why can i print h and have bonjour as output and i can't do the same with p? it also looks like when i increment h++ and print it again i get onjour. how are pointers different with char?

The standard library provides two overloads of the operator<< function for dealing with pointers.

A member function overload:

basic_ostream& operator<<( const void* value );

and a non-member function overload:

template< class Traits >
basic_ostream<char,Traits>& operator<<( basic_ostream<char,Traits>& os,  
                                        const char* s );

The first one is invoked when cout << ptr is used for all pointers that are not of type char* or char const*. The second is used for all pointers that are of tpe char* or char const*. The second one outputs everything up to the terminating null characters while the first one outputs just the pointer value.

That explains the output.

It's instructive to understand why the standard library treats them differently.

The language and the standard libraries make exceptions to the null terminated strings that are represented by char* and char const*. When dealing with strings, the null character ('\0') acts as a sentinel value that marks the end of the string. There is no such value for other types. Hence, an int* cannot be treated the same was a char*.

like image 40
R Sahu Avatar answered Dec 26 '22 00:12

R Sahu