C++ pointers

Started by
28 comments, last by bahadir 16 years, 2 months ago
I am learning about C++ pointers and need to clear up a few things. My understanding is that a simple pointer holds the address location of an object or an array and when you want to know the content of the address its pointing to, you put the * in front of it. But what I dont understand is, when you try to print the address location of what it holds, it instead prints the contents of that location instead. This is of course valid for char type pointers. If I make the pointer a type of int, then it prints the address location instead. So, my question is why isnt this consistent among pointer types? I think you might be already confused and want an example, so here it is:


#include <iostream>

using namespace std;


int main()
{
	char cArr[] = "abcdefgh";
	int  Arr[] = {1,2,3,4,5};

	cout << cArr << endl;
	cout << Arr << endl;


	return 0;
}

Ok, here I set up an array of chars and an array of ints. When I print the content of cArr I get the full string instead of the address. But when I print the content of Arr, I get the actual address location instead of 1. Obviously, if I have *cArr and *Arr, i get the contents of that location. So, my question is, depending on the type of Array, why is the output inconsistent? thanks EDIT: how can I print out the address of cArr, like I did for Arr? by using &?
Advertisement
In C & C++ an array of characters is a string (this is unlike many other languages where strings are special).
You are actually missing the null-delimiter in the first array, so it ought to be printing a lot of garbage and could actually crash.

char cArr[] = "abcdefgh\0";

C++ introduces the std::string class to manage dynamic strings.


char* is not handled the same way other pointers are by the cout object.

Interesting though, try cout << &cArr[0] << endl;
Will that print the address or the string again?
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
actually i dont think i need to put a null character at the end of the string because i think the compiler does that for you.

i tried &cArr[0] and got the string output instead. but when I do &cArr, that seems to print out the address location. but that still really doesnt answer my question as to why char* is treated differently than int*

"char* is not handled the same way other pointers are by the cout object"

I wonder why?
&cArr[0]...

All that does is dereference the pointer and then make it back into a pointer.

The reason they are treated differently is that the "<<" is an overloaded operator. Depending on the type sent on the right, the function evalulates differently.

MSDN Documentation
oh ok. so in other words "cout" re-formats or re-interprets the output?
No. It doesn't reformat and reinterpret anything. It's just that char * , signed char * and unsigned char * are treated in a special way. In C there is no String type like in Java and C++, so all functions like printf treat char * as null-terminated strings. C++ inherited this behaviour, so cout.operator<< treates char * as a null-terminated strings. If you want to print the actual address cast it to void *.

And use std::string in C++ instead of char *.
Quote:Original post by Shannon Barber
In C & C++ an array of characters is a string (this is unlike many other languages where strings are special).
You are actually missing the null-delimiter in the first array, so it ought to be printing a lot of garbage and could actually crash.

char cArr[] = "abcdefgh\0";
This is not right, you never have to explicitly put the null char at the end of a string literal in C or C++. This is always implicit, and if you specify it there will be two null chars.
You have been previously misinformed.

The reason that it does something different for a char* is that there is an overload of the << operator for char* which looks at the string that the pointer points to and prints that out instead. This is simply for convenience. There isn't a similiar overload for int* because in general it just isn't useful.
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms
The others have explained things to you well enough, I don't feel obliged to say anything -- but if you were curious, you can check out the msdn on operator overloading.

Simply put though, you can do a few things with a pointer...

1) point it at something (duh).
2) get the address it is pointing at.
3) convert it to another type (sometimes useful, bit dangerous sometimes too).
4) iterate through arrays (not going to explain how -- pretty bad form to do this).

...and I am sure I forgot a few things too. Trick is remembering how to do each thing in different scenarios; c++ is not very forgiving, pointer bugs can be hell to track down >.<

~Shiny

[edit] I forgot to mention; just because you can overload operators doesn't necessarily mean it is a good idea to -- there are certain guidelines that ought to be followed, which include not screwing up the ability of people to understand your code when they read it...
------------'C makes it easy to shoot yourself in the foot. C++ makes it harder, but when you do, it blows away your whole leg.' -Bjarne Stroustrup
thanks guys for your help. I was further experimenting about pointers when something didnt make sense to me. I thought this was odd. Consider the following code:

#include <iostream>using namespace std;void main(){	char *cp, Arr[] = "abcdefgh";	int *ip, Irr[] = {1,2,3,4,5};	cp = Arr;	ip = Irr;	cout << *(cp) << " " << *(cp+1) << endl;	}


Well the output is obvious, its "a" and "b".

But if i change the cout line to this instead:
cout << *(cp) << " " << *(cp++) << endl;

I would have expected "a" and "a" but instead I get "b" and "a".

Is this correct?? How does "b" get output first? I havent incremented the pointer until the second output and then again thats post-fix increment not prefix! Am i screwing up somewhere thinking it should be "a" and "a"?
Quote:Original post by bahadir
Is this correct??


Undefined behavior. Don't modify and read a variable within the same expression without placing a sequence-point in-between. In this case, the '*cp' may be evaluated either before or after '*cp++' was evaluated, or it may do something else entirely (such as crashing your computer) because there's no sequence point to order their execution.


This topic is closed to new replies.

Advertisement