Home > Blockchain >  Confusing about char* in c
Confusing about char* in c

Time:11-01

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.

  • Related