A pointer of type char* is so different from that of type int*;

A pointer of type char* is so different from that of type int*.

Why a pointer of type char* is the content, while a pointer of type int* is a memory address.

The former is so weird! and that's not explained in the tutorial.
Anyone knows why?

Thanks!

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
26
27
28
29
#include <iostream>
using namespace std;

int main() {


	const char* c = "sample text";
	cout << c << endl;
	
	char cc[] = { "sample text" };
	char* pp = cc; 
//I see an array indentifier is actually a pointer, too.
//so it is "char*pp=cc" here not "char*pp=&cc".

	cout << pp << endl;
//why pp represents the content?

	cout << *(pp) << '\n';
	*pp = 'A';
	cout << *(pp) << '\n';
	cout << pp << endl;


	int b = 8;
	int* pint = &b;
	cout << pint << ',' << *pint << endl;
//it' s OK that pint is the address and *pint is the value contained.
	return 0;
}
Why a pointer of type char* is the content, while a pointer of type int* is a memory address.


They are both entities that hold memory addresses.

You may be looking at how the stream inserter << is defined to deal (differently) with the different types.

http://www.cplusplus.com/reference/ostream/ostream/operator-free/
vs
http://www.cplusplus.com/reference/ostream/ostream/operator%3C%3C/
Last edited on
The output stream gives special treatment to pointers to character types.
It inserts successive characters (till a null character is encountered) from the character array whose first element is pointed to by the pointer.

There is no such special treatment for other pointer types; it just inserts the value of the pointer.
@lastchance @JLBorges
You guys rock!
Thanks so much.
You can overload the operator<< for a type int* (or any other type that hasn't already) so that it uses the value and not the pointer. So:

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

std::ostream& operator<<(std::ostream& os, const int* pi)
{
	return os << *pi;
}

int main()
{
	const int b {8};
	const int* pint {&b};

	std::cout << pint << ", " << *pint << '\n';
	return 0;
}


displays:


8, 8

Not that I would ever write this operator in real code, but it is kind of funny. A null-terminated int array!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>

std::ostream& operator<<(std::ostream& os, const int* pInt)
{
    while (*pInt != 0)
    {
        os << *pInt;
        if (*++pInt != 0)
            os << ' ';
    }
    return os;
}

int main()
{
	const int arr[] {3, 1, 4, 1, 5, 0};
	std::cout << arr << "\n";
	return 0;
}
Last edited on
If you want to display the address of a char*, then you can cast to intptr_t:

1
2
3
4
5
6
7
8
9
include <iostream>
using namespace std;

int main() {
	const char* const c {"sample text"};
	cout << hex << reinterpret_cast<intptr_t>(c) << '\n';

	return 0;
}

Last edited on
To display the address as a pointer, cast it to const void*

To display its integer value, cast it to the unsigned integer type std::uintptr_t
(this is optional, but almost all implementations do define std::uintptr_t)

For example:

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
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <cstddef>

std::ostream& dump_cstr( const char* cstr )
{
    if( cstr )
    {
        using vptr = const void* ;
        using int_val = std::uintptr_t ;
        return std::cout << "address: " << vptr(cstr) << " (value: " << int_val(cstr)
                  << ") contents: \"" << cstr << "\"\n" ;
    }

    else return std::cout << "nullptr\n" ;
}

#define DUMP_CSTR(cstr) ( std::cout << #cstr " " && dump_cstr(cstr) )

int main()
{
    // note: the lieral arrays lit1 and lit2 may or may not be at the same address
    auto& lit1 = "abcdefgh" ; DUMP_CSTR(lit1) ;
    auto& lit2 = "abcdefgh" ; DUMP_CSTR(lit2) ;

    // pointers ptr1 and ptr2 point to the first elements of the literal arrays
    const char* ptr1 = lit1 ; DUMP_CSTR(ptr1) ;
    const char* ptr2 = lit2 ; DUMP_CSTR(ptr2) ;

    // user-defined arrays arr1 and arr2 must be at different addresses
    // const; ergo one of them may have the same address as the literal array
    const char arr1[] = "abcdefgh" ; DUMP_CSTR(arr1) ;
    const char arr2[] = "abcdefgh" ; DUMP_CSTR(arr2) ;

    // user-defined array arr3 must be at a different address
    // non-const, ergo: it can't have the same address as the literal array
    char arr3[] = "abcdefgh" ; DUMP_CSTR(arr3) ;
}

http://coliru.stacked-crooked.com/a/7c11ac61ebb25a76
Last edited on
Topic archived. No new replies allowed.