CS441 Practice Exam – 2

advertisement
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 strong 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 important 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 enforced 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 individual 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++ support 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
and Perl.
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
nonconverting 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 problem.
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
instance?
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
o
Find the correct activation record instance
Determine the correct offset within that activation record instance
h. What’s the two potential problems with the static chain method?
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 variable 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
while 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 evaluated 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;
void 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 initialized 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 objects, 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 appropriate 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 () {
int 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 expression 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 modifications 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.
Download