King
Fahd University of Petroleum and Minerals
ICS 313: Fundamentals of Programming Languages
Fall
1999-2000
Date: 25th
September 1999 Assignment # 2: Imperative Paradigm Due
date: 9th October 1999
Deliverables
and Submission guidelines
Download
this assignment from the course page
and take it on a floppy. If you open it in a browser, you will have the
advantage of easy navigation to some web documents through hot links. Deliverables
and Submission guidelines are provided on-line.
On-line Exploration
and Reading Part
Exercise 1 [Online Reference Section]:
Examine carefully the structure and contents of Java
Reference Section, and other Online Books on
Java. Start familiarizing yourself with its structure, as you will be doing a
programming project in Java shortly.
Go through the Trails Covering the Basics in the tutorial.
In particular the trials First
Cup of Java, Getting
Started, and Learning
the Java Language are recommended for the time being. Try out the simple
programs. We will get to the concepts on object-orientation in the class in a
couple of weeks from now. Meanwhile, get started by having a working version of
the Java Development Kit on your machine. All the necessary soft copies are
available and can be downloaded from the course page. You need to examine the
Frequently Asked Questions section and follow the questions and answers posted
there. After examining them, if you still have a question, you can send an
e-mail message to your instructor with a brief and precise description of the
problem.
Exercise 2 [Reading from Textbook]:
Chapters
4 – 6 of the textbook.
Written Part
1. Written Exercises [Problems from Chapter 4 of the
Textbook]:
Solve the following problems from pages 186-190 of the
textbook.
Problems |
Topic |
6 |
Use
of History Sensitive Variables |
13 |
Illustration
of Dynamic Scope |
2. Written Exercises [Problems from Chapter 5 of the
Textbook]:
Solve the following problems from pages 249-255 of the
textbook.
Problems |
Topic |
6 (program) |
Test Programs for Type
Compatibility in C Language |
14 |
Functions
for row-major and column-major access of a 3D array |
Assignment Solution
1. Written Exercises [Problems from Chapter 4 of the
Textbook]:
Q.
6.(pp. 186) (12
points)
To describe a
situation when a history-sensitive variable in a subprogram is useful, suppose
that a FORTRAN subroutine is used to implement a data structure as an
abstraction. In this situation, it is essential that the structure persists
between different calls to the managing subroutine.
Q. 13. (pp. 189) (48
points)
We will explain in
details the solution for part (a). The other parts can be explained in a
similar manner. In fun3 d, e and f are visible. In fun2 since d and e were hidden by fun3 then it is
only c that is visible. In fun1
since d is hidden by fun3 and c is hidden by fun2 then it
is only b that is visible. Finally, in main since c is hidden by
fun2 and b is hidden by fun1 then it is only a that is
visible. The solution is summarized below:
(a) d, e, f fun3
c fun2
b fun1
a main
(b) d, e, f fun3
b,
c fun1
a main
(c) b, c, d fun1
e,
f fun3
a main
(d) b,
c, d fun1
e,
f fun3
a main
(e) c, d, e fun2
f fun3
b fun1
a main
(f) b, c, d fun1
e fun2
f fun3
a main
2. Written Exercises [Problems from Chapter 5 of the
Textbook]:
Q. 6. (pp. 249): Design a set of simple test programs to determine the type compatibility rules of a C compiler. Write a report of your finding. (Bonus 30 points)
Solution
Type Compatibility Rules:
One is often interested in the type-compatibility
rules so as to understand how a program behaves.
This could be divided broken up into the following
cases:
1.
What kinds of primitive
types can be mixed to go past the compilation and for what operations? What
happens to the result of such an operation?
2.
What kinds of
homogeneous aggregates (arrays) can be compatible with what kinds of operations
(assignment, parameter passing, equality test etc.)
3.
What kinds of
heterogeneous aggregates (records or structures) can be compatible with what
kinds of operations (assignment, parameter passing, equality test etc.)
Given below are some sample programs for primitive
types in C.
C language permits pretty much all kinds of mixing of
the primitive types, usually resorting to truncation in case of a narrowing
assignment.
Array variables are treated as pointers to data areas
and C-language is pretty much relaxed about the assignment of one array pointer
to another.
In so far as structures are concerned, C language
employs structural equivalence, i.e., {int, float, int} declared as two types
will be compatible, since each of the two definitions have three components
each with types int, float, and int respectively. Parameter passing is through
value.
For Pascal, integer to real assignment is permitted
and the other way is not. The other kinds of mixing among variables of
primitive types is not accepted. Pascal employs name equivalence and hence two
aggregate (arrays or records) variables can participate in an assignment,
parameter passing.
Equality
testing is permitted on packed aggregates only.
1.
Test int and long int assignments:
#include <stdio.h>
int main (int argc, char * argv[]) {
int x = 5;
long int y=
9735624,z;
z = x;
x = y;
printf("the value of z=
%ld \n the value of x= %d", z, x);
return 0;
}
Result:
the value of z = 5
the value of x = -29240
which shows that assigning int to a long int
is compatible but not vice versa.
2.
Test for double and float assignments:
#include
<stdio.h>
int
main (int argc, char * argv[]) {
double a = 3.145965932;
float c =
3.14, b;
b = a;
a = c;
printf("the value of b = %f\nthe value of a =
%lf", b, a);
}
Result:
the
value of b =3.145966
the
value of a =3.140000
3.
Test for mixed
primitive data types
#include
<stdio.h>
int
main (int argc, char * argv[]) {
double a = 3.145965932;
float c =
3.14, b;
int x = 5;
long int y = 9735624;
x = a;
c = y;
printf("the value of x = %d\nthe value of c =
%f", x, c);
}
Result:
the
value of x = 3
the
value of c = 9735624.000000
#include
<stdio.h>
int
main (int argc, char * argv[]) {
int choice;
while ( choice != 7 ) {
printf
("\nMAIN MENUE\n1.ADD INTEGER AND FLOAT, \
STORE
IT IN FLOAT.\n2.ADD INTEGER AND FLOAT, \
STORE
IT IN INTEGER.");
printf
("\n3.ADD INTEGER TO CHARACTER, \
STORE
IT IN INTEGER.\n4.ADD INTEGER TO CHARACTER, \
STORE
IT IN CHARACTER.");
printf
("\n5.ADD FLOAT TO CHARACTER, \
STORE
IT IN FLOAT.\n6.ADD FLOAT TO CHARACTER, \
STORE
IT IN CHARACTER.\n7.Exit.\n==>");
scanf ("%d", & choice );
switch
( choice ) {
int a, b;
float
c, d;
char
e, f;
case
1: a=10;
c=5.3;
d=a+c;
printf
("\n%d + %1.1f = %1.1f", a,c,d);break;
case
2: a=10;
c=5.3;
b=a+c;
printf
("\n%d + %1.1f = %d", a,c,b);break;
case
3: a=10;
e='A';
b=a+e;
printf
("\n%d + %c = %d", a,e,b);break;
case
4: a=10;
e='A';
f=a+e;
printf
("\n%d + %c = %c", a,e,f);break;
case
5: c=9.7;
e='L';
d=c+e;
printf
("\n%1.1f + %c = %1.1f", c,e,d);break;
case
6: c=9.7;
e='L';
f=c+e;
printf
("\n%1.1f + %c = %c", c,e,f);break;
case
7: printf
("\n\tbyebye");break;
default
: printf
("\ninvalid number\n");break;
}
}
}
This program tests the type compatibilities rules of a C compiler by
adding various types and we can then see the results and whether or not it
accepted that addition. After running this program no errors were detected
neither by compiler nor runtime and in the case of adding an integer and a
float and storing the result into float we got a float result meaning that the
compiler must have turned the integer into a float:
MAIN MENUE 1.ADD INTEGER AND FLOAT, STORE IT IN FLOAT. 2.ADD INTEGER AND FLOAT, STORE IT IN
INTEGER. 3.ADD INTEGER TO CHARACTER, STORE IT IN
INTEGER. 4.ADD INTEGER TO CHARACTER, STORE IT IN
CHARACTER. 5.ADD FLOAT TO CHARACTER, STORE IT IN FLOAT. 6.ADD FLOAT TO CHARACTER, STORE IT IN
CHARACTER. 7.Exit. ==>1 10 + 5.3 = 15.3 |
In case #2 the storing of the result was done in integer and as we can
see the compiler dropped the 0.3 I changed the value of the float to 5.8 to see
whether it was rounding or just dropping the decimal points. It turned out that
it drops the decimals because I got the same solution (10 + 5.8 = 15):
MAIN MENUE 1.ADD INTEGER AND FLOAT, STORE IT IN FLOAT. 2.ADD INTEGER AND FLOAT, STORE IT IN
INTEGER. 3.ADD INTEGER TO CHARACTER, STORE IT IN INTEGER. 4.ADD INTEGER TO CHARACTER, STORE IT IN
CHARACTER. 5.ADD FLOAT TO CHARACTER, STORE IT IN FLOAT. 6.ADD FLOAT TO CHARACTER, STORE IT IN
CHARACTER. 7.Exit. ==>2 10 + 5.3 = 15 |
In case #3 (ADD INTEGER TO
CHARACTER, STORE IT IN INTEGER). The character
was treated like an integer it was given the value 65 so adding 10 to it gives
75:
MAIN MENUE 1.ADD INTEGER AND FLOAT, STORE IT IN FLOAT. 2.ADD INTEGER AND FLOAT, STORE IT IN
INTEGER. 3.ADD INTEGER TO CHARACTER, STORE IT IN
INTEGER. 4.ADD INTEGER TO CHARACTER, STORE IT IN
CHARACTER. 5.ADD FLOAT TO CHARACTER, STORE IT IN FLOAT. 6.ADD FLOAT TO CHARACTER, STORE IT IN
CHARACTER. 7.Exit. ==>3 10 + A = 75 |
In case #4 (ADD INTEGER TO
CHARACTER, STORE IT IN CHARACTER) the result is
character type therefore we got the character that has the value 75 namely K.
It was as if we asked for the alphabetical character that exceeds A by 10:
MAIN MENUE 1.ADD INTEGER AND FLOAT, STORE IT IN FLOAT. 2.ADD INTEGER AND FLOAT, STORE IT IN
INTEGER. 3.ADD INTEGER TO CHARACTER, STORE IT IN
INTEGER. 4.ADD INTEGER TO CHARACTER, STORE IT IN
CHARACTER. 5.ADD FLOAT TO CHARACTER, STORE IT IN FLOAT. 6.ADD FLOAT TO CHARACTER, STORE IT IN
CHARACTER. 7.Exit. ==>4 10 + A = K |
In case #5 the result obtained satisfies what was said earlier about
characters considered integers. Therefore case #5 is similar to case #1:
MAIN MENUE 1.ADD INTEGER AND FLOAT, STORE IT IN FLOAT. 2.ADD INTEGER AND FLOAT, STORE IT IN
INTEGER. 3.ADD INTEGER TO CHARACTER, STORE IT IN
INTEGER. 4.ADD INTEGER TO CHARACTER, STORE IT IN
CHARACTER. 5.ADD FLOAT TO CHARACTER, STORE IT IN FLOAT. 6.ADD FLOAT TO CHARACTER, STORE IT IN
CHARACTER. 7.Exit. ==>5 9.7 + L = 85.7 |
Case #6 is a combination of case #2 and case #4. We can say that we are
adding an integer to a float and the result is integer type so the 0.7 is
dropped so we get a U rather than a V(if the result was rounded):
MAIN MENUE 1.ADD INTEGER AND FLOAT, STORE IT IN FLOAT. 2.ADD INTEGER AND FLOAT, STORE IT IN
INTEGER. 3.ADD INTEGER TO CHARACTER, STORE IT IN
INTEGER. 4.ADD INTEGER TO CHARACTER, STORE IT IN
CHARACTER. 5.ADD FLOAT TO CHARACTER, STORE IT IN FLOAT. 6.ADD FLOAT TO CHARACTER, STORE IT IN
CHARACTER. 7.Exit. ==>6 9.7 +
L = U |
#include <stdio.h>
int
main (int argc, char * argv[]) {
char
ch;
int
b;
printf("Enter
the value of ch: ");
scanf("%c,
&ch);
printf("\nEnter
the value of b: ");
scanf("%d", &b);
if(a == b)
printf("Type
compatible!!!");
else
printf("\No
type compatible!!!");
}
Q. 14. (pp. 250) (40
Points)
Let the subscript ranges of the three dimensions be
named min(1), min(2), min(3), max(1), max(2), and max(3). Let the sizes of the
subscript ranges be size(1), size(2), and size(3). Assume the element size is
1.
Row Major Order:
You need to imagine that
the storage will look like this:
a(min(1), min(2), min(3)), a(min(1), min(2)+1,
min(3)), … , a(min(1), max(2), min(3)), a(min(1)+1, min(2), min(3)),
a(min(1)+1, min(2)+1, min(3)), … , a(min(1)+1, max(2), min(3)), ……. ,
a(max(1), min(2), min(3)), a(max(1), min(2)+1, min(3)), … ,
a(max(1), max(2), min(3)), , a(min(1), min(2),
min(3)+1), a(min(1), min(2)+1, min(3)+1), … , a(min(1), max(2),
min(3)+1), a(min(1)+1, min(2), min(3)+1), a(min(1)+1, min(2)+1,
min(3)+1), … , a(min(1)+1, max(2), min(3)+1), … , a(max(1),
min(2), min(3)+1), a(max(1), min(2)+1, min(3)+1), … , a(max(1),
max(2), min(3)+1),
location(a[i,j,k])
= (address
of a[min(1),min(2),min(3)]) + ((i-min(1))*size(3) +
(j-min(2)))*size(2)
+ (k-min(3))
Column Major Order:
You need to imagine that
the storage will look like this:
a(min(1), min(2), min(3)), a(min(1)+1, min(2),
min(3)), … , a(max(1), min(2), min(3)), a(min(1), min(2)+1, min(3)),
a(min(1)+1, min(2)+1, min(3)), … , a(max(1), min(2)+1, min(3)), ……. ,
a(min(1), max(2), min(3)), a(min(1)+1, max(2), min(3)), … ,
a(max(1), max(2), min(3)), , a(min(1), min(2),
min(3)+1), a(min(1)+1, min(2), min(3)+1), … , a(max(1), min(2),
min(3)+1), a(min(1), min(2)+1, min(3)+1), a(min(1)+1, min(2)+1,
min(3)+1), … , a(max(1), min(2)+1, min(3)+1), ……. , a(min(1),
max(2), min(3)+1), a(min(1)+1, max(2), min(3)+1), … , a(max(1),
max(2), min(3)+1),
location(a[i,j,k])
= (address
of a[min(1),min(2),min(3)])+((k-min(3))*size(1) +
(j-min(2)))*size(2)
+ (i-min(1))