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