test code:
#include <iostream>
using namespace std;
int main()
{
const char* b="str";
cout << b << endl;
cout << *b << endl;
cout << &b << endl;
cout << *(&b) << endl;
return 0;
}
result:
str
s
0x7ffdf39c27f0
str
I run my code on the web runoob online compiler
Why I get these results? I looked some questions about char*, but not enough for me to understand. Can someone explain that to me? Pictures are best.
I want to know more about it with books or blogs recommended.
By the way, usingchar b[]
instead of const char*
, I get the same results.
Thanks a lot for all of you.
I just want to know why a char pointer's value is not an address.
I think adress is like 0x7ffdf39c27f0. an memory adress.
But const char* b = "str"
. b is just str
.
And I found that *b
is the same as *("str")
.
So I want to know what happened in the memory? why a char pointer's value is not an address?
CodePudding user response:
To understand what the code outputs, you need to understand that C output streams (objects with a type such as std::ostream
) and therefore objects (such as std::cout
) have a number of overloads of operator<<()
. The overload that is called depends on the type of argument provided.
I'll explain your second example, but the explanation for the first example is almost identical.
const char* b="st\0r"; cout << b << endl; cout << *b << endl; cout << &b << endl; cout << *(&b) << endl;
cout << b
expands to cout.operator<<(b)
where b
has type const char *
. That overload of the operator function ASSUMES the argument points to (the first character of) a nul terminated string, which is represented in memory as an array of char
that ends with a char
with value '\0'
(zero). The operator function outputs each character it finds until it reaches a '\0'
character. The first '\0'
found is the one YOU explicitly inserted after the 't'
, so the output st
is produced. The fact that your string has a second '\0'
after the 'r'
is irrelevant, since the operator function stops at the first one it finds.
cout << *b
expands to a call of a different overload of operator<<()
that accepts a single char
, and outputs that char
. *b
is the value of the first character in the string represented by b
. So the output s
is produced.
In cout << &b
, &b
has type const char **
or (equivalently) char const **
. There is no overload of an output stream's operator<<()
that accepts a const char **
, but there is an overload that accepts a const void *
. Since any pointer (other than pointer-to-member or pointers to functions) can be implicitly converted to void *
, that conversion is performed (by the compiler), so the overload matches, and is called. That particular overload of the operator<<()
prints the address in memory.
The implicit conversion in the third case doesn't happen in the first two cases, since a call that doesn't require an implicit conversion is a better match than a call which does.
In the last statement *(&b)
is equivalent to b
. This is the case because &
is the address-of operator in this code, and the *
is the dereference operator (which is the inverse of the address-of operator). So the last statement produces the same output as cout << b
.
CodePudding user response:
cout << b << endl;
You are printing the string b
cout << *b << endl;
You are printing the pointer that points to the first character of b
., so is the same as:
cout << b[0] << endl;
cout << &b << endl;
&b
is the memory address of b
, which means the address memory to store b
in the computer.
cout << &b << endl;
So, you're printing the memory address of b
here. The computer store b
in the memory address 0x7ffdf39c27f0
, so that's what you get.
cout << *(&b) << endl;
You are printing a pointer that points to the memory of b
, so you print the value at the memory address of variable b
which is the same as
cout << b << endl;
edit: A pointer contains an address that (usually, it could point at a function, for example) represents the location of an object, and to print a pointer (usually) prints the value of that memory address. Because char *
is intimately linked with null-terminated strings, there is a special overload for pointers to characters to print the pointed-at string.
A pointer variable is still a variable and will have an address of its own, so &b
results in a pointer to a pointer, a char **
in this case and because it is no longer a char *
, cout << &b;
prints the address of b
, not the address pointed at by b
or the string pointed at by b
.