April 19, 2010

1.
The following code belongs to a member function belonging to a class
`date`

that has exactly one data member,
`int day`

.
What does the following code do to
`day`

?
Find a simpler and faster way to do the same thing.
Don’t worry about anything you do or don’t do to
`initial_year`

.
`initial_year`

is never used again, so anything you do or don’t do to it
doesn’t matter.

for (day = initial_day; initial_year > 0; day += 365) { --initial_year; }

2.
The following member function belongs to a class
`date`

that has exactly one data member,
`int day`

.
It forgot to check for a negative remainder,
but at least it works correctly for a non-negative remainder.
And the reason it works is because the length of December
(`date_length[12]`

)
just happens to be equal to the length of January
(`date_length[1]`

).
Would the
`if`

statement still work even if December and January were different lengths?
If not, make it work.

Extra credit:
eliminate the
`if`

statement.
Make the code work without the special case for New Year’s Eve.

void date:print() const { int m = 1; div_t qr = div(day, 365); int y = qr.quot; int d = qr.rem; for (; d > date_length[m]; ++m) { d -= date_length[m]; } if (d == 0) { //if d==0, then we are 1/0/yy, so we need to go back one day d = date_length[1]; m = 12; --y; } cout << m << "/" << d << "" << y; }

3.
The following constructor puts the correct values into the data members
`year`

,
`month`

,
`day`

.
But it makes a copy of the structure whose address is returned by
`localtime`

.
Copying the structure may be expensive—or outright dangerous,
in a multi-threaded environment.

Put the same values into the data members,
but
*without*
copying the structure.
And while you’re at it,
do not use the same name for a standard library function
(`time`

)
and a local variable
(`time`

).

date::date() { time_t t = time(0); tm time = *localtime(&t); day = time.tm_mday; month = time.tm_mon + 1; year = time.tm_year + 1900; }

4.
The following member function belongs to a class
`date`

that has exactly one data member,
`int day`

.
It contains four copies of the statement

day -= date_length[month];Replace the first and second copies with a single copy of the same statement at a different location in the member function. Replace the third and fourth copies with a single copy of the same statement at a different location in the member function.

Are the two loops identical?
If so, consolodate them, i.e., write the loop once and for all in one place.
Are the two copies of
`year +=`

and
`day +=`

identical?
Consolidate as much as you can of them.

void date::next(int count) { div_t d = div(count, 365); if (d.rem >= 0) { year += d.quot; day += d.rem; while (day > date_length[month]) { if (month > 11) { day -=date_length[month]; month = 1; ++year; }else { day -= date_length[month]; ++month; } } } else { year += d.quot -1; day += d.rem + 365; while (day > date_length[month]) { if (month > 11) { day -=date_length[month]; month = 1; ++year; }else { day -= date_length[month]; ++month; } } } }

5.
The following member function belongs to a class
`date`

that has exactly three data members,
`year`

,
`month`

,
`day`

.
Is the function short enough to be inline?
Should it be
`const`

?

void date::print() { cout << month << "/" << day << "/" << year; }

6.
The following member function belongs to a class
`date`

that has exactly three data members,
`year`

,
`month`

,
`day`

.
Does the following variable
`m`

stay alive even after the loop is over?
Should it
stay alive even after the loop is over?
If so, why?
If not, keep it alive only as long as the loop is in progress.

int date::julian() const { int i = day; int m = month - 1; for (; m > 0; --m) { i += date_length[m]; } return i; }

7.
The following member function belongs to a class
`date`

that has exactly three data members,
`year`

,
`month`

,
`day`

.
It copies the three data members into three local variables named
`temp_y`

,
`temp_m`

,
`temp_d`

,
performs a calculation, and then copies the answer from the three
local variables back into the three data members.

Remove the three local variables. Perform the calculation using the original data members themselves.

The member function also copies the quotient and the remainder
from
`d.quot`

and
`d.rem`

into two local variables named
`quotient`

and
`remainder`

.
Remove these two local variables as well.
Perform the calculation using the original
`d.quot`

and
`d.rem`

.

What is the maximum number of times we can go around the first
`while`

loop?

void date::next(int count) { div_t d = div(count, 365); int quotient=d.quot; int remainder=d.rem; int temp_m=month; int temp_d=0; int temp_y=0; while(remainder<0) { remainder+=365; --quotent; } temp_d=day+remainder; temp_y=year+quotient; while (temp_d > date_length[temp_m]) { temp_d -= date_length[temp_m]; temp_m++; if (temp_m > 12) { temp_m = 1; ++temp_y; } } day=temp_d; year=temp_y; month=temp_m; }

8.
What does the following
`if`

statement actually check for?
The data member
`p`

is a pointer to an
`int`

.

//Pop a value off the stack. int stack::pop() { if (*p == 0) { //underflow cerr << "Can't pop when size " << *p << " == 0.\n"; exit(EXIT_FAILURE); } return a[--(*p)];

9.
The same class
`stack`

as the above problem.
What is the value of the
`p`

in the loop?
Now consider the local variable
`p`

created after the loop is over.
What is it used for and when is it destroyed?

stack::stack(const stack& another) { for (size_t i = 0; i < p - another.a; ++i) { a[i] = another.a[i]; } int *p; p = a; }

10.
What does the following code do?
Find a shorter, less repetitious way to do it.
What purposes was served by changing the order of the statements mentioning
`year`

and
`count`

?

if (d.rem < 0) { d.rem += 365; --d.quot; year += d.quot; //year before count count = d.rem; } else { count = d.rem; //count before year year += d.quot; }

11.
Given the following class
`date`

,

class date { int year; int month; int day; public: date(int initial_year, int initial_month, int initial_day { year = initial_year; month = initial_month; day = initial_day; } void next(int count = 1); void print() const {cout << month << "/" << day << "/" << year;} }; void date::next(int count) { div_t d = div(count, 365); if (d.rem < 0) { d.rem += 365; --d.quot; year += d.quot; count = d.rem; } else { count = d.rem; year += d.quot; } while (count > 0) { if (count > date_length[month]) { ++month; count -= date_length[month]; } else { ++day; --count; } if (day > date_length[month]) { day = 1; if (month == 12) { month = 1; ++year; } } } }

what is the output of the following statements?

int main() { date d(1, 31, 2010); //January 31, 2010 d.next(); //Go one day forward. d.print(); //Should print February 1, 2010 cout << "\n"; return EXIT_SUCCESS; }

12.
The following member function belongs to a class
`date`

that has exactly three data members,
`year`

,
`month`

,
`day`

.
Should it be
`const`

?
How many times do we go around the first loop?
What is the value of
`count_month`

after the first loop has finished?
Find a simpler way to put the same value into
`count_month`

.

Can the
`if`

statement ever be false?
If so, give an example of values for the three data members
that would make the
`if`

false.
If not, remove the word
`if`

(although not necessarily the body of the `if`

).
How many times do we go around the second loop?
How much does the second loop add to
`jul_date`

?
Find a simpler way to add the same amount to
`jul_date`

.
Then eliminate the variable
`count_month`

.

int date::julian() { int jul_date = 0; int count_month = 0; for (int i = 1; i < month; i++) { jul_date += date_length[i]; ++count_month; } //now add the remaining days of the last month to compute the julian date for (int i = 1; i <= day; i++) { if (i <= date_length[count_month + 1]) { ++jul_date; } } return jul_date; }