Sunday, April 29, 2012

10.2


What if we wrote an increment procedure in C as follows (remove the parentheses around *x):

void inc (int* x)
{ *x++;
}

Is this legal? If so, what does this procedure do? If not, why not?

Yes, this is legal. It increments the value that x points to

9.35

Test each of the following C/C++ code fragments with a translator of your choice (or rewrite it into another language and test it) and explain its behavior:

(a)
{
int i, n = 3;
for( i = 1; i <= n; i++)
{
printf("i = %d\n, i");
n = 2;
}

the loop runs twice and prints "i = 1" the first time through and "i = 2


(b)
int j;
for(j = 1; j <= 3; j++)
{
printf("j = %d\n", j);
j = 3;
}

it returns "j = 1", then exits the loop

9.34

C++ and java loops are often written with empty bodies by placing all side effects into the tests, such as in the following two examples:

i = 0
while (a[i++] != 0);

for (i = 0; a[i]  != 0; i++);



(a) Are these loops equivalent?
if a[0] is 0, the while loop will not run once. the for loop will run at least once

(b) Are there any advantages or disadvantages to using this style of code? Explain.
It makes it more concise, but can make it more difficult to read

9.31

Here is a legal switch-statement in C/C++

int n = ...;
int q = (n +3) / 4;
switch (n % 4)
{
case 0: do { n++;
case 3: n++;
case 2: n++; 
case 1: n++; 
}while (--q > 0);
}



Suppose that n has the value (a) 0; (b) 1; (c) 5; (d) 8. What is the value of n in each case after the execution of the above switch-statement? Can you state a general rule for the value of n after this code executes? If so, state it. If not, explain why not.

(a) 0
n = 4

(b) 1
n = 2

(c) 5
n = 10

(d) 8 
n = 16

General rule:


if(n>0) output = 2*n
if(n==0) output = 4
if(n<0) output = n

9.22

Show how to imitate a while-statement in C/C++ with a for-statement.


for(int i = 0; i < 2; i++)
{
//stuff inside while loop
if(whilecondition=true)
i=0;
else
i=2;
}

Saturday, April 28, 2012

9.21

Show how to imitate a for-statement in C/C++ with a do-statement.


int x = 0;
do
{
cout << y << endl;
y = y - 1;
x++;
}
while(x <= 10);



9.20

Show how to imitate a while-statement in C/C++ with a do-statement.

int dowhile = 5;
do
{
if (dowhile > 0 == true)
{
cout << dowhile << endl;
dowhile--;
}
else break;
}
while(true);


9.10

Suppose that we were to try to write a short-circuit version of and in C as the following function:

Int and (int a, int b)

{
return a ? b : 0
}



(a) Why doesn't this work?

It will evaluate both terms no matter what, which is not short circuiting

9.4

In LISP the following unparenthesized prefix expression is ambiguous:

+ 3 * 4 5 6

It is ambiguous because there are multiple interpretations

Two possible expressions could be.

Expression 1

LISP: ( + 3 (* 4 5 6))

Real Math: (4 * 5 * 6) + 3 = 123

Expression 2

LISP: ( + 3 (* 4 5) 6)

Real Math: (4 * 5) + 3 + 6 = 29

8.47

Given the following C++ declarations,


double* p = new double(2);
void* q;
int* r;


which of the following assignments does the compiler complain about?


q = p;
p = q;
r = p;
p = r;
r = q;
r = (int*)q;
r = static_cast<int*>(q);


r = static_cast<int*>(p);
r = reinterpret_cast<int*>(p);

Try to explain the behavior of the compiler. Will *r ever have the value 2 after one of the assignments to r? Why?

q is void, and so assigning it p is fine
r = reinterpret_cast<int*>(p) forces the conversion regardless of types


the rest produce errors as follows:

p = q                                       cannot convert from void* to double*
r = p                                        cannot convert from double* to int*
p = r                                        cannot convert from int* to double*
r = q                                        cannot convert from void* to int*
r = (int*)q                                q is being used without being initialized
r = static_cast<int*>(q)         q is being used without being initialized
r = static_cast<int*>(p)         cannot convert from double* to int*


r should have the value of 2 after r = reinterpret_cast<int*>(p)

8.31

Write a polymorphic max function in C++ that takes an array of values of any type and returns the maximum value in the array, assuming the existence of a ">" operation


#include <iostream>
using namespace std;


template <typename T>
T max(T x[], int size)
{
T max x[0];
for(int i=0; i<size;i++)
{
max = (x[i]>max)?x[i]:max;
}
return max;
}


template <typename T>
T max(T x[], int size, bool (*gt)(T,T))
{
T max = x[0];
for(int i=1;i<size;i++)
{
max = (*gt)(x[i],max)?x[i]:max;
}
return max;
}


int main()
{
char temparray[4] = {'a','c','f','d'};
cout << max(temparray, 4);
system("Pause");
return 0;
}

8.15

Suppose we used the following C++ code that attempts to avoid the use of a static_cast to print out the internal value of true( see code at end of Sec 8.7)


union
{
    int i;
    bool b;
} x;
...
x.b = true;
cout << x.i << endl;


Why is this wrong(Hint: try assignment x.i = 20000 before x.b = true)


x.i is not initialized, and so will return garbage

8.5

In C,
int x[10];
int y[10];


Why will the statement x = y not compile?


x = y will not compile because the name of an array passes the address of the first element of an array, not the values stored in the array.  In order to copy the array, the assignment statement should be as follows


for(int i=0, i<10, i++)
    {
           x[i] = y[i];
    }

8.3


(a) The Boolean data type may or may not have an order relation (pg332), and it may or may not be convertible to integral types (pg350), depending on the language. Compare the treatment of the Boolean type in at least two of the following languages with regards to these two issues: Java, C++, Ada, ML.

In Java, boolean is a primitive data type.
In Ada, the boolean type is an enumeration type.In C++, the boolean type is a Numeric type. In Java and C++, 0 represents false, while all positive nonzero values evaluate to true. The boolean can be used before or after an operator. Booleans can be cast as integers in both languages, and when doing so, false => 0 and true => 1

(b) Is it useful for booleans to be ordered? convertible to integers?
If booleans were not ordered, they might not be consistently convertible to integers. It is useful to convert booleans to integers for use of booleans in calculations more concisely

7.33

Here is a legal C program with a function variable:


Figure 7.45




Compare lines 6 and 8 of this code to the equivalent code of Figure 7.45 (lines 1 and 3). Why is this version of the code permitted? Why is it not required?

The function fun_var at line 6 is allowed because it has the same parameters as the gcd function it points to, and is essentially a pointer, and so it can store the address of another function with the same parameters

7.32

Why is the following C code illegal?

{
   int x[3];
   x = (int *) malloc(3*sizeof(int));
   ...
}

x is an array, which stores an address. this is the same thing as trying to assign something to an "address of" statement

7.31

Why is the following code illegal?


{
int x;
&x = (int *) malloc(sizeof(int));
...
}

Assignments cannot be made to an "address of" statement

7.26

Given the following C program, draw box- and-circle diagrams of the variables after each of the two assignments to **x (lines 11 and 15). Which variables are aliases of each other at each of those points? What does the program print?


#include <stdio.h>


main()
{
int **x;
int *y;
int z;
x = (int**) malloc(sizeof(int*));
y = (int*) malloc(sizeof(int));
z = 1
*y = 2;
*x = y;
**x = z;
printf(%d\n",*y);
z = 3;
printf("%d\n",*y);
**x = 4;
printf("%d\n,z);
return 0;
}


After 11: All 3 variables are aliases


After 15: y and z are aliases




The program prints 1, then 3, then 4

7.14

The following program prints two integer values; the first value typically is garbage ( or possibly 0, if you are executing inside a debugger or other controlled environment), but the second value might be 2. Explain why.


#include  <stdio.h>


void p(void)
{
int y;
printf("d\n", y);
y = 2;
}

int main()
{
p(); p();

return 0;
}

The first value will be garbage or 0 because y has been instantiated but not initialized.  The second value printed may be 2 because the value of y has by then been initialized to 2, and so may keep its value for the second printf.

Wednesday, April 25, 2012

8.7

Given the following variable declarations in C/C++


int (*f) (int);
int (*g) (int);
int (*h) (char);


the assignment f = g is fine in C and C++ but the assignment h = g generates a compiler warning in C and a compiler error in C++. Explain


f and g are the same type, whereas h and g are different types. An integer will not fit in the space allocated for a char, and so the compiler complains

Saturday, April 21, 2012

7.1

For the languages C and Java, give as precise binding times as you can for the following attributes. Explain your answers.


(a) The maximum number of significant digits in a real number

language implementation time

(b) The meaning of char

language definition time

(c) The size of an array variable

Given the existence of both static and dynamic arrays, this could be either compile or run time

(d) The size of an array parameter

compile time

(e) The location of a local variable

C: load time (static binding)

Java: run time

(f) The value of a constant

C: compile time


Java: compile time or load time, depending on whether or not the "static" keyword is specified

(g) The location of a function

C: load time unless it is declared virtual, in which case it will be bound at run time

Java: either load time or run time