# include <iostream>
using namespace std;
int main(void)
{
char *name = "Stack overflow";
cout << *&name << endl;
cout << &*name << endl; // I don't understand why this works
return 0;
}
I understand how the first "cout" statement works but unable to understand why and how the second one works.
& and * are opposite operations. The first one takes the address of the array (adding one level of indirection) and then dereferences it (removing one level of indirection). The second dereferences the pointer (removing one level of indirection) and then takes the address of the result (adding one). Either way, you get back to the same value.
Just like 4 / 2 * 2 is the same as 4 * 2 / 2, or just like taking a step back and then forward leaves you at the same place as taking a step forward and then backward.
To understand how the second statement works substitute it
cout << &*name << endl;
for
cout << &name[0] << endl;
because *name and name[0] are equivalent and return reference to (lvalue) the first character of the string literal pointed by name.
The last statement is equivalent to
cout << name << endl;
Related
I'm rather new to C++ and while working with a pointer to a char array (C style string) I was confused by its behavior with the ostream object.
const char* items {"sox"};
cout << items << endl;
cout << items[0] << endl;
cout << *items << endl;
cout << &items << endl;
cout << &items[1] << endl;
Running this leads to:
sox
s
s
0x7fff2e832870
ox
In contrary to pointer of other data types, printing the variable doesn't output the address, but the string as a whole. By what I understand, this is due to the << operator being overloaded for char arrays to treat them as strings.
What I don't understand is, that cout << &items[1] prints the string from index 1 onward (ox), instead of the address of the char at index 1. Is this also due to << operator being overloaded or what is the reason for this behavior?
The type of &items[1] is const char *. Therefore the const char * overload of operator << is used, which prints the string from index 1 onwards.
OTOH, the type of &items is const char **, for which no specific overload exists, so the address of items is printed (via the const void * overload).
Back in the olden days, when C ran the world, there was no std::string, and programmers had to make do with arrays of char to manage text. When C++ brought enlightenment (and std::string), old habits persevered, and arrays of char are still used to manage text. Because of this heritage, you'll find many places where arrays of char act differently from arrays of any other type.
So,
const int integers[] = { 1, 2, 3, 4 };
std::cout << integers << '\n';
prints the address of the first element in the array.
But,
const char text[] = { 'a', 'b', 'c', '\0' };
std::cout << text << '\n';
prints the text in the array text, up to the final 0: abc
Similarly, if you try to print addresses inside the array, you get different behavior:
std::cout << &integers[1] << '\n';
prints the address of the second element in th array, but
std::cout << &text[1] << '\n';
prints the text starting at the second character of the array: bc
And, as you suspected, that's because operator<< has an overload that takes const char* and copies text beginning at the location pointed to by the pointer, and continuing up to the first 0 that it sees. That's how C strings work, and that behavior carries over into C++.
items[1] is the second character of the array and its address, i.e. &items[1], is a pointer to the second character (with index 1) as well. So, with the same rule that you have mentioned for operator <<, the second character of the string till the end is printed.
Here is sth I find but I can't understand one address ,when I use "cout<
#include<iostream>
using namespace std;
int main()
{
char a[2]={'a','b'};
char b[3]="ab";
cout<<&a<<endl;
cout<<&b<<endl;
cout<<sizeof(a)<<endl<<cout<<sizeof(b);//the result of this I am puzzled
return 0;
}
The result is :
0x28ff2e
0x28ff10
2
0x4453c43
0x28ff2e is an address of a
0x28ff10 is an address of b
2 is the size of a
0x4453c43 is an address of the result of converting cout to void* followed by sizeof(b) (See Does std::cout have a return value?)
Maybe you did want this instead:
cout << sizeof(a) << endl;
cout << sizeof(b) << endl;
Or this:
cout << sizeof(a) << endl << sizeof(b) << endl;
When you do this line:
cout<<sizeof(a)<<endl<<cout<<sizeof(b)
You shouldn't use cout second time. When you do, you printf address of it:
0x4453c4
or rather Does std::cout have a return value?
and then you print size of b, is the 3 on the end of this 0x4453c43
Rather you should just use this:
cout<< sizeof(a) << endl << sizeof(b) << endl;
You're printing the address of cout ;)
cout<<sizeof(a)<<endl<<cout<<sizeof(b)
The problem is that you're streaming the cout object to itself, so it prints whatever the cout can be converted to that operator<< if overloaded for - which happens to be void* (before C++11, which you evidently aren't using).
Either break cout<<sizeof(a)<<endl<<cout<<sizeof(b); into two lines with a semicolon after endl, or remove the second cout. You should put in a final endl or '\n' too... on some systems you won't be able to read the output otherwise (as the shell prompt will return to the left-of-screen then overwrite it).
You probably don't want this bit:
cout<<sizeof(a)<<endl<<cout<<sizeof(b);
^^^^^^
Older implementations of streams had an operator void*(), to allow constructs like if (cout) without allowing implicit conversions to bool and other numeric types; you are seeing the result of that, concatenated with the final value. A C++11 implementation should have an explicit operator bool() insead, and so should cause a compile error here.
Removing that gives something like:
0x28ff2e
0x28ff10
2
3
as you would expect.
"the result of this I am puzzled"
cout< < sizeof(a)< <endl << cout <<sizeof(b);
^^^ The "puzzling" address comes from this
Remove it and see the result
cout output to standard output is implementation defined
You have a stray cout there. Note that you're effectively printing cout into cout here:
cout << ... << cout << sizeof(b);
cout needs some form of conversion to boolean. Before C++11, this was provided by a conversion to void*; this happens in your case, as the only way cout can be converted to something streamable. Note that there's an extra 3 after 6 hexa digits of the pointer - that's the 3 produced by sizeof(b)
This is going to be a long-winded post, so I apologize in advance.. but trying to ask multiple questions with context:
So, I've been trying to learn C++, and I've been picking everything up fairly easily, but I make a habit of trying to do things alongside the tutorials in "slightly different ways", in order to ensure that I understand the functionality of the thing I'm learning.
I seem to have hit a mental roadblock regarding constants and their involvements with pointers.
In the previous section, I think I got a pretty solid grip on references, dereferences (and the difference between * when used for dereferences and pointers), and then wrote this code:
int a[5];
int * p;
p = a;
cout << "Select the value for the first item at address(" << &a[0] << ")" << nl;
cin >> *p;
p++;
cout << "Select the value for the second item at address(" << &a[1] << ")" << nl;
cin >> *p;
p++;
cout << "Select the value for the third item at address(" << &a[2] << ")" << nl;
cin >> *p;
p++;
cout << "Select the value for the fourth item at address(" << &a[3] << ")" << nl;
cin >> *p;
p++;
cout << "Select the value for the fifth item at address(" << &a[4] << ")" << nl;
cin >> *p;
for (int n=0;n<5;n++)
cout << a[n] << "(" << &a[n] << ")" << nl;
Now, I realize that this isn't necessarily the most "optimized" solution, ever.. but it worked, I was able to "write" into the array I had store on the memory, and display the changes. It was neat, and like I said.. I think I got a pretty good understanding of how these things worked.
..and then, I hit the next section, which used the example:
const char * terry = "hello";
to teach me, and I quote: "As in the case of arrays, the compiler allows the special case that we want to initialize the content at which the pointer points with constants at the same moment the pointer is declared" (this being on the cplusplus.com tutorial).
Anyway, to get to the point: in order to try and familiarize myself with it and the previous section, I tried writing:
const char * p = "Hello.";
for (int n=0;n<5;n++)
cout << p[n] << "(" << &p[n] << ")" << nl;
cout << nl;
..and this does not work. I essentially tried replicating my previous code (although without the writing aspect) in an attempt to be able to read the RAM-location of each character in this constant array, and I experimented with every possible combination of pointers, references, dereferences, etc.. but I just get a print out of the whole "Hello." array with &p.
How in the hell does one get the reference of a constant array? I think I understand the basic premise that I'm creating an array and immediately allocating it to memory, and then assigning a pointer (p) to the first block ("H")'s location.. but I can't seem to print the blocks out. I was able to get the location of the first block to print at one point (can't remember what code I used to do this) and tied it into the for loop, but even then.. it just ALWAYS printed the location of the first block, even when assigned to follow the [n] count.
I have no idea what I'm missing, here, or if I'm just trying to reach "over my head", but maybe I just don't understand the usage/point of creating an array without being able to location the memory assignment of each item within it..
This brings me to my next issue, though. How does one get the memory location of a char variable, whether constant or not? I have been having issues with this code, as well:
char const a = 100;
int * b = &a;
cout << a << nl << *b << nl;
cout << nl;
Obviously, this doesn't work.. because I can't assign b to the location of a, since they're different variables.. and obviously making a char pointer is silly, since it's just going to print messed up/null characters instead of the location (I checked this, obviously.. not just assuming).
I hope I'm just missing an option to use which may just be "more advanced" than where I'm currently at.. but if I'm not, I don't quite see the point in being able to access the block location of any type of variable/constant, if you can't access ALL of them due to restrictions of the type being used.
This problem is sorta what limits the third quoted code, too: the fact that I can't just assign a variable to hold the &p value, since it itself would have to be a char to be compatible.. which is pointless since char can't hold the eight-digit reference.
In
const char * p = "Hello.";
[...] cout << &p[n] [...]
&p[n] is a pointer to char, and cout::operator<< has an overload that takes a pointer to a char and prints a null-terminated string, that's probably why you're confused.
So I have the following code:
cout << _userLoginName << endl;
cout << *_userLoginName << endl;
cout << (_userLoginName+1) << endl;
cout << *(_userLoginName+1) << endl;
the variable char * _userLoginName has been set equal to "smith". My question is simple: Why in the last lines of code do I get the following output?
smith // as from cout << _userLoginName << endl;
s // as from cout << *_userLoginName << endl;
mith // cout << (_userLoginName+1) << endl;
m // cout << *(_userLoginName+1) << endl;
I really did try reasoning the result but I cannot figure it out.
Thank you.
If you give cout1 a char *, it will try to print a string. If you give it a char, then it will print that single character.
_userLoginName and (_userLoginName+1) are of type char *; *_userLoginName and *(_userLoginName+1) are of type char.
1. Technically, "give std::operator<<(std::ostream &, T)".
Pull out a sheet of paper and draw a box with six cell with "smith" written into them:
+-+-+-+-+-+--+
|s|m|i|t|h|\0|
+-+-+-+-+-+--+
^ ^
| +- _userLoginName + 1
+- _userLoginName
Use your pen as your pointer '_userLoginName' and point it at the first cell. Derefencing the pointer (i.e. using *ptr for a pointer ptr) means looking at the content of the cell it points at. That is '*_userLoginName' shows into the content of the cell. Writing a pointer of type char* or char const* does something funny: it follows the pointer and writes the content of each cell it finds until it reaches a cell having the value \0.
This should explain the first to outputs. Now, ptr + 1 looks at the cell next to ptr, i.e. ptr + 1 is another pointer (pull out another pen if necessary) placed the next cell. It does just the same as above.
Consider the type of *_userLoginName—it is char.
Maybe you overlooked that * in this context dereferences the pointer?
Dereferencing a pointer (such as *_userLoginName) always returns the element the pointer is pointing at, in the case of a normal string the first character therein, which is then printed.
Adding n to a pointer (such as _userLoginName+1) increments the pointer by n steps, so if it pointed to the 0th element it will afterwards point to the nth element.
Combine the two to explain the fourth line.
The first cout is looking at the pointer userLoginName (char* and char[] are very very similar in c++). The cout will print all values in memory, treating them as chars, until it comes across a '\0' character, which terminates the string.
The second cout is looking at one memory element, that pointed to by userLoginName, or userLoginName[0].
The third cout is doing the same as the first, but the memory address starts 1 char later than userLoginName, as the pointer is of type char.
The final cout is the same as the second, but is userLoginName[1].
There are two separate overloads for operator<< at work here: One for char-pointers, and one for chars. The second one, for single characters, simply prints that one character. The first one, for char pointers, treats the pointer as the pointer to the first character in a null-terminated array of characters (a "string") and prints all those.
Combine this with the language syntax that a[i] is the same as *(a + i) for an array a, and you have:
cout << s; // prints all characters, starting at the first
cout << *s; // prints only the first character, equal to "cout << s[0];"
cout << s + 1; // prints all characters, starting at the second
cout << *(s+1); // prints only the second character, equal to "cout << s[1];"
I was just experimenting with the use of pointers when dealing with arrays and I've become a bit confused with how C++ is handling the arrays. Here are the relevant bits of code I wrote:
//declare a string (as a pointer)
char* szString = "Randy";
cout << "Display string using a pointer: ";
char* pszString = szString;
while (*pszString)
cout << *pszString++;
First off, when I tried using cout to write what was in "pszString" (without de-referencing)I was a bit surprised to see it gave me the string. I just assumed it was because I gave the pointer a string and not a variable.
What really caught my attention though is that when I removed the asterisk from the line cout << *pszString++; it printed "Randyandyndydyy". I'm not sure why it's writes the array AND then writes it again with 1 letter less. My reasoning is that after writing the char string the increment operator immediately brings the index to the next letter before it can reach the null terminator. I don't see why the null terminator wouldn't cause the loop to return false after the string is output for the first time otherwise. Is this the right reasoning? Could someone explain if I'm getting this relationship between arrays and pointers?
cout has an operator<< overload for char* to print the entire string (that is, print each character until it encounters a 0). By contrast, the char overload for cout's operator<< prints just that one character. That's essentially the difference here. If you need more explanation, read on.
When you dereference the pointer after incrementing it, you're sending cout a char, not and char*, so it prints one character.
So cout << *pszString++; is like doing
cout << *pszString;
pszString = pszString + 1;
When you don't dereference the pointer, you're sending it a char* so cout prints the entire string, and you're moving the start of the string up by one character in each iteration through the loop.
So cout << pszString++; is like doing
cout << pszString;
pszString = pszString + 1;
Illustration with a little loop unrolling:
For cout << *pszString++;
Randy\0
^ pszString points here
// this means increment pszString and send cout the character at which pszString *used* to be pointing
cout << *pszString++;
// so cout prints R and pszString now points
Randy\0
^ here
// this means increment pszString and send cout the character at which pszString *used* to be pointing
cout << *pszString++;
// so cout prints a and pszString now points
Randy\0
^ here
// and so on
For cout << pszString++;
Randy\0
^ pszString points here
// this means increment pszString and pass the old pointer to cout's operator<<
cout << pszString++;
// so cout prints Randy, and now pszString points
Randy\0
^ here
cout << pszString++;
// cout prints andy, and now pszString points
Randy\0
^ here
// and so on
I am glad you are experimenting with pointers this way, it'll make you actually know what's going on unlike many programmers who will do anything to get away from having to deal with pointers.