### Thread: 2d array. indexes to pointers.

1. No Profile Picture
.
Devshed Newbie (0 - 499 posts)

Join Date
Dec 2002
Posts
296
Rep Power
16

#### 2d array. indexes to pointers.

(i meant converting indexes to pointers)

i'm really stuck on this exercise. part of the reason i'm stuck is that i'm not sure to what extent pointers should be used.

exercise: rewrite the routines dayofyear and monthday with pointers instead of indexing:
Code:
```static char daytab[2][13]={
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};

/* dayofyear: set day of year from month and day */
int dayofyear(int year, int month, int day)
{
int i, leap;

leap = year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
if(day < 1 || day > daytab[leap][month])
return 0;			/* invalid input */
for(i=1; i < month; i++)
day += daytab[leap][i];
return day;
}

/* monthday: set month, day from day of year */
void monthday(int year, int yearday, int *pmonth, int *pday)
{
int i, leap;

leap = year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
if(yearday < 1 || yearday > 365+leap) {
*pmonth=*pday=0;		/* invalid day input */
return;
}
for(i=1; yearday > daytab[leap][i]; i++)
yearday -= daytab[leap][i];
*pmonth = i;
*pday = yearday;
}```
so both functions use the fact that the leap variable will be set to 0 or 1 depending if it's a leap year or not and use the 0 or 1 to directly access the correct array within daytab. (daytab is a 2 dimensional array, obviously).

does the answer to the exercise, do you think, require access to both levels of that array with pointers, or does it require you to use pointers to access only one of the levels, while still using indexes for the other?

when i say levels i mean
level 1: one of the two arrays (which are made up of 13 elements each)
level 2: one of the 13 elements

i've got a feeling from the wording of the exercise, both levels (i'm sure that's not the correct word but not to worry) should be accessed with pointers? but i can't see how to do that at all.

if it turns out to be only one level should be accessed by pointers, and the other remaining accessed by indexing, that won't be too much of a problem for me (i don't think, apart from i don't know which of the two levels).

if someone could give me a small hint setting me off in the right direction on this, rather than the final answer, it'd be great. :)
Last edited by balance; February 27th, 2003 at 09:21 AM.
2. No Profile Picture
Contributing User
Devshed Beginner (1000 - 1499 posts)

Join Date
Feb 2001
Posts
1,481
Rep Power
19
You can use pointer notation to get at any element of the array but it's a little complicated:

*(*(daytab + i) + j)

This is how my book explains it:

daytab refers to the address of the first row of the array, so daytab + i refers to row i of the array. The expression *(daytab + i) is the address of the first element of row i, so *(daytab + i) + j is the address of the element in row i with the offset j. Dereferencing the whole expression therefore gives you the value of that element. Unless you have good reason for referencing the elements of an array in this way, it is best avoided.

Personally, I don't understand that explanation because of the statement:

"The expression *(daytab + i) is the address of the first element of row i."

To me it seems that would be the value of the first element of row i. I didn't know you could dereference a pointer and get an address, although if you have a pointer to a pointer, I guess that would make sense.
Last edited by 7stud; February 27th, 2003 at 02:14 PM.
3. Thank you for that "*(*(daytab + i) + j)". I hadn't seen it before.

Originally posted by 7stud
Personally, I don't understand that explanation because of the statement:

"The expression *(daytab + i) is the address of the first element of row i."

To me it seems that would be the value of the first element of row i. I didn't know you could dereference a pointer and get an address, although if you have a pointer to a pointer, I guess that would make sense.
"char daytab[][]" is equivalent to "char **daytab". "*(daytab + i) only dereferences it one level, making it a (char *) instead of a char. You need that second deference to get to the element itself.

A good article on pointers, which I cannot find on the Web, is "Pointer Power in C and C++" by Christopher Skelly, C Users Journal, Feb & Mar 1993 (a two-part article). In it, he goes through multiple-level referencing and dereferencing and how to properly decipher a complex declaration. The articles might still be available in some college/university libraries. Skelly was 71005.771@compuserve.com .

Another good handout we got was taken from (I seem to recall) the Schaum Outline "Programming in C", chapter 10. Leafing through it just now, I spotted them using the "*(*(daytab + i) + j)" notation you had just given.
4. No Profile Picture
.
Devshed Newbie (0 - 499 posts)

Join Date
Dec 2002
Posts
296
Rep Power
16

yeah your first answer still had a [] in - that's what i was trying to get at with my level talk. still using one set of []'s i'd describe as only using pointers for one level while remaining using indexing for the other level. but now your new answer is what i'd call both levels with pointers which i haven't digested properly yet, but will do. thanks v. much. :)
5. No Profile Picture
Contributing User
Devshed Beginner (1000 - 1499 posts)

Join Date
Feb 2001
Posts
1,481
Rep Power
19
"yeah your first answer still had a [] in - that's what i was trying to get at with my level talk. still using one set of []'s i'd describe as only using pointers for one level while remaining using indexing for the other level."

After posting, I realized that wasn't what you were after, so I did a little more digging(...turned to the next page), and I found the all pointer method.

dwise1_aol,

Thanks for the info.
6. No Profile Picture
.
Devshed Newbie (0 - 499 posts)

Join Date
Dec 2002
Posts
296
Rep Power
16
I realized that wasn't what you were after
well i'm not sure - it's not what i was after, but what the exercise was after. that's partly what i was unsure of.

*(*(daytab + i) + j) seems a much better, more coprehensive answer to that exercise, but then from your book:
Unless you have good reason for referencing the elements of an array in this way, it is best avoided.
so maybe not.

the 2 pointers like that do roughly make sense to me though - it reflects the fact that a 2 dimensional array is actually one array whose elements are arrays. *(*(daytab + i) + j) is a pointer within a pointer.

when i first came to do the exercise i thought the first thing that needed to be done was to alter the way the daytab array is setup, like this at the start:

static char *daytab...

but i couldn't get anything like that to work. i think there may be a solution via that route too. but inanycase your 2 pointers works fine. thanks.
7. No Profile Picture
Contributing User
Devshed Beginner (1000 - 1499 posts)

Join Date
Feb 2001
Posts
1,481
Rep Power
19
My book also says that using what it calls a mix of pointer notation and an index value is not recommended either:

*(daytab[0] + j)

which is the mehtod I originally posted, though I find that method very easy to follow. That only leaves one method my book approves of:

daytab[i][j]

which is what your exercise started with.
8. No Profile Picture
.
Devshed Newbie (0 - 499 posts)

Join Date
Dec 2002
Posts
296
Rep Power
16
but then i've read that generally using pointers to deal with arrays is more efficient than the indexing method.

i don't see why either of those pointer versions should not be used. does your book say why? is it just because they're so damn confusing? they'd be right with that, if that is the case.

here's a bit from the book i'm reading that helps me understand why *(*(daytab + i) + j) works:

by definition, the value of a variable or expression of type array is the address of element zero of the array. thus after the assignment...
pa = &a[0];
...pa and a have identical values. since the name of an array is a synonym for the location of the initial element, the assignment pa=&a[0] can also be written as:
pa = a;
so basically the array name used without any indexes is the address of it's first element. that's talking about a 1 dimensional array. so i guess if you're dealing with a 2 dimensional array, array[3] for example is the address of the first element of the array that's in array[3]

what i'd like to know is, if using pointers to access an array is more efficient, is:

*(*(daytab + i) + j)

more efficient than:

*(daytab[i] + j)

seeing as *(daytab[i] + j) appears to be half pointers and half indexing? i'm going to guess that *(*(daytab + i) + j) is more efficient.

also i mentioned that i thought there might another way to tackle this by modifying the way the array is initialised in the first place. well i found some other people's solutions to this exercise here: http://www.trunix.org/programlama/c/kandr2/krx509.html
look at the 2nd person's solution - in particular the way the daytab array is setup. i don't actaully fully understand it but that does definetely appear to be another way of tackling this kind of thing. - defining the array as an array of pointers, or it's partly that.
9. Originally posted by balance
what i'd like to know is, if using pointers to access an array is more efficient, ...
I think that most of us can only repeat what we've been taught in class or by our mentors.

I'm afraid that only way to really find out is to write a few examples -- ie, accessing with indices and the same thing with pointers and perhaps even a mixture of pointers and indices -- and examine the assembly code that the compiler generates.

Both gcc, g++, and VC++6 have compiler options for generating an assembly source file. I found VC++6 a bit easier to use because it also includes the original C++ source code as comments so it's easier to see which lines of assembly correspond to which lines of C++ code.