Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Exercise 5-9 K&R

Reply
Thread Tools

Exercise 5-9 K&R

 
 
mdh
Guest
Posts: n/a
 
      08-03-2007
May I ask two questions relating to this exercise? ( asking to repeat
the example using pointers)

Given a 2-dimensional array:

char a[2][13] ( which is initialized in the exercise to represent days
of the month in a leap/non-leap year)

Part of the answer ( in Tondo and Gimpel) includes "assigning" a char
pointer to the correct "row" thus:

char *p
p = a[leap]; ( with "leap" either 0 or 1);

Question.

If "a" is "converted" to a pointer to element 0 of row 1, then a[1]
points p to element 0 of row 2? Is this the correct way of visualizing
this?

2nd question involves pointer arithmetic.
p is advanced using *++p.
In order to calculate the difference between a[leap] and the current
position of "p" the expression

*pmonth = p - *(a + leap ) is used. ( again, "leap" is 0 or 1)
( *pmonth is a ptr of type integer declared as such in the parameter
of the function)

Question:

I can see how p represents an address of the "pth" element of "a" and
that this should simply be the difference between 2 pointers.
However, the syntax

*(a + leap) is the one that is confusing to me. I thought the "*" is
the dereferencing operator, and as such, it should be (a + p) and
not *(a+p).

thanks in advance.

 
Reply With Quote
 
 
 
 
mdh
Guest
Posts: n/a
 
      08-03-2007
<I should have included the original code...sorry. Included below.>

May I ask two questions relating to this exercise? ( asking to repeat
the example using pointers)
Given a 2-dimensional array:

char a[2][13] ( which is initialized in the exercise to represent
days
of the month in a leap/non-leap year)

Part of the answer ( in Tondo and Gimpel) includes "assigning" a char
pointer to the correct "row" thus:

char *p
p = a[leap]; ( with "leap" either 0 or 1);

Question.

If "a" is "converted" to a pointer to element 0 of row 1, then a[1]
points p to element 0 of row 2? Is this the correct way of
visualizing
this?

2nd question involves pointer arithmetic.
p is advanced using *++p.
In order to calculate the difference between a[leap] and the current
position of "p" the expression

*pmonth = p - *(a + leap ) is used. ( again, "leap" is 0 or 1)
( *pmonth is a ptr of type integer declared as such in the parameter
of the function)

Question:

I can see how p represents an address of the "pth" element of "a" and
that this should simply be the difference between 2 pointers.
However, the syntax

*(a + leap) is the one that is confusing to me. I thought the "*" is
the dereferencing operator, and as such, it should be (a + p) and
not *(a+p).

thanks in advance.
>>>>>>>>

#include <stdio.h>

static char daytab[2][13]={
{0,31,28,31,30,31,30,31,31,31,30,31,30},
{0,31,29,31,30,31,30,31,31,31,30,31,30}
};


void month_day( int yearday, int year, int *pmnth, int *pday);

int main (int argc, const char * argv[]) {
int mnth, day;

printf("The Day of the year for \"12th Dec 1957\" is %d\n",
day_of_year(1957, 12, 12) );
month_day(228, 1957, &mnth, &day );
printf("The Day 228 of the year 1957 was day %d of month %d", day,
mnth);

return 0;
}


/* day_of_year*/

int day_of_year(int year, int month, int day){



int leap;
char *p;

leap = year % 4==0 && year % 100 != 0 || year %400 == 0;
p=daytab[leap];

while ( --month)
day += *++p;

return day;

}

/* set the month and day, from day of year */

void month_day( int yearday, int year, int *pmnth, int *pday){

int leap;
char *p;

leap= year % 4==0 && year % 100 != 0 || year %400 == 0;
p=daytab[leap];

while ( yearday > *++p)
yearday -= *p;

*pmnth = p -*(daytab+leap);
*pday = yearday;
}


 
Reply With Quote
 
 
 
 
Army1987
Guest
Posts: n/a
 
      08-03-2007
On Thu, 02 Aug 2007 20:06:31 -0700, mdh wrote:

> May I ask two questions relating to this exercise? ( asking to repeat
> the example using pointers)
>
> Given a 2-dimensional array:
>
> char a[2][13] ( which is initialized in the exercise to represent days
> of the month in a leap/non-leap year)
>
> Part of the answer ( in Tondo and Gimpel) includes "assigning" a char
> pointer to the correct "row" thus:
>
> char *p
> p = a[leap]; ( with "leap" either 0 or 1);
>
> Question.
>
> If "a" is "converted" to a pointer to element 0 of row 1, then a[1]
> points p to element 0 of row 2? Is this the correct way of visualizing
> this?

a is a char [2][13], which is converted to a char (* )[13].
Thus a + 1 points to the second char [13] in the array, that is
to the second row.
a[1], that is *(a + 1), is a char [13], which is converted to
a char * pointing to a[1][0]. Got it?
> 2nd question involves pointer arithmetic.
> p is advanced using *++p.
> In order to calculate the difference between a[leap] and the current
> position of "p" the expression
>
> *pmonth = p - *(a + leap ) is used. ( again, "leap" is 0 or 1)
> ( *pmonth is a ptr of type integer declared as such in the parameter
> of the function)
>
> Question:
>
> I can see how p represents an address of the "pth" element of "a" and
> that this should simply be the difference between 2 pointers.
> However, the syntax
>
> *(a + leap) is the one that is confusing to me. I thought the "*" is
> the dereferencing operator, and as such, it should be (a + p) and
> not *(a+p).

*(a + p) is the same as a[p]. Remember which a is an array [2] of
arrays [13] of chars, so it evaluates to a pointer to an array
[13] of chars. *(a + 0) = *a is the first line of a, that is a
char [13], and it evaluates to a pointer to its first element,
i.e. &a[0][0]. Similarly *(a + 1) is a[1], which evaluates to
&a[1][0].
--
Army1987 (Replace "NOSPAM" with "email")
"Never attribute to malice that which can be adequately explained
by stupidity." -- R. J. Hanlon (?)

 
Reply With Quote
 
mdh
Guest
Posts: n/a
 
      08-03-2007

> mdh wrote:
> >
> > char *p
> > p = a[leap]; ( with "leap" either 0 or 1);

>
> > Question.

>
> > If "a" is "converted" to a pointer to element 0 of row 1, then a[1]
> > points p to element 0 of row 2? Is this the correct way of visualizing
> > this?


Army1987 <army1...@NOSPAM.it> wrote:
>
> a is a char [2][13], which is converted to a char (* )[13].
> Thus a + 1 points to the second char [13] in the array, that is
> to the second row.
> a[1], that is *(a + 1), is a char [13], which is converted to
> a char * pointing to a[1][0]. Got it?



Yes...I think so. So, there are 2 "levels" of conversion? Is this
then true? Given that conceptually one can imagine this object ( char
a[2][13] ) as array 2 of 13 chars (each), calling the name "a"
converts to a pointer of type array 13 to char. Hence manipulating
this, whether by indexing or pointers will change the "row". Invoking
the name "a[]" converts to a char pointer, hence char *p is able to
access each individual character of a given "row"?

> > mdh wrote:
> > 2nd question involves pointer arithmetic.
> > p is advanced using *++p.
> >

>
> > Question:

>
> > I can see how p represents an address of the "pth" element of "a" and
> > that this should simply be the difference between 2 pointers.
> > I thought..... it should be (a + p) and not *(a+p).

>


Got it...just the reverse of the above.
Thanks.

BTW...great quote !

> "Never attribute to malice that which can be adequately explained
> by stupidity." -- R. J. Hanlon (?)



 
Reply With Quote
 
Army1987
Guest
Posts: n/a
 
      08-05-2007
On Fri, 03 Aug 2007 09:32:54 -0700, mdh wrote:
> Army1987 <army1...@NOSPAM.it> wrote:
>>
>> a is a char [2][13], which is converted to a char (* )[13].
>> Thus a + 1 points to the second char [13] in the array, that is
>> to the second row.
>> a[1], that is *(a + 1), is a char [13], which is converted to
>> a char * pointing to a[1][0]. Got it?

>
>
> Yes...I think so. So, there are 2 "levels" of conversion?

Depends on what you mean.
a is a char [2][13] and gets converted to a char (*)[13].
*a is a char [13] and gets converted to a char *.
But the fact that you can write **a does NOT mean that a is ever
converted to a char **. If an implementation had different sizes
for pointers to pointers and pointers to arrays, sizeof(a + 0)
would return the former. Also you could not assign a to a char **.
**a works because it binds as *(*a), and *a has type char [13]
before conversion and char * after conversion.
Similarly, the fact that you can write
#include <stdio.h>
int main(void)
{
(
*******
* * *
* * *
* * *
* * * * *
* * *
*******
puts)("Peace!");
return 0;
}
doesn't mean puts is ever converted to a 31th-level pointer to
function returning int and taking a const char *.
 
Reply With Quote
 
mdh
Guest
Posts: n/a
 
      08-05-2007
On Aug 5, 4:01 am, Army1987 <army1...@NOSPAM.it> wrote:
>
> > Yes...I think so. So, there are 2 "levels" of conversion?

>
> Depends on what you mean.
> a is a char [2][13] and gets converted to a char (*)[13].
> *a is a char [13] and gets converted to a char *.


I think I had a "minor" break-through in understanding here, thanks to
your help. It involves understanding the issue of "type" and realizing
how important it is ( wrt pointers) to "pointer arithmetic"...and that
is the part that I was missing.

This really clarifies the ability to access each "character" in a row
by using:

char *p;
p=a[1] or p=a[0]; etc etc

( Well, I hope it clarifies it...else it's back to the drawing
board!!!!).

Thanks very much for your help.

 
Reply With Quote
 
Joe Wright
Guest
Posts: n/a
 
      08-05-2007
mdh wrote:
> <I should have included the original code...sorry. Included below.>
>
> May I ask two questions relating to this exercise? ( asking to repeat
> the example using pointers)
> Given a 2-dimensional array:
>
> char a[2][13] ( which is initialized in the exercise to represent
> days
> of the month in a leap/non-leap year)
>
> Part of the answer ( in Tondo and Gimpel) includes "assigning" a char
> pointer to the correct "row" thus:
>
> char *p
> p = a[leap]; ( with "leap" either 0 or 1);
>
> Question.
>
> If "a" is "converted" to a pointer to element 0 of row 1, then a[1]
> points p to element 0 of row 2? Is this the correct way of
> visualizing
> this?
>
> 2nd question involves pointer arithmetic.
> p is advanced using *++p.
> In order to calculate the difference between a[leap] and the current
> position of "p" the expression
>
> *pmonth = p - *(a + leap ) is used. ( again, "leap" is 0 or 1)
> ( *pmonth is a ptr of type integer declared as such in the parameter
> of the function)
>
> Question:
>
> I can see how p represents an address of the "pth" element of "a" and
> that this should simply be the difference between 2 pointers.
> However, the syntax
>
> *(a + leap) is the one that is confusing to me. I thought the "*" is
> the dereferencing operator, and as such, it should be (a + p) and
> not *(a+p).
>
> thanks in advance.
> #include <stdio.h>
>
> static char daytab[2][13]={
> {0,31,28,31,30,31,30,31,31,31,30,31,30},
> {0,31,29,31,30,31,30,31,31,31,30,31,30}
> };
>
>


Thirty days hath September, April, June and November. All the rest have
31 save February which has 28 or 29.

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
 
Reply With Quote
 
mdh
Guest
Posts: n/a
 
      08-05-2007

>
> > static char daytab[2][13]={
> > {0,31,28,31,30,31,30,31,31,31,30,31,30},
> > {0,31,29,31,30,31,30,31,31,31,30,31,30}
> > };

>
> Thirty days hath September, April, June and November. All the rest have
> 31 save February which has 28 or 29.
>



oops...well...wasn't really the gist of the issue...but point taken.

 
Reply With Quote
 
Richard Heathfield
Guest
Posts: n/a
 
      08-05-2007
Joe Wright said:

> mdh wrote:
>> <I should have included the original code...sorry. Included below.>
>>
>> May I ask two questions relating to this exercise? ( asking to repeat
>> the example using pointers)
>> Given a 2-dimensional array:
>>
>> char a[2][13] ( which is initialized in the exercise to represent
>> days
>> of the month in a leap/non-leap year)
>>
>> Part of the answer ( in Tondo and Gimpel) includes "assigning" a char
>> pointer to the correct "row" thus:
>>
>> char *p
>> p = a[leap]; ( with "leap" either 0 or 1);
>>
>> Question.
>>
>> If "a" is "converted" to a pointer to element 0 of row 1, then a[1]
>> points p to element 0 of row 2? Is this the correct way of
>> visualizing
>> this?
>>
>> 2nd question involves pointer arithmetic.
>> p is advanced using *++p.
>> In order to calculate the difference between a[leap] and the current
>> position of "p" the expression
>>
>> *pmonth = p - *(a + leap ) is used. ( again, "leap" is 0 or 1)
>> ( *pmonth is a ptr of type integer declared as such in the parameter
>> of the function)
>>
>> Question:
>>
>> I can see how p represents an address of the "pth" element of "a" and
>> that this should simply be the difference between 2 pointers.
>> However, the syntax
>>
>> *(a + leap) is the one that is confusing to me. I thought the "*" is
>> the dereferencing operator, and as such, it should be (a + p) and
>> not *(a+p).
>>
>> thanks in advance.
>> #include <stdio.h>
>>
>> static char daytab[2][13]={
>> {0,31,28,31,30,31,30,31,31,31,30,31,30},
>> {0,31,29,31,30,31,30,31,31,31,30,31,30}
>> };
>>
>>

>
> Thirty days hath September, April, June and November. All the rest
> have 31


With you so far.

> save February which has 28 or 29.


No no no, it's:

"...Saving February alone,
Which hath 28 days clear,
And 29 in each leap year."

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      08-06-2007
Richard Heathfield <> writes:
> Joe Wright said:

[...]
>> Thirty days hath September, April, June and November. All the rest
>> have 31

>
> With you so far.
>
>> save February which has 28 or 29.

>
> No no no, it's:
>
> "...Saving February alone,
> Which hath 28 days clear,
> And 29 in each leap year."


Thirty days hath September;
All the rest I don't remember.

Or maybe it's:

Thirty days hath September,
April, June, and November.
All the rest have thirty-one,
Save for February, which has none.

--
Keith Thompson (The_Other_Keith) kst- <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
tree functions daily exercise: Range Xah Lee Java 12 06-22-2005 08:51 AM
Cisco Student VPN exercise problem : gen_unrfrag: fail to generate unreachable, unexpected args robert Cisco 0 06-02-2004 07:33 PM
2154 module 4 Exercise 2 Drew Brown MCSE 0 10-22-2003 02:47 AM
Exercise needed for java 2 programmer test lonelyplanet999 Java 1 09-30-2003 10:37 AM
Re: Development best practices and knowing when to exercise control over development Kevin Spencer ASP .Net 2 08-06-2003 09:33 PM



Advertisments
 



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 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57