A large part of the problem is that your examples are mostly wrong.
First example:
int ar1 = {1,2,3};
int *p1 = ar1;
To be correct, this needs to be;
int ar1[] = {1, 2, 3};
int *p1 = ar1;
In this case, things are pretty simple: under most circumstances (including this one) the name of an array evaluates to the address of the beginning of that array (i.e., the type of value you'd assign to a pointer). The primary exception is when you use the array as an operand of the sizeof
operator, so sizeof(ar1)
would give the actual size of the array (3 *sizeof(int)
), not the size of a pointer.
In your second example:
int n1 = 5;
int p1 = &n1;
int &r1 = *p1; // why not: int &r1 = p1; ,*p1 is NOT an address,p1 is.This does not make any sense...
You're right -- this doesn't make any sense, and a properly functioning compiler shouldn't compile it as-is. What you apparently want is something like this:
int n1 = 5;
int *p1 = &n1; // p1 is a pointer to int, holding address of n1
int &r1 = *p1; // r1 is a reference to int, referring to what p1 points at (n1).
As far as printing things out goes, it's pretty simple: how any type gets printed out is purely a decision made by the people who wrote the library. They decided that it made the most sense that when you pass a pointer to char, that it would assume you wanted to print the string that pointed at. For other pointer types, they decided to print out the value of the pointer itself. None of this is really about the language proper though -- it's just a decision somebody made because it was what made sense to them.
If you have an array of char/pointer to char and want to print out the address instead of the characters its points at, you typically cast it to a pointer to void:
char *msg = "message";
std::cout << static_cast<void *>(msg);
As to why they chose this, I think it's pretty simple: because when people say cout << mystring
, they usually want the content of the string printed out. That's normally restricted to strings because (nearly) everybody agrees about how to print out the contents of a string, but not so much when it comes to things like the contents of an array of int, double, etc.