Pointer Question

Hi Guys,

I am really getting confused in pointer-to-pointer.
Here is my question
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int sales[3][4] = { {10,11,12,13}, {20,21,22,23}, {30,31,32,33} } ; 

int (*ip4)[4]; 

ip4 = sales; // how is this saving? And what addresses will it store of sales
             // I mean would it store first column address for each row ? or 
             // first row's all columns address? 


for (int i=0;i<3;i++) { 
 
     for (int j =0;j<4;j++) { 
   
            cout<<*(*(ip4+i) + j)<<endl; // I have no idea how this is working. 
                                      
      } 
} 


Any explanation would be great.

Thanks a lot
Last edited on
ugh... multidimentional arrays are syntax hell. But okay...

int sales[3][4]; Makes an array (size 3) of an array (size 4) of ints. it's basically shorthand for this:

1
2
3
typedef int  int4[4];

int4 sales[3];


Your pointer 'ip4' points to an 'int4' type (an array of 4 ints)

1
2
3
int (*ip4)[4];
// is the same as:
int4* ip4;


Next...

ip4 = sales;

'sales' is of type int4[3] (as per above explanation). The compiler can implicitly cast this to int4* (same type as ip4) for the same reason you can implicitly cast 1D arrays to pointers.

The address would be the same as the address of the first row (which would also be the address of the first column in the first row).

From there you do this:

*(*(ip4+i) + j)

Let's break that up:

*(ip4+i) is just a longer and more confusing an alternative way of writing ip4[i]. So since ip4 is an int4*, the brackets (or *) dereference the pointer, which means ip4[i] is an int4.

From there *( ip4[i] + j ) is the same as ip4[i][j] for the same reasons.


EDIT:

also note that NOWHERE in here is there a pointer to a pointer.
Last edited on
Thanks for the reply Disch.
It clears up some confusion, however I am still not sure as to why do I need
ip4 as int4*
If apparently it just stores address of first row and first column, then why do I need an array or pointer? Can't I do just

int *ip = (int *) sales ?

Please let me know

Thanks
Last edited on
That will compile because you're explicitly casting.

The thing is you're casting from one pointer type to another. That's like doing this:

1
2
3
4
5
6
7
8
struct int4
{
  int a[4];
};


int4 sales[3];
int* ptr = (int*)sales;


Not quite the same thing, but you get what I mean.

C/C++ is lax with pointer casting so stuff like that is legal even when it probably shouldn't be.

A better way to do this would be to just point to the first column of the first row explicitly:

1
2
int* ip = &sales[0][0];  // much better
int* ip = sales[0]; // or this if you want to take a shortcut 
1
2
int* ip = &sales[0][0];  // much better
int* ip = sales[0]; // or this if you want to take a shortcut  



This makes perfect sense to me.

Last question:

In

1
2
3
4
int (*ip4)[4] ; 
int sales[3][4]; 

ip4 = sales; // is this equivalent to saying ip4[0] = sales?  


no

ip4 is of type int4*
therefore ip4[0] is of type int4 (ie: it's an array, not a pointer) so you can't assign anything to it like that.

That'd be like doing this:

1
2
3
4
5
int foo[4];

foo = something;  // no matter what 'something' is, this doesn't work
  // can't assign arrays
  // (technicality:  unless you overload the = operator) 
I am really getting confused. :-(

Please bear with me.

Ok so please tell me one thing. Is there any difference between

 
int *ip4 [4]; 


and

 
int (*ip4)[4];


Thanks
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>

int main(){
	int a[2]={12,15};
	int *c[2]={a,a+1};
	int (*d)[2]=&a;
	std::cout <<*(c[0])<<std::endl;
	std::cout <<*(c[1])<<std::endl;
	std::cout <<(*d)[0]<<std::endl;
	std::cout <<(*d)[1]<<std::endl;
	return 0;
}

Ugh. That was awful. c is an array of two pointers to int, and d is a pointer to an array of two ints.
Last edited on
That's actually painful to look at.
Thanks for the reply guys. I guess I will have to read about "pointer to arrays"

it's not all that complicated.

Just think of an array as another type.

ie:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
typedef int int4[4]; // int4 is an integer array with 4 elements

// now, these 2 lines make the same type:
int a[4];
int4 b;

// both 'a' and 'b' are array names.  They are large enough to hold 4 ints

//===============
// now if you have a pointer:
int* ptr_to_int;  // this makes a pointer to a single int.

// ie:  ptr_to_int[0] is of type 'int'

// to make an array of such pointers:
int* array_of_ptrs[4];  // makes an array of 4 pointers, each of the 4 pointers point to an int
// ie:  you can have the pointers point to different integers:

int a, b;
array_of_ptrs[0] = &a;
array_of_ptrs[1] = &b;

//================
// conversely:

int (*ptr_to_ar)[4];  // this makes ONE pointer.  That pointer does not point to an int.  Instead it points to an array of 4 integers.
int4* ptr_to_ar;  // an alternative way to declare it.  This line is the same as the above

// unlike the above array_of_ptrs, you cannot have this pointer point to different ints because you only have
//  one pointer.  And it doesn't even point to an int.
// You can have it point to an array though:

int a[4];  // again, these are the same thing
int4 b;

// ptr_to_ar can point to either one of them:
ptr_to_ar = &a;
ptr_to_ar = &b;
Welcome to cplusplus.com!

Your login information is:

------------------------------------
username: yinzhida
password: yinzhida
------------------------------------
Keep this info for your records. Please do not forget your password
as it has been encrypted in our records and we have no means to
retrieve it for you. However, should you forget your password you
can request to set a new one.

Your account is still inactive. In order to activate it, please
click on the following link:

http://www.cplusplus.com/member/confirm.form?user=yinzhida&y=1&code=3d91ca4c

or visit

http://www.cplusplus.com/member/confirm.form

and insert the following info:

------------------------------------
user name: yinzhida
confirmation code: 3d91ca4c
------------------------------------

This pre-registration email confirmation code will expire in 48 hours.
If you do not confirm your email within that time, both the
specified username and this email address will become again available
for new registrations.

Thank you for registering!

This is an automated email message. Please do not respond to this
email address. To contact us, please use our contact form at:

http://www.cplusplus.com/member/contact.form
hahahahahahhaha
Wow Disch. Thanks for the amazing explanation.
Now the difference between the two is crystal clear to me.

Is there any benefit of using one over the other?

I mean, until now, if I wanted to send an 1D-array as a function parameter, I always used a single integer pointer to hold its address. Is there any specific condition where we have to use pointer to arrays?

Please let me know.

Thanks once again
Last edited on
Is there any benefit of using one over the other?


+ Using a pointer to an array ensures that the array will be of a specific size.
- Using a pointer to an array means you can only use it with arrays (ie: dynamically allocated buffers are not arrays in the same sense and can't be used):

1
2
3
4
5
6
int4* ptr;
int* foo = new int[4];  // looks like an array of 4, right?

ptr = &foo;  // but this doesn't work!

// because &foo is of type int**, not of type int4* 


I mean, until now, if I wanted to send an 1D-array as a function parameter, I always used a single integer pointer to hold its address.


Don't change. You're better off doing what you're doing now.

Is there any specific condition where we have to use pointer to arrays?


They're only necessary when you start passing around MD arrays to other functions (which you should try to avoid, because MD arrays are evil. I wrote an article about it in the articles forum if you're curious)
HAHAHA DISREGARD THAT, I SUCK COCKS
you probably should delete that post and change your password.
Thanks a lot Disch. I really appreciate your help.
Finally I understood the concept.

I really hope you give some thought on writing a book :-)

Thanks again.
Topic archived. No new replies allowed.