Pointer Problem

B

bintom

What is the difference between the following declarations?

int *ptr[10];

and

int (*ptr)[10];
 
J

Juha Nieminen

bintom said:
What is the difference between the following declarations?

int *ptr[10];

and

int (*ptr)[10];

The former is an array of 10 elements, each element being an int*.

The latter is a pointer to a two-dimensional array (iow. a single
array which is indexed using two index values), the second dimension
of said array being 10.
 
8

88888 Dihedral

在 2012å¹´2月16日星期四UTC+8下åˆ11æ—¶15分14秒,Juha Nieminen写é“:
bintom said:
What is the difference between the following declarations?

int *ptr[10];

and

int (*ptr)[10];

The former is an array of 10 elements, each element being an int*.

The place where the * should be appeared is not only
the style problem.
The latter is a pointer to a two-dimensional array (iow. a single
array which is indexed using two index values), the second dimension
of said array being 10.

int* ptr[10];
int (*ptr2)[10];

//I prefer this style.
 
V

Victor Bazarov

在 2012å¹´2月16日星期四UTC+8下åˆ11æ—¶15分14秒,Juha Nieminen写é“:
bintom said:
What is the difference between the following declarations?

int *ptr[10];

and

int (*ptr)[10];

The former is an array of 10 elements, each element being an int*.

The place where the * should be appeared is not only
the style problem.
The latter is a pointer to a two-dimensional array (iow. a single
array which is indexed using two index values), the second dimension
of said array being 10.

int* ptr[10];
int (*ptr2)[10];

//I prefer this style.

You do, do you? In this declaration:

int* a[10], b[20];

what's the type of 'b[2]'?

V
 
V

Victor Bazarov

Victor Bazarov said:
在 2012å¹´2月16日星期四UTC+8下åˆ11æ—¶15分14秒,Juha Nieminen写é“:
What is the difference between the following declarations?

int *ptr[10];

and

int (*ptr)[10];

The former is an array of 10 elements, each element being an int*.


The place where the * should be appeared is not only
the style problem.

The latter is a pointer to a two-dimensional array (iow. a single
array which is indexed using two index values), the second dimension
of said array being 10.

int* ptr[10];
int (*ptr2)[10];

//I prefer this style.

You do, do you? In this declaration:

int* a[10], b[20];

what's the type of 'b[2]'?

int of course. Yet another reason to place declarations individually.

int *a[10];
int *b[10];

Easier to pick out the identifier visually this way.

Identifiers should have a meaningful number of characters for easy
picking out, IMNSHO. 'a' or 'b' aren't very good no matter whether you
declare them each on a separate line, or together.

Besides that, why waste a line of code in the following idiom:

sometype obj, *ptr = &obj;

?

V
 
M

Mike McCarty

...
Besides that, why waste a line of code in the following idiom:

sometype obj, *ptr = &obj;

?


Uh, why not?

Do you also prefer this:

Foo f; Bar *b=&f;

?

If not, why not? Semantically, it's exactly the same thing.
 
J

Juha Nieminen

LR said:
bintom said:
What is the difference between the following declarations?

int *ptr[10];

and

int (*ptr)[10];

You may want to read about the Right Left Rule.

Unfortunately that rule doesn't help here because the "(*)[]"
syntax is special and has a particular meaning that isn't obvious.
One just has to know what it means.

(Incidentally, quite many even experienced C and C++ programmers
don't know how to create a pointer to a multi-dimensional array, or
even that it's possible. It's one of the more obscure features of C.)
 
J

Jens Thoms Toerring

Juha Nieminen said:
bintom said:
What is the difference between the following declarations?

int *ptr[10];

and

int (*ptr)[10];
The former is an array of 10 elements, each element being an int*.
The latter is a pointer to a two-dimensional array (iow. a single
array which is indexed using two index values), the second dimension
of said array being 10.

Sorry for chiming in, but the second is just a pointer to
an array of 10 ints, nothing two-dimensional involved at
this stage (see e.g. http://www.torek.net/torek/c/pa.html
even though it's abot C, but there's no difference to C++).

Regards, Jens
 
L

LR

Juha said:
LR said:
bintom said:
What is the difference between the following declarations?

int *ptr[10];

and

int (*ptr)[10];

You may want to read about the Right Left Rule.

Unfortunately that rule doesn't help here because the "(*)[]"
syntax is special and has a particular meaning that isn't obvious.
One just has to know what it means.

I'm sorry, but I don't understand why the Right Left Rule does not apply
to the second example above. Can you please explain why the rule
doesn't help here and what is special about (*)[]?
 
J

Juha Nieminen

Jens Thoms Toerring said:
Juha Nieminen said:
bintom said:
What is the difference between the following declarations?

int *ptr[10];

and

int (*ptr)[10];
The former is an array of 10 elements, each element being an int*.
The latter is a pointer to a two-dimensional array (iow. a single
array which is indexed using two index values), the second dimension
of said array being 10.

Sorry for chiming in, but the second is just a pointer to
an array of 10 ints, nothing two-dimensional involved at
this stage

If you want to be really pedantic, that might be so. It's the same as
with an "int*" which doubles as a pointer to a single int and a pointer
to an array of ints.

In practice "int*" is basically always a pointer to an array of ints
because it has intrinsic support for it being an array (ie. you can
index the potential array behind it). If it's pointing to a single int
you can think of it as pointing to an array of size 1.

Likewise "int (*ptr)[10]" is always a pointer to a two-dimensional array
where the second dimension is 10, even if it's pointing to just an array
of 10 elements (in which case you can think of it as the first dimension
being 1).

It's useful to know that because it allows you to create pointers to
multi-dimensional arrays, something that's a lesser-known feature of C/C++.
For example, you can have something along the lines of:

int array1[20][10] = { ... };
int array2[20][10] = { ... };

int (*currentArray)[10];
if(something) currentArray = array1;
else currentArray = array2;

currentArray[3][7] = 5;
...
 
J

Juha Nieminen

LR said:
Juha said:
LR said:
bintom wrote:
What is the difference between the following declarations?

int *ptr[10];

and

int (*ptr)[10];

You may want to read about the Right Left Rule.

Unfortunately that rule doesn't help here because the "(*)[]"
syntax is special and has a particular meaning that isn't obvious.
One just has to know what it means.

I'm sorry, but I don't understand why the Right Left Rule does not apply
to the second example above.

I didn't say it doesn't apply. I said it doesn't help understanding
what the syntax means.
 
N

Nick Keighley

On 2/16/2012 12:18 PM, Scott Lurndal wrote:
[...] Yet another reason to place declarations individually.
     int *a[10];
     int *b[10];
Easier to pick out the identifier visually this way.

Identifiers should have a meaningful number of characters for easy
picking out, IMNSHO.  'a' or 'b' aren't very good no matter whether you
declare them each on a separate line, or together.

depends. If you're solving quadratic equations than 'a' and 'b' may be
quite sensible identifiers.

On behalf of the Campaign Against Unnecessarily Long Variable Names

<snip>
 
L

LR

Juha said:
LR said:
Juha said:
bintom wrote:
What is the difference between the following declarations?

int *ptr[10];

and

int (*ptr)[10];

You may want to read about the Right Left Rule.

Unfortunately that rule doesn't help here because the "(*)[]"
syntax is special and has a particular meaning that isn't obvious.
One just has to know what it means.

I'm sorry, but I don't understand why the Right Left Rule does not apply
to the second example above.

I didn't say it doesn't apply. I said it doesn't help understanding
what the syntax means.

I'm not sure I agree, but I can see your point about the RLR not leading
to an understanding of the semantics. However, the OP asked about the
difference between the two, and I think the RLR is very useful for that
purpose.
 
J

Juha Nieminen

LR said:
However, the OP asked about the
difference between the two, and I think the RLR is very useful for that
purpose.

That would have been the case if he had asked something like what's
the difference between

const int* ptr;

and

int* const ptr;

However, in the case of "int *ptr[10]" vs. "int (*ptr)[10]" it's of
no help.
 
J

Jens Thoms Toerring

Juha Nieminen said:
Jens Thoms Toerring said:
Juha Nieminen said:
What is the difference between the following declarations?

int *ptr[10];

and

int (*ptr)[10];
The former is an array of 10 elements, each element being an int*.
The latter is a pointer to a two-dimensional array (iow. a single
array which is indexed using two index values), the second dimension
of said array being 10.

Sorry for chiming in, but the second is just a pointer to
an array of 10 ints, nothing two-dimensional involved at
this stage
If you want to be really pedantic, that might be so. It's the same as
with an "int*" which doubles as a pointer to a single int and a pointer
to an array of ints.

Ok, let me really pedantic;-) An "int*" doesnt double as a pointer
to an array (of ints), it just can point to an element of an array
(just as it can point to a "lonely" int).
In practice "int*" is basically always a pointer to an array of ints

There are a lot of cases where there are pointers to single ints,
e.g. when passing them to a function (admitedly, more often in C
were ypu don't have references and pointers are the only way to
pass something to a function that can be modified from within
the function).
because it has intrinsic support for it being an array (ie. you can
index the potential array behind it). If it's pointing to a single int
you can think of it as pointing to an array of size 1.

I understand what you mean, but this is saddling the horse from
the back. An "int*" never points to more than a single int. Due
to the shortcoming of C (and thus C++) that arrays aren't "first
class" objects (i.e. they can't be passed to functions by value
since an array isn't a "value", contrary to e.g. structures) a
special case was introduced: when an array appears in a place
were a value is required then the array gets converted to a
pointer to the first element of that array. And this has
resulted in many people (even experienced C and C++ program-
mers) getting confused about the distinction between arrays
and pointers. But that doesn't make a pointer anything "array-
like" - it's just that in certain situations when an array is
found it is converted silently to a pointer to that array's
first element. That's all there's about "intrinsic support".
Likewise "int (*ptr)[10]" is always a pointer to a two-dimensional array

Sorry, but no. Like an "int*" only points to a single int, a "int
(*ptr)[10]" points to just a single array of 10 ints. But because,
when incremented, it points to the next following array of 10
ints it can be used to iterate over the sub-arrays of a two-
dimensional array when that is an array of arrays of 10 ints.

I can just recommend reading what Chris Torek writes about all
this (even though it doesn't mention C++, but it's exactly the
same in C++) - it's the most lucid explanation I've ever found.

Best regards, Jens
 
P

Peter Remmers

Am 18.02.2012 23:39, schrieb Jens Thoms Toerring:
Ok, let me really pedantic;-) An "int*" doesnt double as a pointer
to an array (of ints), it just can point to an element of an array
(just as it can point to a "lonely" int).

I think I have a deja vu :)



Peter
 
P

Paul

Juha Nieminen said:
Jens Thoms Toerring said:
What is the difference between the following declarations?
int *ptr[10];
   and
int (*ptr)[10];
  The former is an array of 10 elements, each element being an int*.
  The latter is a pointer to a two-dimensional array (iow. a single
array which is indexed using two index values), the second dimension
of said array being 10.
Sorry for chiming in, but the second is just a pointer to
an array of 10 ints, nothing two-dimensional involved at
this stage
  If you want to be really pedantic, that might be so. It's the same as
with an "int*" which doubles as a pointer to a single int and a pointer
to an array of ints.

Ok, let me really pedantic;-) An "int*" doesnt double as a pointer
to an array (of ints), it just can point to an element of an array
(just as it can point to a "lonely" int).
In practice "int*" is basically always a pointer to an array of ints

There are a lot of cases where there are pointers to single ints,
e.g. when passing them to a function (admitedly, more often in C
were ypu don't have references and pointers are the only way to
pass something to a function that can be modified from within
the function).

The pointer can point to a single integer or an array of integers, it
is dependant on the context.
I understand what you mean, but this is saddling the horse from
the back. An "int*" never points to more than a single int.

What you say is technically incorrect because an int* can point to one
past the last element of an array of integers thus it may not point to
any single integer.
If such a pointer doesn't point to any single integer yet still points
to an array of integers , what does this pointer point to?
Due
to the shortcoming of C (and thus C++) that arrays aren't "first
class" objects (i.e. they can't be passed to functions by value
since an array isn't a "value", contrary to e.g. structures) a
special case was introduced: when an array appears in a place
were a value is required then the array gets converted to a
pointer to the first element of that array. And this has
resulted in many people (even experienced C and C++ program-
mers) getting confused about the distinction between arrays
and pointers. But that doesn't make a pointer anything "array-
like" - it's just that in certain situations when an array is
found it is converted silently to a pointer to that array's
first element. That's all there's about "intrinsic support".
Likewise "int (*ptr)[10]" is always a pointer to a two-dimensional array

Sorry, but no. Like an "int*" only points to a single int,
This is not correct see above.
a "int
(*ptr)[10]" points to just a single array of 10 ints. But because,
when incremented, it points to the next following array of 10
ints it can be used to iterate over the sub-arrays of a two-
dimensional array when that is an array of arrays of 10 ints.
The pointer type int(*) will point to the same thing as an int*
that stores the same address.

In C++ the array works in such a way that it defaults to a pointer, or
an address , and you don't need to take the address of an array in the
same way you'd normally take the address of an object. The language is
structured in such a way that the index operator [] automatically
dereferences a pointer to an array. For example:

int anarray[5] = {0};
int* ptr = anarray;

There is no need to take the address of an array , it automatically is
converted to a pointer.



An array can be thought of in two ways:
a) one complete object with its own type
b) a sequence of objects
The argument you put forward is based on a) where the pointer-type T*
is a pointer to an object of type T, where T is an array object type.
But as you said arrays aren't first class objects and cannot be
accessed by value. So we cannot have a pointer that, when
dereferenced, returns an array.

I think the way most people see it is that an array is a sequence of
elements of type T, so it makes sense that the pointer that points to
them is of type T*. The fancy pointer types like T(*) are of the
same type but have another level of indirection to allow for multiple
indexing .. anarray[i1][i2].

HTH
Paul.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top