Page 1 of 2 12 Last
  • Jump to page:
    #1
  1. No Profile Picture
    .
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2002
    Posts
    296
    Rep Power
    12

    array containing arrays pointer incrementing?


    this is something that's niggled me with arrays in an array in conjunction with pointers for a while now. i *think* i've now realised the answer myslelf, but i just want to check.

    2 arrays in an array:
    Code:
    	char array[2][5] = {
    		{14, 13, 12, 11, 10},
    		{54, 53, 52, 51, 50}
    	};
    this is no problem, for example:
    Code:
    	char *j = array[1];
    (which is the same thing as char *j = &array[1][0]; ). those both give a pointer to the first element in the second array which is 54. obviously if you increment the pointer j, like j++ it then points to 53 in the array, it's second element.

    but is there a way to do the same with the base/main array? the array that contains the two arrays? in the same way as the above example? i've got a feeling not. not in the same way as above that is, bearing in mind in memory the arrays in question are layed out like this i think: 14, 13, 12, 11, 10, 54, 53, 52, 51, 50 and going from 14 to 54 with one ++ doesn't seem so likely, but i could be wrong.

    so reiterating, what i'm wondering is, is there a way to set a pointer to point to the first element of the main/root array, which contains an array, then when the pointer is incremented would then point to the second element, which is the second array? (i'm meaning that very literally - i know there's arrays of pointers which probably fills this gap, but i just want to check on this point)

    what this would require is a pointer that knows the size of the arrays in order to jump the right number of bytes when you ++ it. just like a double pointer knows what size a double is in order to jump the right amount of bytes when it's incremented by one. but then saying that, arrays in an array may not be lined up right next to each other, right? if that's so, then this whole question is out of the question if you see what i mean.

    i don't think there is such a thing, and if that's so, this does point out a difference between arrays that contain arrays and arrays that don't, but you all probably knew that already.

    just wanted to check though. also: there is no guarantee at all that arrays in an array are right next to each other right? is that ever guaranteed?
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Feb 2001
    Posts
    1,473
    Rep Power
    15
    You didn't read those posts carefully enough. :)
    Code:
    #include <iostream>
    using namespace std;
    
    int main () 
    {
    	int Arr2d[2][3] = 
    	{
    		{1, 2, 3},
    		{4, 5, 6}
    	};
    	
    	//Declare a pointer to the array:
    	int (*pArr2d)[3] = Arr2d;
    	
    	//Display the addresses of every value
    	//using the pointer name and array notation:
    	for(int i=0; i<2; i++)
    	{
    		for(int j=0; j<3; j++)
    			cout<<&pArr2d[i][j]<<" ";
    	
    		cout<<endl;
    	}
    
    	//Now check those addresses against
    	//what pointer arithematic yields:	
    	cout<<pArr2d<<endl;
    	cout<<pArr2d + 1<<endl;
    
    	return 0;
    }
    Last edited by 7stud; May 25th, 2003 at 09:09 PM.
  4. #3
  5. No Profile Picture
    .
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2002
    Posts
    296
    Rep Power
    12
    ahh, c please! not c++ :/ sorry: should have indicated that. i see <<'s and get worried. oh yeah, and cout's. seems that the critical part uses << those things maybe.


    oh yeah, and i know about

    *(*(array + i) + j)

    but that's different. that's using 'array' as a base and using i and j to jump from it, 'array' being a static (english static not c) thing.
    Last edited by balance; May 25th, 2003 at 09:24 PM.
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Feb 2001
    Posts
    1,473
    Rep Power
    15
    "seems that the critical part uses << those things maybe."

    Those symbols just allow you to display data in C++, they don't do anything to the data. You can think of "cout<<" as meaning "print". I don't know C, sorry. Using "cout<<", which just means "display this", and using "cin>>", which means "read in this", are much easier than using printf() and scanf()--you don't have to worry about all those % signs, etc.

    oh yeah, and i know about

    *(*(array + i) + j)
    I never used that. I incremented the pointer pArr2d by 1 and I got the address of the next row, not the next element i.e. pointer arithmetic knew the size of the rows.

    Use C to ouput this code to see what I mean:
    Code:
    int Arr2d[2][3] = 
    {
    	{1, 2, 3},
    	{4, 5, 6}
    };
    	
    	
    int (*pArr2d)[3] = Arr2d;
    
    //Display these addresses:
    
    pArr2d
    pArr2d + 1
    
    //Display these addresses and compare them to the ones above:
    
    &pArr2d[0][0], &pArr2d[0][1]
    &pArr2d[1][0]
    
    // Does the address of pArr2d equal the address of pArr2d[0][0]?
    // Does the address of pArr2d + 1 equal the address of 
    // pArr2d[1][0]?  What does that tell you?
    // Did incrementing the pointer by 1 result in the
    // address of the next element in the row(&pArr2d[0][1])
    // or the address of the next row(&pArr2d[1][0])?
    char *j = &array[1][0];...obviously if you increment the pointer j, like j++ it then points to 53 in the array, it's second element....but is there a way to do the same with the base/main array?...14, 13, 12, 11, 10, 54, 53, 52, 51, 50 and going from 14 to 54 with one ++ doesn't seem so likely, but i could be wrong.
    You seemed to be asking if there was a way to increment a pointer by 1 and have it jump to the next row rather than move to the next column. Did I misunderstand?
    Last edited by 7stud; May 25th, 2003 at 10:24 PM.
  8. #5
  9. No Profile Picture
    .
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2002
    Posts
    296
    Rep Power
    12
    i see completely what you're doing with the code. it's output, including the contents of the elements too was:
    Code:
    0xbffffd20 1
    0xbffffd2c 4
    
    0xbffffd20 1    0xbffffd24 2
    0xbffffd2c 4
    but it's similar to this though (base address and adding to it) :

    oh yeah, and i know about

    *(*(array + i) + j)


    I never used that.
    i know. i was just pre-empting that as a possible answer. :)

    You seemed to be asking if there was a way to increment a pointer by 1 and have it jump to the next row rather than move to the next column. Did I misunderstand?
    no you didn't misunderstand. yes, but more particularly a single variable pointer, rather than a pointer made up of array base name with variable added to it: one that opperates in the same way as a variable pointer that points to various elements in an array not containing an array.

    just like a usual pointer you might asign, to step along say a character array using ++ like this:
    Code:
    #include <stdio.h>
    
    main()
    {
    	char chararray[]="abcd";
    
    	char *cp = chararray;
    
    	printf("1st char: %c\n", *cp);
    
    	cp++;
    
    	printf("2nd char: %c\n", *cp);
    }
    obviously that's a 1d array, defining a pointer to the start of it, accessing the array via the pointer, which is the first element, incrementing the pointer, then accessing the array again via the pointer - this time the second element because the pointer was incremented.

    now imagine the above array, instead of containing a, b, c, d in it's elements, imagine it containing arrays instead of single characters. that would make it a '2d' array obviously. but forget the arrays that are going in the place of the characters, staying with the base array, do *exactly* what the above code does: assign a single variable pointer to the base array's first element, ++ it and have it pointing to the second element (which is the second array that has replaced the 'b' in the imaginary array): so i guess that would specifically amount to pointing to the first element of each of the secondary arrays. possible?

    (the reason i say "so i guess that would specifically amount to pointing to the first element of each of the secondary arrays." is because if you've got a usual 1d array and you refer to it just by it's name with nothing else (like with no [i] or if using pointer, +i), that refers to it's fisrt element.)
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Feb 2001
    Posts
    1,473
    Rep Power
    15
    How would that be possible? It sounds like you're asking for polymorphic behavior where the compiler has to read your mind to know whether when you increment the pointer you want it to move to the next element or jump to the next row.

    If you have a pointer to a basic type, and what your pointer points to is in an array, then pointer arithmetic is defined to move to the next element, not the next row. Presumably, you could write your own class where you could make pointer arithmetic jump to the next row.

    Your question seems analogous to asking: "If I have this:

    int var = 10;
    var++;

    is there a way to get var++ to equal 15 instead of 11?"
    Last edited by 7stud; May 26th, 2003 at 02:32 PM.
  12. #7
  13. No Profile Picture
    .
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2002
    Posts
    296
    Rep Power
    12
    yup, of course you're absolutely right. i could see this was working fine:

    pArr2d + 1;

    but failed to see that this would work:

    pArr2d++;

    and that does work fine, so that's it. it's a variable, and a single pointer. brilliant.

    so this:

    int (*pArr2d)[3] = Arr2d;

    the (*pArr2d)[3] bit tells the pointer how big it should be, which is the part that i thought didn't exist. very clever. that's great. thanks 7stud. as i said that was something that was niggling me for a while. :)


    !ah! you've changed your answer! :) oh well, you were right the first time: at least i think you were - it seems to work fine from that example.
    Last edited by balance; May 26th, 2003 at 02:36 PM.
  14. #8
  15. No Profile Picture
    Contributing User
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Feb 2001
    Posts
    1,473
    Rep Power
    15
    lol. I changed my answer because I re-read yor post a few times, and I decided you were asking something else.

    pArr2d + 1

    and

    pArr2d++

    are equivalent.

    int (*pArr2d)[3] = Arr2d;

    the (*pArr2d)[3] bit tells the pointer how big it should be
    int, *, and [3] make up the type of the variable pArr2d. A 2d array is declared like this:

    int Arr2d[2][4];

    and the first dimension of an array--the leftmost one--is not part of the type, so the type of that array is int[ ][3] and a pointer that points to that array must reflect that type.
    Last edited by 7stud; May 26th, 2003 at 02:42 PM.
  16. #9
  17. No Profile Picture
    .
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2002
    Posts
    296
    Rep Power
    12
    i'm not sure if it is working or not. from what you're saying about the impossability - that's what i thought this whole question might be from the outset, but was checking. but you example does seem to be working. will think about it :) thanks.
  18. #10
  19. No Profile Picture
    Contributing User
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Feb 2001
    Posts
    1,473
    Rep Power
    15
    If you want a pointer to a basic type to jump to the next row, it won't work. A pointer declared like this:

    int* pint;

    won't do what you want.
  20. #11
  21. No Profile Picture
    Contributing User
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Feb 2001
    Posts
    1,473
    Rep Power
    15
    Also, I'm not sure about the internals of this:

    int (*pArr2d)[3] = Arr2d;

    and how it works. The one thing I noticed is that you can say:

    pArr2d[0]

    which doesn't make sense to me, since pArr2d is not supposed to be an array of pointers like when declaring it this way:

    int* pArr2d[3];
  22. #12
  23. jasondoucette.com
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2003
    Location
    Canada
    Posts
    378
    Rep Power
    12
    Originally posted by 7stud
    Also, I'm not sure about the internals of this:

    int (*pArr2d)[3] = Arr2d;

    and how it works. The one thing I noticed is that you can say:

    pArr2d[0]

    which doesn't make sense to me,
    since pArr2d is not supposed to be an array of pointers
    like when declaring it this way:

    int* pArr2d[3];
    This is the stuff that is never well explained anywhere. I would like to offer the method in which I understand it, and perhaps it will help you remember/understand it in such a way that it never confuses you again.

    I think of code such as:

    int (*pArr2d)[3] = Arr2d;

    in which there are brackets ( ) around the pointer variable *pArr2d, to mean that the variable points to what is outside of the brackets. You have int[3] outside of the brackets, so you have a variable that points to a data type that is int[3].

    This is consistent with a pointer to a function, let's say for example:

    char (*pfunc)(double,int);

    pfunc points to what it outside of the brackets, which is char ...(dounle, int), which is a function that accepts a double and int as parameters, and returns a char.

    Does this help any?

    Another thing that can perhaps help whoever needs a better understand of what is going on in situations like where balance wants a pointer that has the property that when it is incremented, it goes to the next row of the 2D array, instead of the next element in the current row:

    I think about all arrays as single dimension arrays. If it is a multi-dimension array, think of this variable as a single dimension array of type X (in which you don't know what X is, but you have an array of X's). In the case of the code above, X is an array of 3 ints. Now, when you delcare a pointer to point to this variable, and you wish to increment it row by row, you are really making a pointer to type X, and you are incrementing it one X at a time. Thus, you declare a pointer to type X, which is a pointer to an array of 3 ints, which is:
    int (*pArr2d)[3] = Arr2d;

    I hope I have not insulted anyone with my simplistic explanations, but this is how I think of it whenever things get confusing... which can happen a lot when dealing with multi-dimension arrays.
  24. #13
  25. No Profile Picture
    .
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2002
    Posts
    296
    Rep Power
    12
    How would that be possible? It sounds like you're asking for polymorphic behavior where the compiler has to read your mind to know whether when you increment the pointer you want it to move to the next element or jump to the next row.
    not (i'm refering to the mind reading bit) if you can somehow say "this pointer is for the base index" somehow, which is what:

    int (*pArr2d)[3] = Arr2d;

    looks like is exactly what it accomplishes. i'm pretty sure that is the answer. i've messed around with it a bit and it does seem to work. the thing that worried me was that it might be relying on the fact that the array was a constant one, therefore in one nice once defined block. but it seems to work with non constant arrays. haven't gone into that fully, but so far seems fine.

    also as far as the stepping along the base array's index, then changing direction and going along one of the secondary array's indexes you can use two different pointers like:
    Code:
    /* arraycontainingarrays: contains a handful of arrays each of 10 int elements */
    
    int (*pp)[10] = arraycontainingarrays;	/* the base array index pointer */
    int *p		/* for secondary array index pointer */
    
    pp++;
    pp++;
    pp++;	/* step along the base array index a few times to a certain point */
    
    p = *pp;	/* get secondary array pointer ready */
    
    p++;		/* 90 degree corner turn here. now stepping along secondary array index */
    p++;
    printf("%d\n", *p);	/* that would print the int in arraycontainingarrays[3][2] */
    yeah, so as far as your concern for the compiler knowing which index you intend to use, you just have different pointers. it would be good if you could somehow flick/switch the pointer rather than having to use another one... :/ whatever. maybe void would help that? probably shouldn't have said that because i have no idea.

    in any case, i think int (*pArr2d)[3] = Arr2d; does exactly what i was asking about and works great (from what i've seen so far). thanks v. much :)
  26. #14
  27. No Profile Picture
    Contributing User
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Feb 2001
    Posts
    1,473
    Rep Power
    15
    in any case, i think int (*pArr2d)[3] = Arr2d; does exactly what i was asking about and works great (from what i've seen so far).
    Ok, good to hear. That was in the other thread, and that's why I started off by saying you didn't read the other thread carefully enough. :)

    Does this help any?
    lol. Not really. I understand what the notation represents(see the previous couple of posts and the original thread), I was wondering about what happens internally in memory. However, the second part of the post was very helpful--thanks.
    Last edited by 7stud; May 26th, 2003 at 07:59 PM.
  28. #15
  29. No Profile Picture
    .
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2002
    Posts
    296
    Rep Power
    12
    Also, I'm not sure about the internals of this:

    int (*pArr2d)[3] = Arr2d;

    and how it works.
    it seems that the pointer is defined to know the size it's dealing with, just like when you declare a pointer to point at a double, it finds out how many bytes a double actually is, so then knows how much to jump by when you say ++ to it. but then the part i do not understand is what if the arrays that are contained in the array are not next to each other, in one nice long line? i'm still not sure if it does actually work with that or not. but then it should do really. if you've got an array containing arrays in each of it's elements, the base array *has* to know where the start of each of those arrays are otherwise arrays in arrays simply wouldn't work. when you say arrayname[2] (when arrayname contains arrays itself) you get the first element of the array in the 3rd element of arrayname without any question. so if it works for indexes, it should work for pointers. they're interchangeable right? i don't understand the internals of indexing (which is exactly the same thing here i think) either, but can still use them, sort of.

    The one thing I noticed is that you can say:

    pArr2d[0]

    which doesn't make sense to me, since pArr2d is not supposed to be an array of pointers like when declaring it this way:

    int* pArr2d[3];
    yeah but array names are addresses to their first elements.

    if onedarray is a 1d array, if you say:

    int *p;
    p = onedarray;

    or if you say

    int *p;
    p = &onedarray[0];

    both of those are exactly the same. p ends up with the same address - the first element of onedarray. the array name on it's own, without any indexes or anything, amounts to the address of it's first element.

    and if you've got arrays in an array, then arraycontainingarrays[3] amounts to an array name just like onedarray above. that's "arraycontainingarrays[3]" is an array name just like onedarray. it just happens to have [3] in it, but that's irrelevent - it's just part of the name. so when you refer to arraycontainingarrays[3] you're refering to the first element of the array named "arraycontainingarray[3]".

    bit hazy on the pointer aspect of pArr2d[0] put with the above description right now, but basically i think pArr2d[0] amounts to the first element of the array contained in Arr2d first element.





    ..a pointer that has the property that when it is incremented, it goes to the next row of the 2D array, instead of the next element in the current row:

    I think about all arrays as single dimension arrays
    well that's the reason i asked this question because if you couldn't have done int (*pArr2d)[3] = Arr2d; to allow stepping along the base array index, the thinking "all arrays are single dimension arrays" would not have held true really i don't think. what kind of an array is it, if you can't assign a pointer to one of it's elements and step along it by incrementing that pointer. but you can: int (*pArr2d)[3] = Arr2d;
    Last edited by balance; May 26th, 2003 at 08:32 PM.
Page 1 of 2 12 Last
  • Jump to page:

IMN logo majestic logo threadwatch logo seochat tools logo