---
# System prepended metadata

title: OOP Midterm solutions

---

OOP Midterm solutions
===
Contributed by < `25077667` >
Date: 2020/10/29
Creative Commons [CC-BY-3.0](https://creativecommons.org/licenses/by/3.0/tw/)


* What are the three main characteristics of oop, in English?
    * Encapsulation
    * Inheritance
    * Polymorphism

---

* Given the following C++ program, which of the declarations on lines 3 and 4 is an initialization and which is an assignment?
```cpp=
int main()
{
    int a = 1;
    int b = a;
}
```
Both are initialization.

---

* What would be the output of the following C++ program? What are the mechanisms used by C++ to call each of the three functions f, g, and h?
```cpp=
#include <iostream>
using std::cout;
using std::endl;

void f(int x, int y)
{
    int t = x; x = y; y = t;
}

void g(int *x, int *y)
{
    int t = *x; *x = *y; *y = t;
}

void h(int& x, int& y)
{
    int t = x; x = y; y = t;
}

int main()
{
    int a = 1, b = 2;
    f(a, b);
    cout << a << ", " << b << endl;
    g(&a, &b);
    cout << a << ", " << b << endl;
    h(a, b);
    cout << a << ", " << b << endl;
    return 0;
}
```
Output:
> 1, 2
> 2, 1
> 1, 2

Mechanisms:
```void f(int  x, int  y)```
> pass by value of a variable

```void g(int *x, int *y)```
> pass by value of a pointer

```void h(int &x, int &y)```
> pass by reference

---

* What's output?
```c=
#include <stdio.h>

int f(int i)
{
    static int v = 1;
    int t = v;
    v += i;
    return t;
}

int main()
{
    int i;
    for (i = 1; i <= 8; i <<= 1)
        printf("%d\n", f(i));
    return 0;
}
```
> 1
> 2
> 4
> 8

---

* Use typedef to declare “foo” as an array of 3 pointers to functions taking as input an integer and returning as output an integer in a single declaration in C++.
```cpp
typedef int (*foo[3])(int);
```
or
```cpp
using foo = int (*[3])(int);
```


---

* Define an integer variable “`a`” in C++ so that it can only be seen in the file at which it is defined.

```cpp
static int a;
```
or
```cpp
namespace { int a; }
```

---

* Define in a single declaration in C++ a pointer to integer “p” so that p[1] is an alias of a[0], p[2] is an alias of a[1], and so on, all the way up to p[128] is an alias of a[127] for the integer array “int a[128];” defined in C++.

```cpp
auto p = a - 1;
```
or
```c
int *p = a - 1;
```

---

* What's output?
```c=
#include <stdio.h>
#define SQUARE(x) x*x
int main()
{
    printf("%d\n", SQUARE(1+2*3)*SQUARE(3+4*5));
    return 0;
}
```
> 105

---

* What is (most) wrong with the C++ function `f` below?
```cpp=
static int i = -1;
int *f()
{
    int a[10];
    for (i = 0; i < 10; i++) {
        a[i] = i;
    }
    return a;
}
```

> Return a local variable of an array (dangling pointer). It would cause a segfault as a signal `SIGSEGV` while accessing the value of the returned pointer.

---

* What is (most) wrong with the C++ function `g` below?

```cpp=
#include <stdlib.h>
#include <string.h>

char *g()
{
    char *d = (char *) malloc(128);
    char *s = "Now is the time...";
    strcpy(d, s);
    free(s);
    return d;
}
```

> `free` the [.rodata](https://pic1.xuehuaimg.com/proxy/csdn/https://img-blog.csdnimg.cn/20200519103314194.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2FjZGVmZ2hi,size_16,color_FFFFFF,t_70). It will cause a `SIGABRT` in runtime immediately.

---

* What's output?
```c=
#include <stdio.h>
int main()
{
    int i = 55555;
    printf("%08X\n", * (unsigned int *) &i);
    i = -i;
    printf("%08X\n", * (unsigned int *) &i);
    return 0;
}
```
The output
> 0000D903
> FFFF26FD

Explain:
> Please read the format string rules.

[Format string wiki](https://zh.wikipedia.org/wiki/%E6%A0%BC%E5%BC%8F%E5%8C%96%E5%AD%97%E7%AC%A6%E4%B8%B2)

---

* What's output?
```c=
#include <stdio.h>
int main()
{
    float i = 55555;
    printf("%08X\n", * (unsigned int *) &i);
    i = -i;
    printf("%08X\n", * (unsigned int *) &i);
    return 0;
}
```
The output
> 47590300
> C7590300

---

* What's output?
```cpp=
#include <iostream>
using std::cout;
using std::endl;
int main()
{
    int a = 100;
    cout << ++a-- << endl;
    return 0;
}
```
The output
```
error: lvalue required as increment operand
    7 |  cout << ++a-- << endl;
      |             ^~

```

---

* What's output?
```cpp=
#include <iostream>
using std::cout;
using std::endl;
int main()
{
    int a[10][20][30][40][50];
    cout << a[1]-a[6] << endl;
    cout << a[1][1]-a[6][6] << endl;
    return 0;
}
```
The output
> -100
> -3150

For the first line:
> 20 pointers for each `a[i]`, a[1] to a[6] crossing 5 `a[i]`, 5 * 20 = 100, but a[1] is lower than a[6] in memory space, hence a[1]-a[6] is negative.

For the second line:
![](https://i.imgur.com/c9CthD7.png)

> Form the a[1][1] black dot to a[6][6] black dot.
> each box has 30 elements.

$(19+20 \cdot 4+6) \cdot 30 = 3150$

---

* What's output
```cpp=
#include <iostream>
using std::cout;
using std::endl;
#define MIN(a,b) (((a) < (b))? (a) : (b))
int main()
{
    int x = 7, y = 8;
    int m = MIN(x++, y++);
    int n = MIN(++x, ++y);
    cout << m << " " << n << endl;
    return 0;
}
```
The output:
> 8 11

Explian:
Just be careful the macro is extending the expression rather than calling a function call.

---

* Use typedef to declare "foo" as an array of 10 pointer to functions taking as input two constant generic pointer and returning an integer in C++
```cpp
typedef int (*foo[10])(const void *, const void *);
```

or
```cpp
using foo = int (*[10])(const void *, const void *);
```

---

* Define in C++ a pointer that points to the element `a[5][10]` of the array "`int a[10][20][30][40];`" named p.

```cpp
auto p = &a[5][10];
```
or
```cpp
int (*p)[30][40] = &a[5][10];
```

---

* In C++, when is the default constructor automatically generated by the compiler?

> §11.4.3 Special member functions 
Default constructors (11.4.4.1), copy constructors, move constructors (11.4.4.2), copy assignment operators, move assignment operators (11.4.5), and prospective destructors (11.4.6) are special member functions. 
>> [Note: ==The implementation will implicitly declare these member functions for some class types when the program does not explicitly declare them.== The implementation will implicitly define them if they are odr-used (6.3) or needed for constant evaluation (7.7). — end note] 
>> 
> An implicitly-declared special member function is declared at the closing } of the class-specifier. Programs shall not define implicitly-declared special member functions.

ref: [C++20 std](https://isocpp.org/files/papers/N4860.pdf)

---

* What is the difference between struct and class in C++.
> All `struct`'s members are public by defualt.
> All `class`'s members are private by default. Except for the special member functions.

---
* What is the difference between a pointer and the name of an array in C++?

Array is a pointer to a address for some spaces of contigous memory.
Pointer is a pointer to a memory address.

$Array = Pointer$
$Array \not\equiv Pointer$

For example:
```cpp=
int arr[10];
sizeof(arr);     // 40
sizeof(&arr);    // 8 in 64-bit machine
```
:::info
還沒讀完：
[C++17 standard](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4713.pdf)
[Array declaration](https://en.cppreference.com/w/cpp/language/array)
[Value category](https://en.cppreference.com/w/cpp/language/value_category)
> About prvlaue, xvalues, rvalue expressions...


:::

---

* What would be the output of the following C++ program? Why?

```cpp=
#include <iostream>
using namespace std;
class A {
public:
	A(int i) : v(i) { cout << "A::A(" << i << ") called" << endl; }
	~A() { cout << "A::~A() called" << endl; }
	operator bool() { return v != 0; }
private:
	int v;
};

int main() {
	int i = 1;
	while (A a = i) {
		i = 0;
	}
	return 0;
}
```
Output:
> A::A(1) called
> A::~A() called
> A::A(0) called
> A::~A() called

Explain:
`A a = i` is an initialization of `A` to `a`.
And the `v(i)` of the constructor `A(int i) : v(i) {...}` is also an initialization of the variable `v` for `int` type.

---

* What is the major difference between a reference parameter and a constant reference parameter?

We cannot modify the constant reference parameter's value in compile time.
But non-const could.
:::info
NOTE: We can use the [buffer overflow](https://en.wikipedia.org/wiki/Buffer_overflow) or some [special hijacking method](https://accu.org/journals/overload/28/156/harrison_2776/) to modify any variable or function in run time.
:::

---

* Give the definition of the special member functions and their names as we discussed in the classroom that would in some circumstances be implicitly defined by a C++ implementation for a class, say, C, as given below.
```cpp=
struct C {
    std::string s;
};
```
Sol: 
:::spoiler
```cpp=
C() : s() {}                     // default ctor
~C() {}                          // dtor
C(const C &_a) : s(_a.s) {}      // copy ctor
C(C &&_a) : s(std::move(_a.s)) {}// move ctor
C &operator=(const C &_a) {      // copy assignment operator
    if (&a != this)
        s = _a.s;
    return *this;
}
C &operator=(C &&_a) {           // move assignment operator
    if (&a != this)
        s = std::move(_a.s);
    return *this;
    
}
```
The implementation will implicitly declare these member functions for some class types when the program does not explicitly declare them.
:::

