Vous êtes sur la page 1sur 4

CS 341 / Fall 2016

Quiz #1: Wednesday, September 14th


Name: ______ SOLUTION KEY ___________________ LAST 4 DIGITS OF ID: ____________

Multiple Choice / Short Answer (20 points)

Assume V is a list<double>, which is a linked-list. The linked-list contains the values 42.5, 11.9, and 18.2 (in
that order). Consider the following C++ code fragment:

auto X = V.begin();
auto Y = V.end();
auto E1 = *X;
auto E2 = *Y;
auto PI = 3.14;

1) What is X? Circle the best answer. [ 4 pts ]


a) X is 42.5 c) X is an iterator denoting 42.5
b) X is a pointer to 42.5 d) X is a pointer to an iterator to 42.5

2) What is E1? Circle the best answer. [ 4 pts ]


a) E1 is 42.5 c) E1 is an iterator denoting 42.5
b) E1 is a pointer to 42.5 d) E1 is undefined because *X is illegal

3) What is E2? Circle the best answer. [ 4 pts ]


a) E2 is 18.2 c) E2 is an iterator denoting 18.2
b) E2 is a pointer to 18.2 d) E2 is undefined because *Y is illegal

4) The auto keyword denotes type inference in C++. Is the type of the variable PI known at compile-time, or
does C++ wait until run-time to compute the type? Circle your answer: compile-time / run-time

5) Javascript is a dynamic programming language. What does this mean? How does this impact execution
time and memory usage? [ 4 pts ]

In a dynamic programming language, language-related decisions are delayed until run-time. A good
example is type-checking. In dynamic languages, the types of variables do not need to be specified by the
programmer. Instead, types are determined and checked during execution. While flexible and less
work for the programmer, this increases execution time because type-checking is done as part of program
execution. This also increases memory usage, because data must also contain type information.

Page 1 of 4
Lambda Expressions (30 points)

6) Consider the following code fragment, which compiles and runs without error:

std::vector<int> V = {80, 0, 19, 46, 11, -2, 14};


std::set<int> S = {0, 14, 31, 46, 78, 80, 99};

auto R = std::count_if(V.begin(), V.end(),


[&](int x)
{
auto iter = std::find_if(S.begin(), S.end(),
[=](int y)
{ return x == y; }
);

return iter != S.end();


}
);

a) When std::count_if is called, what are the values of x? In other words, what is the value of x each time
the associated lambda expression is called? [ 6 pts]

80, 0, 19, 46, 11, -2, 14

b) When std::find_if is called the 1st time, what are the values of y? In other words, what is the value of y
each time the associated lambda expression is called? [ 6 pts]

0, 14, 31, 46, 78, 80, 99

c) For the values of V and S shown above, what is the value of R when execution completes? [ 6 pts ]

d) Suppose V contains N elements and S contains M elements. What is the time complexity of this code
fragment? [ 6 pts ]

O(N * M)

e) Suppose the [&] was changed to [=]. Does the code still work? Circle your answer: Yes / No

f) Continuation of previous question if you circled Yes, the code still works, then explain why [&] was
used. If you circled No, the code does not work, explain why changing [&] to [=] broke the code.

The [&] was used for efficiency the lambda expression needs the set S, and [=] would copy S each time.
The [&] allows S to be captured by reference, i.e. only a pointer to S is copied each time.

Page 2 of 4
Object-Oriented Programming (20 points)

7) Consider the following class definitions in C++:

class Course class Student


{ {
public: public:
int CrsNum; //111,141,151 int UIN;
int Grade; //4,3,2,1,0 (A,B,) std::vector<Course> Courses;
int Hours; //# of credit hours
Student(int uin)
Course(int N, int G, int H) : UIN(uin)
: CrsNum(N), Grade(G), Hours(H) { }
{ } void AddCourse(int N, int G, int H)
}; { }
double GPA()
{ }
int TotalCreditHours()
{ }
};

a) Implement the AddCourse function, which inserts the given course data into the Courses vector.

void Student::AddCourse(int N, int G, int H)


{
Course C(N, G, H);
Courses.push_back( C );
}

b) Implement the TotalCreditHours function, which returns the total # of credit hours in the Courses
vector. However, note that if the grade is a 0 (i.e. F), the credit hours for that course dont count.
Half-credit if you use a range-for loop, full credit if you use built-in C++ function(s) instead of a loop.

int Student::TotalCreditHours()
{
std::vector<int> hours( Courses.size() ); // create target vector:

std::transform(Courses.begin(), Courses.end(), hours.begin(),


[](const Course& C)
{
if (C.Grade > 0) // passed the class, so hours count:
return C.Hours;
else // failed, hours dont count:
return 0;
}
);

return std::accumulate(hours.begin(), hours.end(), 0);


}

Page 3 of 4
Memory (30 points)

8) Consider the following program, with a simplified Student class & 2 functions F and main:

class Student
{
public:
int UIN;
std::vector<char> Grades;

Student(int uin)
: UIN(uin)
{ }
};

void F(std::vector<int>& V2,


Student *X)
{
Student S(33);
S.Grades.push_back('A');

/* point A */
}

int main()
{
std::vector<int> V;
V.push_back(9);
V.push_back(12);

Student *S;
S = new Student(22);

F(V, S);

Draw the state of memory (stack and heap) when execution reaches point A --- draw your answer above and
to the right. Label the name of each memory cell as appropriate, and include the contents of each memory
cell if known; draw ? if the contents are unknown.

[ For std:: vector, assume an implementation similar to that discussed in class/book, with 3 values: elem, space, and
last. Also assume that when a std::vector is first constructed, an underlying array of capacity 4 is created. Finally,
assume that std::vector provides a copy constructor that performs a deep copy. ]

Page 4 of 4

Vous aimerez peut-être aussi