![]() |
|
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 |
|
Newbie
Join Date: Sep 2004
Posts: 29
Rep Power: 0
![]() |
Confusion With Pointers and Arrays
Ok, Pointers confuse the heck out of me, and pointers to arrays only make things worse.
Right now, I've got a number of two dimensional arrays of structures where one of the elements of the structure is a string array. On startup, depending on the configuration of the system, only one of the arrays will be used. I need to handle this by using a pointer to point to that array. Basically I have no clue how to set up that pointer to correctly point to that array. Here is an example of my situation: // The structure (INT8U is an unsigned 8 bit character)
typedef struct
{
INT8U ID;
INT8U AnotherValue;
INT8U NameString[20];
} ITEM_DEFINE_t;
// The first array
ITEM_DEFINE_t FirstItemDefinitionArray[2][4] =
{
{
{0, 1, "First Item"},
{1, 1, "Second Item"},
{2, 1, "Third Item"},
{3, 1, "Fourth Item"},
},
{
{0, 2, "First Item"},
{1, 2, "Second Item"},
{2, 2, "Third Item"},
{3, 2, "Fourth Item"},
}
};
// The second array
ITEM_DEFINE_t SecondItemDefinitionArray[2][4] =
{
{
{0, 3, "First Item"},
{1, 3, "Second Item"},
{2, 3, "Third Item"},
{3, 3, "Fourth Item"},
},
{
{0, 4, "First Item"},
{1, 4, "Second Item"},
{2, 4, "Third Item"},
{3, 4, "Fourth Item"},
}
};
// Ok this is one part of the problem.
// How do I define the pointer to correctly reference the array?
ITEM_DEFINE_t **ItemPointer;
// This is the next part.
// How do I correctly set the pointer to reference the array?
ItemPointer = SecondItemDefinitionArray;
// The final part, and the part that I have the least problem with
// How do I correctly reference a member in the structure that the pointer is pointing too?
printf ("%s", ItemPointer[1][1]->NameString);Any help would be hugely appreciated. Like I said, Pointers confuse me to no end. |
|
|
|
|
|
#2 |
|
Battle Programmer
Join Date: Feb 2006
Location: Bellevue, WA, USA
Posts: 770
Rep Power: 3
![]() |
I'd recommend reading either Narue's tutorial or Dawei's tutorial. If you can spare the time, read both
![]() |
|
|
|
|
|
#3 |
|
Newbie
Join Date: Sep 2006
Posts: 5
Rep Power: 0
![]() |
I think a quick tutorial is in order. Its not that hard just getting to understand the syntax for a novice can be hard. Here I go.
I will start with a 1 dimensional array. A string will do as I am not feeling too creative tonight. #include <stdio.h>
int main()
{
char MyArray[] = "Hello World";
//To get to the fist element using the [] notation you would do this
printf("%c\n", MyArray[0]);
//That would print n, but what if i wanted to use a pointer to
//do the same thing
printf("%c\n", *(MyArray));
//That will produce the same result as before printing a "H"
//Now what if i wanted to get to the second character(second index)
printf("%c\n", MyArray[1]);
printf("%c\n", *(MyArray + 1));
//All i did here was add one to the address and C is smart enough to
//move the pointer along to the start of the next value. It does not matter
// if the size of each element is one byte or 10 bytes it will always work.
}So that was one dimensional arrays, but what if you want two dimensions #include <stdio.h>
int main()
{
char MyArray[3][3] = {
{'1', '2', '3'}
{'4', '5', '6'}
{'7', '8', '9'}
};
//First lets look at the address of MyArray
printf("%p\n", MyArray);
//Now lets look at the adress of MyArray[0][0]
printf("%p\n", &MyArray[0][0]);
//Now lets see what is in MyArray[0]
printf("%p\n", MyArray[0]);
//If you run that code what will be printed?
//They will all print the same memory address as simple a 2D array
// is just an array of arrays.
//Take a look at the values in MyArray
printf("%c\n", MyArray[0][0]);
printf("%c\n", *MyArray[0]);
printf("%c\n", **MyArray);
//This should all print 1 as they all refer to the same location.
}So this is all the ways to get at the elements in MyArray MyArray[0][0] = *MyArray[0] = **MyArray MyArray[0][1] = *(MyArray[0]+1) = *(*MyArray+1) MyArray[0][2] = *(MyArray[0]+2) = *(*MyArray+2) MyArray[1][0] = *(MyArray[0]+3) = *(*MyArray+3) = *MyArray[1] MyArray[1][1] = *(MyArray[0]+4) = *(*MyArray+4) = *(MyArray[1]+1) MyArray[1][2] = *(MyArray[0]+5) = *(*MyArray+5) = *(MyArray[1]+2) MyArray[2][0] = *(MyArray[0]+6) = *(*MyArray+6) = *MyArray[2] = *(MyArray[1] + 3) MyArray[2][1] = *(MyArray[0]+7) = *(*MyArray+7) = *(MyArray[2]+1) = *(MyArray[1] + 4) MyArray[2][2] = *(MyArray[0]+8) = *(*MyArray+8) = *(MyArray[2]+2) = *(MyArray[1] + 5) So you can see the pattern and how it works. I will leave it for someone else to make some contrive example for a 2D array. ![]() If i have made a silly error then please feel free to kill me :p Last edited by synchronized; Sep 8th, 2006 at 6:56 PM. |
|
|
|
|
|
#4 | |
|
Hobby Coder
Join Date: May 2006
Posts: 58
Rep Power: 0
![]() |
Quote:
Pointers are wonderful, and very powerful, but if they're leading you into great confusion, just use them very sparingly. When you're working with a 2d array, pointer notation in your code does NOT help it's clarity, one bit. Array[2]2], is infinitely clearer than any other notation, including pointer. Adak |
|
|
|
|
|
|
#5 | |
|
Programming Guru
![]() Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 5
![]() |
Quote:
c Syntax (Toggle Plain Text)
JawaKing00 appears to understand the fact that a 2D array is simply an array of arrays, and he comprehends that a pointer can be assigned to an array. What he slips up on is to assume that arrays and pointers are the same thing. The correct approach can be inferred by DaWei's excellent and knowledgable guide to pointers. However, as far as I can see, the correct way of pointing to a 2D array is ever explicitly mentioned, so I'll mention it now. This is partially for JawaKing00's benefit, partially for mine; if I'm incorrect, I'd like to know about it! c Syntax (Toggle Plain Text)
|
|
|
|
|
|
|
#6 |
|
Programming Guru
![]() Join Date: Jun 2005
Location: Adelaide, South Australia
Posts: 1,260
Rep Power: 5
![]() |
The relationship between pointers and arrays trips everyone up sometime. Heck, I typed a response to a question about passing multi-dimensional arrays to functions a couple of days back, and got it wrong too (that was at the end of a stressful couple of weeks, which started with undergoing knee surgery and then the pain of recovery and physiotherapy to get walking again). I can't find the thread at the moment, but I think Narue corrected my error.
The links to both Narue's and Dawei's tutorials given above are good, and should be read over and over again. They both cover the key issues quite well, although they are written in different styles that may suit different people. As Arevos has said, arrays are different things from pointers. However, C treats pointers and arrays as equivalent (i.e. interchangeable) in some contexts. A pointer is a variable that can contain the address of another variable. For example, a pointer to int can contain the address of an int. For example; int main()
{
int x;
int *px = &x; /* px contains the address of x */
*px = 2; /* sets x to be 2 */
}int main()
{
int array[5];
int *px = x; /* px contains the address of x[0] */
*px = 2; /* sets x[0] to be 2 */
*(px + 1) = 5 /* sets x[1] to be 5 */
px[1] = 5; /* does exactly the same thing as the previous line */
}int main()
{
int *px; /* px is an uninitialised pointer */
*px = 2; /* sets the value pointed at by px to be 2 */
px[0] = 2; /* same as previous line */
}Multi-dimensional arrays are where this breaks down. A multi-dimensional array is an array of arrays, but (as of the 1989 C standard) it is not equivalent to a pointer to a pointer. In some contexts, it can be treated as a pointer to an array. For example; int main()
{
int x[3][4]; /* an array of 3 arrays of 4 ints */
int (*px)[4]; /* a pointer to an array of 4 ints */
px = x; /* OK; px is now an alias for x */
px[1][2] = 5; /* Sets x[1][2] to be 5 */
}Where things get a little squirrelly (and can trip up people - like myself - who used C before there was a standard) is that pre-standard versions of C did not recognise an array as a distinct type, so allowed an implicit conversion of an "array of array" to "pointer to pointer". That caused a lot of headaches for programmers (as compilers would not complain about some of those conversions when they really should have, and the program would simply crash for no obvious reason). One of the great services done by the committee that produced the 1989 C standard was that they disallowed this conversion. The trade-off is that most things relating to multi-dimensional arrays in C are difficult to get right, because compilers complain bitterly if the syntax is not "just so". But a whining compiler is much better for a programmer sanity than code which "looks right, compiles OK, but crashes for the end user": end users tend to complain more loudly than compilers. |
|
|
|
|
|
#7 | |
|
Newbie
Join Date: Sep 2004
Posts: 29
Rep Power: 0
![]() |
Quote:
I still don't quite understand why, though. I read through both of those tutorials, and I do have a passing knowledge of pointers and arrays, but sometimes they just make my head hurt. I get that that is a pointer to an array of structures, but why is there only one dimension? Wouldn't c Syntax (Toggle Plain Text)
Also, why do we need to use the '.' and not '->' when accessing a member of the structure in that array? I thought when using a pointer, that the '->' notation was used, but again that doesn't work. Finally, why do we initialize the pointer as the whole array and not the address of the array? I would expect something like c Syntax (Toggle Plain Text)
c Syntax (Toggle Plain Text)
I guess my inexperience with pointers to arrays is showing here, but I'd like to know more about the reasoning behind this. Especially since I'll probably need to explain it to the lead engineer on the project, since he doesn't appear to fully understand this implementation either ![]() Thank you again for all the help. It has been incredibly useful. |
|
|
|
|
|
|
#8 | |
|
Programming Guru
![]() Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 5
![]() |
Quote:
c Syntax (Toggle Plain Text)
c Syntax (Toggle Plain Text)
c Syntax (Toggle Plain Text)
Your array contains ITEM_DEFINE_t, and not ITEM_DEFINE_t*, which is why you need a . and not a ->. |
|
|
|
|
|
|
#9 |
|
Resident Grouch
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Jun 2005
Posts: 6,453
Rep Power: 10
![]() |
If you want to see the difference between an array name used as a pointer, and the usage of a pointer to the same array, simply write the two instructions (which look identical) and examine the emitted assembly code. In many cases the compiler babies us (at the cost of some confusion). After all, we all know we can't assign to arrays, but we all write char myStuff [] = "ABC";.
![]()
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code. Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers |
|
|
|
|
|
#10 |
|
Programming Guru
![]() Join Date: Jun 2005
Location: Adelaide, South Australia
Posts: 1,260
Rep Power: 5
![]() |
Dawei, an assignment for you: write on the blackboard 100 times "Dawei should not tell lies". |
|
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Arrays, Pointers, and Constants | JawaKing00 | C | 4 | May 31st, 2006 2:19 PM |
| strings, pointers, arrays | bl00dninja | C++ | 21 | Mar 15th, 2006 9:02 AM |
| n00b question(s) about arrays, pointers, and functions | keweedsmo | C++ | 8 | Feb 9th, 2006 2:46 PM |
| Pointers in C (Part II) | Stack Overflow | C | 2 | Apr 29th, 2005 11:39 AM |
| Pointers in C (Part I) | Stack Overflow | C | 4 | Apr 28th, 2005 8:03 PM |