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; }