This is not true. A pointer is a varaible with a memory address
for a value.
You're again thinking only in terms of the values of pointers,
i.e. memory addresses, and are disregarding that a pointer is
more than an address - it has another quality, it got 'type'.
The object stored at the memory location is not defined by the pointer-type,
for example:
int x =0;
char* p = 0;
p= (char*)&x;
p[2] =1;
The pointer-type is char* , but its initialised to point to nothing,
then it is assgined the address of an int. At no time does this
pointer point to an object of type char.
When you dereference the char pointer the compiler will
extract a value of type char from that location. By poin-
ting a char pointer to an address you promise the compiler
that it can extract a char value from there when asked to.
That's not a big problem with chars - since they are the
smallest addressable unit you hardly can go wrong with that.
The other way round (assuming an int with 4 bytes)
char y[ ] = "abcd";
int * ip = ( int * ) &y;
you're already into deeper trouble. If you use 'ip' to get
at an int value stored in that location you get away with
that on a number of architectures all of the time, but on
others, if you're unlucky, your program will crash with a
bus error since the array of chars may not be properly
aligned for an int access.
And then, when you convert from one type to another, you
have to go to some effort, especially under C++. C is
somewhat more relaxed about that since it was intorduced
forprogramming near to the metal were most people had a
good idea what can be done and what to avoid. C++ tightens
the rules quite a bit to keep people from making mistakes
but still lets you do a lot of things that are against the
type system (making casts more ugly and harder to write
is another way to dicourage people to use them). So, yes,
you can work against the type system, but at your own peril
- and then, if you do, it's advantageous if you understand
what you're doing.
This is a pointer to an array type.
You need to acknowledge that an array-type is not the same as an array
entity.
I don't know exactly what an 'array entity' is supposed to mean.
If it means a "real array" I use in my program, then yes, of
course, it's something different. The same way a table isn't
the same as the word "table".
When we say a char* can point to an array we are speaking about an
array entity.
You are, again, disregarding 'type'. I never claimed that an
array has not the same address as its first element. But hol-
ding the same address does not make two pointers identical
if they have different types. If I have a laser shining at
my head at same time stand in the sun that doesn't make the
laser the same as the sun just because they both illuminate
my head. Two pointers of different types behave differently,
even if they point to the same memory location.
Or take an example that doesn't involve pointers at all:
usigned char c = 0;
unsigned long l = 0;
You're arguing that they are the same since they both have
the same value. But now let's do the exact same thing to
both variables:
c += 2263576;
l += 2263576;
And now it becomes (at least on "normal" machines, where
the range of a char is rather limited) that they are not
the same at all, you just have to compare their values.
So their different types make a lot of a difference, even
if both started of with the same value and the exact same
operation was applied to them.
When an array is converted to a pointer, the pointer-type is a
pointer to a (n-1) dimensional array.
I go into that at the end.
You can't say a statement such as "a char* can point to an array of chars"
is sloppy because you have interpreted it incorrectly. You are confusing the
obvious(IMO) context of an array entity, with array-type.
I have no problem saying that. It may be ok to say "a char *
points to an array" when everyone around understands that
this is just short for "points to the first element of an
array" and I don't want to sound pompous or like a buro-
crat but that doesn't make it a precise statement.
If you cannot access the array , then its not a pointer to the array.
A pointer to an array , when dereferenced must access the array.
Of course, you can access the array, I never said anything
else. You just can't directly access its individual elements
of the array. The same way you can't directly access the in-
dividiual members of a structure when you have a pointer to
a structure. The pointer to the structure points to the
structure as a whole (even when that is the same address as
the first member) and you need some extra syntax to get at
its members.
Actually, according to your line of arguments you also should
say that with
struct {
int x;
int y;
} z;
int * ix = ( int * ) &z;
'ix' is now a pointer to the structure. It's value is the
same as the address of 'z', so, according to your criteria,
it should be a pointer to the structure. But do you really
think so?
What you describe is an indirect pointer to an array, you must dereference
it twice to access the array.
No. There is a difference between accessing an array and
accessing an element of an array. An array is a structured
blob in memory the same way e.g. a structure is. And a
pointer to an array points to that blob. Getting at its
innards need a bit more work, as it is needed for getting
at the members of a structure. That you can't write an
element access like e.g. 'ap->[1]' (which would be 'sym-
metric to how one would deal with a structure pointer) is
just the "fault" of the language and you thus have to re-
sort to the more ugly '(*ap)[1]', in e.g. Perl that's quite
fine when you have a pointer (reference) to an array.
An array of chars is not a type, its an entity.
I never said that an array of chars "is" a type, I said
it "has" a type - beside its property of consisting of a
number of bytes. We're not discussing assembler here, the
language adds types to entities when we progrm in that
language and we need to consider that. What later happens
at the execution phase is something different. There is no
1-to-1 mappin between the language and what the processor
does when the program has been compiled. Otherwise using a
computer language would be useless.
A pointer of type char* can point to an array of chars, when dereferenced it
returns one element of the array.
You cannot get any pointer type that addresses a whole array simultaneously,
unless the array is sized one or something silly like that.
This depends on what you mean by being equal.
are the following two variables equal:
int x=0
char c=0;
No, they aren't, see above.
Yes there is obviously a difference in opinions on this. I think neither POV
can be said to be right or wrong.
I don't think so. I feel that you're missing an important
point, i.e. that a computer language is more than just
about bits and bytes. It adds completely new levels of mea-
ning that can't be understood in terms of what happpens at
the register and memory level. This allow you to get away
from thinking just in categories of bytes and what happens
to them and instead lets you concentrate on the problem do-
main. Like, when you write "car->turn( 30 );" in an OOP
program you aren't supposed to keep in mind what that does
in terms of what happens in the CPU, you should keep focused
on what the class 'car' is an instance of will do with that.
But having this acceptance for others' POV I feel its wrong to suggest one
POV is sloppy and somehow incorrect when it's a failure to understand the
other POV.
You're in a good mood tonight;-) But, sorry, I think your
POV is wrong, or at least misses an important aspect.
But sometimes you don't need the type info.
And often you have no option because you are using a function that takes a
pointer to an array , not a reference.
But regardles if I want the type or not it's there, given by the
language I'm using.
Perhaps it would be better if C++ pointers to array were of the type you
describe but this is not the case , I think we are stuck with the present
case which we inhereted from C
I'm not really religious about the way it's done in C or C++.
And passing a pointer to an array would require other changes
in the language. Since an array has a well-defined length you
would need a functions for each length of array. To avoid
that You would need to change C++ so that it would accept an
argument of 'pointer to array of unspecified length' but still
be able to get at the length - or you'd be back to square one,
i.e. you'd would have to pass a length with the pointer to the
array. And when we would need that then it would make no sense
at all, there would hardly any difference to what we have now.
char* p= new char[64];
The above is a pointer points to an array of 64 chars.
No, that's a pointer to a single char, the one at the
very start of the array. If you want a pointer to an
array of 64 chars you need
char (*p64)[64];
Ok so this is also wrong?
<quote ref=
http://www2.research.att.com/~bs/glossary.html>
"char* - pointer to a char or an array of char."
</quote>
Again lingo, not wrong when meant in the right way, just a
bit sloppily expressed. It might have been better if he had
said "...or the first element of an array", but then this is
a glossary, not an in-depth explanation.
Again why would he say pointer the nth element, when the pointer can
point
to any element?
It's really simple: If you increment a pointer by 1 it
always points to the address directly behind the object
it pointed to (its value is increased by the size of the
type of object it points to). And if you incrememt 'p'
by 1 it points to the next char in the array, so it's a
pointer to a single char, not an array of so many chars.
That it points to the first element of the array doesn't
change anything about that. But if you increment 'p64' by
1 it points directly past the end of the array, so that's
a pointer to an array of 64 chars.
Perhaps you should read Chris Torek's nice article about
pointers and arrays
http://web.torek.net/torek/c/pa.html
and also
http://web.torek.net/torek/c/expr.html#therule
(which might address the reasons behind your confusion).
While it's about C C++ works the same way.
Thanks for your post but I think you should read the quotes I posted
above
from Bjarbne Stroustrup and Steve Summit.
I did but I don't think they really support your point of view.
\They clearly state exactly my POV.
That a char* can point to a single char or an array of chars.
Why then does incrementing pointers of different types re-
sult in different values? You seem to be avoiding that point.
Or you're using your private definition of "pointer", probably
one that turns a blind eye to pointers having a type beside a
value. That's nothing I'm going to have sleepness nights about,
but it makes discussions a bit difficult and, if you insist on
your definition, futile in the longer (or even shorter) run.
I don't see that I'm avoiding anything.
You ask why does incremeenting pointers of different types result in
different values.
I think you mean by different values , you probably mean different stepping
increments and not the value of the pointer.
The values of the two pointers 'p' and 'p64'
char x[ 64 ];
char *p = x;
char ( *p64 )[ 64 ] = &x;
are the same now but will definitely be different after you did
p++;
p64++;
The first one will point to the second element of the array 'x',
the other will point directly after the end of 'x'. So I would
call that a different value, wouldn't you? And that's one of
the differences in behaviour that's due to the different types
of the pointers.
The way I see it an array is converted to a pointer of type pointer to (n-1)
dimensional array. So with a 2dim array the pointer-type it's converted to
is:
T (*)[Dim2]
incrementing this pointer-type would result in stepping increments
sizeof(T)*Dim2, which effectively would step over a whole sub-array. This
allows the following 2d subscripting with 2d array pointers:
p[0][0];
Nice point you're giving me there;-) If you have e.g.
int a[ 3 ][ 5 ];
then you need
int ( *ap )[ 5 ] = a;
i.e. 'a' "decays" to a real 1D array pointer like the one I des-
cribed before. And are you now going to argue that '(*ap)[5]' is
a pointer to a two-dimensional array as it would seem logical to
me when you claim that 'char *' is also a pointer to an array?
To me it looks like a pointer to a 1-dimensional array as this
example program perhaps can illustrate
#include <iostream>
int main( )
{
int a[ 3 ] = { 1, 2, 3 };
int ( *ap )[ 3 ] = &a;
int b[ 3 ][ 2 ] = { { 7, 9,}, { -4, 5,}, { 8, -5 } };
int ( *bp )[ 2 ] = b;
std::cout << ( *ap )[ 1 ] << ' ' << ( *bp )[ 1 ] << '\n';
}
- both 'ap' and 'bp' seem to me to have the same type.
As you say, this conversion ("decaying" when an array is used
in a context where a value is expected) reduces the dimension
by 1. But that does not make the thing on the left and right
hand side the same - the equal sign is even more out of place
here then it is everywhere else (when you consider its mathe-
matical meaning). This is basically an overloding of the '='
operator to get any sense out of that expression since an
array (whatever it's dimension) simply has no value in C or
C++ and thus such an expression would be meaningless other-
wise. (Or arrays would have to be made "first-class" citi-
zens of C and C++, so that you could assign one array to
another with '=' and pass it by value to a function, as you
can do with structures or class instances.)