Question #1
Write down the output of the following program segment. Getting the first,
second and third output lines correct are worth 6, 7 and 7 marks respectively.
You may use the next page as well. Hint: to receive partial marks, in
case you get the output wrong, you probably want to indicate what the four
pointers are pointing to after each line.
int a = 1, b = 2, c = 3,
*p1, *p2,
**pp1, **pp2;
p1 = &c;
p2 = &a;
pp1 = &p2;
pp2 = &p1;
if (**pp2 == *p1 + a) {
cout << "TRUE" << endl;
} else {
cout << "FALSE" << endl;
}
**pp1 = **pp2 - a;
*pp1 = p2;
*p1 = *p2 + a;
cout << "FIRST: " << a << ' ' << b << ' ' << c << endl;
*pp2 = &b;
p1 = *pp1;
**pp1 = **pp2 - *p1;
cout << "SECOND: " << a << ' ' << b << ' ' << c << endl;
| Assgn. |
a |
b |
c |
p1 |
p2 |
pp1 |
pp2 |
*pp1 |
*pp2 |
| p1 = &c |
1 |
2 |
3 |
&c |
? |
? |
? |
? |
? |
| p2 = &a |
. |
. |
. |
. |
&a |
? |
? |
? |
? |
| pp1 = &p2 |
. |
. |
. |
. |
. |
&p2 |
? |
p2 |
? |
| pp2 = &p1 |
. |
. |
. |
. |
. |
. |
&p1 |
. |
p1 |
| **pp1 = **pp2 - a |
2 |
. |
. |
. |
. |
. |
. |
. |
. |
| *pp1 = p2 |
. |
. |
. |
. |
. |
. |
. |
. |
. |
| *p1 = *p2 + a |
. |
. |
4 |
. |
. |
. |
. |
. |
. |
| *pp2 = &b |
. |
. |
. |
&b |
. |
. |
. |
. |
. |
| p1 = *pp1 |
. |
. |
. |
&a |
. |
. |
. |
. |
. |
| **pp1 = **pp2 - *p1 |
0 |
. |
. |
. |
. |
. |
. |
. |
. |
HENCE, the output is:
FALSE
FIRST: 2 2 4
SECOND: 0 2 4
Question #2
Dynamic Memory Allocation & Arrays
Write a function with prototype int** alloc(int n, int m), which
allocates a 2n * m matrix, which has the property that the value a[i][j]
== a[i+n][j], or in other words, the ith and (i+n)th
rows are identical. Moreover, this property is intrinsically imposed by the
structure. For example, for n=2 and m=3, a 4 * 3 structure
is created
int **a = alloc(2,3);
a[0][0] = 1; a[2][1] = 2; a[2][2] = 3;
a[1][0] = -1; a[3][1] = -2; a[1][2] = -3;
// a[0][0] == 1 a[0][1] == 2 a[0][2] == 3
// a[1][0] == -1 a[1][1] == -2 a[1][2] == -3
// a[2][0] == 1 a[2][1] == 2 a[2][2] == 3
// a[3][0] == -1 a[3][1] == -2 a[3][2] == -3
You may assume that neither n nor m are 0. Hint: start
with part 3, you do not even need 10 lines.
int** alloc(int n, int m) {
int** a= new int*[2*n];
for(int i=0; i< n; i++) {
a[i] = new int[m];
a[i+n] = a[i];
}
return a;
}
Write a function with prototype void dealloc(int** a, int n),
which deallocates the 2n * m (m irrelevant}) structure passed in
a and allocated by alloc. You may assume that neither m
nor n are 0. Hint: start with part 3, you do not even need 10
lines.
void dealloc(int** a, int n) {
for(int i=0; i< n; i++) {
delete [] a[i];
}
delete [] a;
}
Draw a diagram which shows how such a 4 * 3 structure with n =
2 and m = 3 is arranged in memory. You may assume any pointer and
integer size and make up addresses, but do indicate what addresses are stored in
the pointers.
Question #3
Logical errors.
Would the following function swap the values of x and y?
Explain!
void swap(int *a, int *b) {
int *c = a;
a = b;
b = c;
}
int x,y;
swap(&x,&y);
NO! The pointer variables a and b are
created on the stack when swap gets called. a holds &x
and b holds &y. After the body of swap is
executed, a holds &y and b holds &x.
However, a and b are destroyed when the function is finished,
the values in x and y have not been touched.
Find one error in the following program segment, and describe what
it is. Hint: there are no syntax errors!
int* f() {
int *a = new int;
*a = 5;
return a;
// a has the address of a dynamically allocated
// piece of memory, OK
}
int& foo1(int* (*func)()) {
return *(func());
// as far as, func returns the
// address of a global variable
// or one on the heap, OK
}
int& foo2() {
int x = foo1(f);
// x is a local variable
return x;
// retrurning a local variable by
// reference is a serious mistake
// pp 42 in your notes
}
...
cout << foo2() << endl; // dereferencing the local x!!
...
Question #4
Consider the following class definition, method and function implementations :
class C {
public:
C();
C(int);
C(const C&);
C& operator=(const C&);
~C();
};
C foo(C c) {
return c;
}
C::C() { cout << "C::C()" << endl; }
C::C(int) { cout << "C::C(int)" << endl; }
C::C(const C&) { cout << "C::C(const C&)" << endl; }
C& C::operator=(const C&) { cout << "C::operator=" << endl; return *this; }
C::~C() { cout << "C::~C()" << endl; }
Answer the question posed on the following page.
Give the output of the following short code segment, and explain briefly but
clearly what caused each line to be printed! Hint: the two lines
are in a local scope!
...
{
C c1(5),c2;
c1 = foo(c2);
}
...
C::C(int) - for c1
C::C() - for c2
C::C(const C&) - creating the copy of c2 on the stack
(passed by value)
C::C(const C&) - returning the copy of foo's local c
(returned by value)
C::~C() - foo ends, c destroyed
C::operator= - for the assignment
C::~C() - the C object returned by foo
C::~C() - for c2, scope ends
C::~C() - for c1, scope ends
Question #5
Write a program with one function. The function takes an integer array
and its length and it returns an integer. The value returned is the smallest
positive value in the array, or 0 if all values are negative or if the length of
the array is 0. Call this function in main with an array that you
declared and initialized to perform this task.
#include < iostream.h >
int small_pos(int *a, int l) {
int smp = 0;
for(int i=0; i < l; i++) {
if (a[i] > 0) {
if (smp == 0 || a[i] < smp) smp = a[i];
}
}
return smp;
}
int main() {
int a[4] = {2,-4,1,0};
cout << a[0] << ' ' << a[1] << ' ' << a[2] << ' ' << a[3] << endl;
cout << "smallest positive: " << small_pos(a,4) << endl;
return 0;
}