CS441 Midterm- 2

taxidermistplateSoftware and s/w Development

Nov 7, 2013 (3 years and 10 months ago)

98 views

CS441 Midterm
-

2


Name:

1.

Answer the following questions concerning programming languages:

a.

Why do you suppose that
variable
-
length argument lists

are so seldom supported
by high
-
level programming languages?

The variables
-
length arguments are against to st
rong coupling and also make the
optimization difficult.

b.

What purpose(s) do types serve in a programming language? What does it mean
for a language to be
strongly typed
?
Statically typed
? What prevents, say C or
C++, from being strongly typed? Name two impo
rtant programming languages
that are strongly but dynamically typed.

Types keep track of a variable and how is it modified. When no application of an
operator to arguments can lead to a run
-
time type error, language is strongly typed.
If
type rules are enf
orced strongly (that is, generally allowing only those automatic type
conversions which do not lose information), the process is called
strongly typed
, if
not,
weakly typed
.

With statically
-
typed languages, there usually are pre
-
defined
types for individua
l pieces of data (such as numbers within a certain range, strings of
letters, etc.), and programmatically named values (variables) can have only one fixed
type, and allow only certain operations: numbers cannot change into names and vice
versa.

C, C++ sup
port void pointers which should be changed to a type( typecaseted) before
using it


which is violation on strongly typed. The explicit type cast allow
coversions of types .

The programming languages which are strongly but dynamically typed are: Python
an
d

P
erl.

c.

In what ways may an enumeration type be preferable to a collection of named
constants? In what ways may a subrange type be preferable to its base type? In
what ways may a string be preferable to an array of characters?

When the named constants are
really in order like days in a week or they have
any relation to previous type and could be collected in a logic sequence, then
enumeration is the best way representing such a collection of named constants.

Using subrange range checking is done in compile
time rather than runtime.

If the operations to performed on strings instead on the chars of a string ( like
strcat and changing the case of a string) then strings are preferred.



d.

Explain the difference between
type conversion
,
type coercion
, and
nonconver
ting type casts
.

If the type of a variable is converted to another type (like narrowing and broadening)
is called type conversion. Type coercion is for implicit operand type conversions.
The non
-
converting type casts is when change of type without altering

the underlying
bits.

e.

What is the difference between a
pointer

and an
address
? What are dangling
references? How are they created, and why are they a problem? Discuss the
comparative advantages of
tombstones

and
locks and keys

as a means of solving
the pro
blem.

Pointer holds the address of another variable. A pointer has address too. If a pointer
points to an address, which is no longer valid, it is called a dangling reference.

f.

What’s the difference between an activation record and an activation record
ins
tance?

An activation record is the data used by the subroutine while it is active that is not the
subroutine’s code. An activation record instance is the data for a particular call to a
subroutine

g.

What are the two steps in locating a nonlocal variable in a

static
-
scoped language
with stack
-
dynamic local variables and nested subprograms?

o

Find the correct activation record instance

o

Determine the correct offset within that activation record instance

h.

What’s the two potential problems with the static chain metho
d?

1.

A nonlocal reference is slow if the number of scopes between the reference and
the declaration of the referenced variable is large

2.

Time
-
critical code is difficult, because the costs of nonlocal references are not
equal, and can change with code upgrades

and fixes

i.

What are the differences between the deep access and shallow access methods of
implementing dynamic scoping?

Deep Access
-

nonlocal references are found by searching the activation record
instances on the dynamic
chain.
Length of chain cannot be

statically determined
Every activation record instance must have variable names

In case of shallow access names and values are stored in a global table. Using this
method, space is allocated for every variable name that is in the program(one space
for var
iable temp though there might be several declarations of temp in the different
methods). When a sub
-
routine is called it saves the current value of the variable and
replaces it with the value in its current scope and restores the value of the variable
whil
e exiting.


2.

consider the following C program:

int fun (int *i) {


*I += 5;


return 4;

}

void main () {


int x = 3;


x = x + fun(&x);

}

What is the value of x after the assignment statement in main?

a.

If operands are evaluated left to right

b.

If operands are ev
aluated right to left

a.

x = 3 + 4 = 7

b.

x = 8 + 4 = 12


3.

Given the following Java
-
like code, what is the output of the program when each of the
following scoping rules is applied? Explain your answers.

a.

Static scope

b.

Dynamic scope

public class A {

int x = 0;

voi
d fa() {

int x = 1;

fb();

}

void fb() {

println("x = " + x)

}

public static void main(String[] args) {

new A().fa();

}

}


Suggested Solution



Static Scope: The output is 0, since the variable x is declared as an instant variable
of class A which is initiali
zed to 0.



Dynamic Scope: The output is 1, since the local variable x of method fa() is closer
to the method fb() on the system stack when the prinln() statement is executed at
runtime


4.

Consider the following skeletal C program.

void fun1(void) {

int b, c,
d;

// call another function

}

void fun2(void) {

int c, d, e;

// call another function

}

void fun3(void) {

int d, e, f;

// call another function

}

void main () {

int a, b, c;

// call another function

}

Given the following calling sequences and assuming that

dynamic scoping is used, what
variables are visible during execution of the last function called? Include with each
visible variable the name of the function in which it was defined.

a.

main calls fun2; fun2 calls fun3; fun3 calls fun1.


(b, c, d: fun1; e,
f: fun3; a: main)

b.

main calls fun3; fun3 calls fun1.


(b, c, d: fun1; e, f: fun3; a: main)

c.

main calls fun1; fun1 calls fun3; fun3 calls fun2.


(c, d, e: fun2; f: fun3; b: fun1; a: main)

d.

main calls fun3; fun3 calls fun2; fun2 calls fun1.


(b, c, d: fun1: e
: fun2; f: fun3; a: main)

5.

Pointer and reference type

(a)

For a language with which you are familiar that provides a
pointer type

for
programmer
-
constructed data objects and operations such as
new

and
delete

(or
similar), which allocate and free storage for obj
ects, write a code sample that
generates
garbage

(i.e., useless objects that keep occupying memory space). Then,
write a code sample that generates a
dangling reference
.

Suggested Solution:



(b)

In your selected language, suggest programming techniques that

could diminish the
risk of generating garbage and dangling references. What language constructs in your
selected language can be used to support your techniques (if any)?

Suggested Solution

C# is one such language which does automatic garbage collection.
It is based on a
usage approach that the unreferenced space and not usable space are freed up.

Further reading: http://msdn.microsoft.com/library/default.asp?url=/library/enus/

dndotnet/html/dotnetGCbasics.asp


6.

Write (in a language of your choice or an app
ropriate pseudo
-
language) samples of
procedures or functions that will have different effects, depending on whether arguments
are passed
by value
,
by reference
,
by value/result
, or
by name
.

Let

s take examples of two swap functions

Void swap1(int x,int y)

{


int temp = x;



y = temp;


x= y;

}

Void swap2(int * x,int * y)

{


int temp = *x;



*y = temp;


*x= *y;

}

int main()

{


int x = 5,y=4;


swap1(x,y);


printf(“%d %d”,x,y); // prints 5 4 since this is pass by value


swap2(&x,&y);


printf(“%d %d”,x,y)
;


// prints 4 5 since this is pass by reference. The values in this case




// are stored in the address locations as indicated by &x and &y


}


7.

Consider the following program written in C syntax:

void main () {

i
nt value = 2, list[5] = {1, 3, 5, 7, 9};

swap (value, list[0]);

swap (list[0], list[1]);

swap (value, list[value]);

}

void swap (int a, int b) {

int temp;

temp = a;

a = b;

b = temp;

}

for each of the following parameter
-
passing methods, what are all of the

values
of the variables value and list after each of the three calls to swap?

a.

passed by value
:
The values remain the same

b.

passed by reference
:
value = 2 list= {3,1,5,7,9}

c.

passed by value
-
result
:

value = 2 list = {3,1,5,7,9}


8.

Some C puzzles involving
expr
ession evaluation and assignment
:

a.

What does this do:

int a=5, b=10;

f( (a,b) );

The inner expression uses the weird comma operator in C. The result of a
comma
-
separated list of expressions in C is the value of the rightmost expression.
So 10 (the value of
b) is passed to the function f (which presumably expects a
single int argument).



b.

One of these expressions is valid in C, the other is undefined. Explain.

int j=5;

if ( j++ == ++j ) ....

if ( j++ && ++j ) ...


Expressions involving two or more modificatio
ns to the same variable are
generally undefined in C. (There is an inscrutable definition for this in the
Standard involving the concept of "sequence points". Not for the faint of heart...)
The first statement will clearly cause problems. The order of the
increments is
not specified. In the second expression, because of short
-
circuit evaluation of the
boolean AND operator (&&) a very similar

expression is well
-
defined because the first increment MUST be evaluated first,
then the second (only if the first is

TRUE).


c.

What's the problem here?

int y;

double x, z;

x = y = z = 3.1415;


Suggested solution:

There is a hidden truncation lurking in here. Because = is right associative, first
3.1415 is assigned to z, then the same value is assigned to
the int y, causing a
truncation. This truncated value (3.0) is then assigned to the floating
-
point variable x.