Call by Name with dynamic scoping - c

I am stuck at the following problem on static/dynamic scoping:
The following program fragment is written in a programming language that allows global
variables and does not allow nested declarations of functions.
global int i = 100, j = 5;
void P(x) {
int i = 10;
print(x + 10);
i = 200;
j = 20;
print (x);
}
main() {P(i + j);}
Q1. If the programming language uses static scoping and call by need
parameter passing mechanism, the values printed by the above program
are
(A) 115, 220 (B) 25, 220 (C) 25, 15 (D) 115, 105
Q2. If the programming language uses dynamic scoping and call by name
parameter passing mechanism, the values printed by the above program
are
(A) 115, 220 (B) 25, 220 (C) 25, 15 (D) 115, 105
What I think:
On Q1: As it's static scoping and as per call by need, x should be replaced with i + j. But it will cause a local name conflict as there is already a variable with name i. So it (the global i) might be renamed, lets say to i1, and then call will be:
first call: print(x+10) -> (i1 + j + 10) -> (100 + 5 + 10) -> 115
second call: print(x) -> print(i1 + j) -> 105 (Already evaluated - call by need)
On Q2: In dynamic scoping, you search for a variable in the local function first, then you search in the function that called the local function, then you search in the function that called that function, and so on, up the call stack.
As per call by name:
print (i1 + j + 10) -> print (100 + 5 +10 ) -> 115
And the second call will be
print(x) -> print(i1 + j) -> (100 + 20) = 120 // Evaluate again - Call be name.
Is this answer correct? (Not present in the options)
Is there something I'm missing? (Dynamic binding may be?)

Q1
OP's answer is correct (D). In fact, because global i is not modified during the execution of P, there is no difference between call by need and call by value.
Here is an example where it does make a difference:
global int i = 100, j = 5;
void IncreaseTheGlobal() {
i = i + 1; // static scoping means this is the GLOBAL i!
print(i);
}
void P(x) {
int i = 10;
IncreaseTheGlobal(); // 101 (increased global i)
print(i); // 10 (local i)
print(x); // 106 (x is evaluated; picks up increased global i)
IncreaseTheGlobal(); // 102 (2nd time increased global i)
print(x); // 106 (x not re-evaluated; unaffected by 2nd increase)
}
main() {
print(i); // 100 (original global i)
P(i + j);
print(i); // 102 (new global i)
}
As already pointed out by OP, the first time x is evaluated, it picks up whatever value global i has at that particular moment. After that initial evaluation, x is no longer affected by a later modification of global i.
Q2
Call by name is typically used in macro languages. So why not use the best known macro language ever: the C preprocessor?
#include <stdio.h>
int i = 100, j = 5;
#define print(num) printf("%d\n", num)
#define P(x) { \
int i = 10; \
print(x + 10); \
i = 200; \
j = 20; \
print(x); \
}
main() {
P(i + j);
}
Compile, run, and see: 25, 220.
Call by name works with a simple search-and-replace; within the body of P, replace every occurrence of x by i + j.
int i = 10;
print(i + j + 10); // 10 + 5 + 10 = 25
i = 200;
j = 20;
print(i + j); // 200 + 20 = 220
In other words, the i and the j inside i + j just pick up the present value of whatever happens to be in scope when x is evaluated.
So the correct answer is B, right? Well, almost... the correct answer depends on the implementation of print.
Suppose print practices call by name too, and print defines its own local variable i, then that would dramatically change the result. Try this:
#define print(num) { int i = 0; printf("%d\n", num); }
The result now changes to 15, 20.
This is probably the most important reason why dynamic scoping is bad for the maintainability of your code. Implementation changes in function print (even something trivial as changing the name of a local variable) might break functions on a higher level.

In the second part that is Call by name
The line i=200 will update the local i
Now while print(x) is called it will be replaced by print(i+j)=>print(200+20)=>220

For Q1:
int i = 10;
print(x + 10); // print (i + j + 10); prints 10 + 5 + 10 = 25; local i gets used here
i = 200;
j = 20;
print (x); // print (i + j); call by need ensures, no reevaluation and i + j is 15.
So, answer is C - 25, 15

Related

unexpected output in recursive function involving static local variable

I am trying to find the output for fun(5). But I am getting an unexpected result (19) and don't know why.
My doubt is for n =5 for instance, it would return fun(3) + 3. After that would the return fun(4) + x work or the function fun will be called again?
int fun(int n)
{
static int x = 0;
if (n<=0) return 1;
if (n>3)
{
x = n;
return fun(n-2) + 3;
}
return fun(n-1) + x;
}
This is the sequence of what happens:
call fun(5)
x=0; which, being the initialisation of a static local variable,
only happens before the very first call to fun()
5>3: x=5 (not a problem, static vars can be changed and keep the value)
return fun(3)+3
return fun(2) + 5
return fun(1) + 5
return fun(0) + 5
return 1
return 1 + 5
return 6 + 5
return 11 + 5
return 16 + 3
The exact meaning an relation of the following lines seem to be of interest to you.
static int x = 0;
/* Defines a local but static variable, initialised to 0;
the initialisation happens before the first execution of the function,
conceptually at the beginning of the whole program (credits John Bollinger).
This does NOT cause an assignment to 0 during each execution of the function.
The static attribute also means that the value at the end of one
execution will still be found in the variable at the start of the next
execution, even and especially if that start is before the end of the current execution,
which is typical for recursive functions.
*/
/* ... */
x = n;
/* This conditional (inside an if) assignment in the middle of the
recursive function changes the value of the static variable away from
the initialisation value, to e.g. 5.
If/because no other assignment occurs, the value will stay in the
for the rest of the program.
*/

C - Increase Integer In Loop

I'm trying to increase 0.001f in a loop, so in loop 1 the value is 0.001f, in loop 2 the value is 0.002f
This is what I have (doesn't work since it doesn't include the i in the value and it's not correct):
for (int i = 0; i < 34; i++) {
GRAPHICS::DRAW_RECT(0.825f, ((maxOptions * 0.000f++) + 0.1765f), 0.23f, 0.035f, scrollerColor.r, scrollerColor.g, scrollerColor.b, scrollerColor.a); // Scroller
}
I have tried making a buffer like so, but as expected that didn't work:
int buffer[10];
sprintf(buffer, "0.00%if", i);
How would I do this? ANswers are appreciated!
0.000f++ is invalid syntax, as the postincrement operator cannot be used on constants. It can only be used on an lvalue (i.e. the name of a variable or an expression that represents one).
Assuming you want this value to range from 0.001 to 0.034 you would multiply 0.001 by the loop index, changing the loop to go from 1 to 34 instead of 0 to 33.
for (int i = 1; i <= 34; i++) {
GRAPHICS::DRAW_RECT(0.825f, ((maxOptions * 0.001f * i) + 0.1765f),
0.23f, 0.035f, scrollerColor.r, scrollerColor.g,
scrollerColor.b, scrollerColor.a); // Scroller
}
The variable i is never used inside your loop. Maybe you could tell us where you want to use it, or add more context to the question?
But here's my first raw attempt at an answer anyway:
for (float i = 0; i < 0.034f; i += 0.001f) {
GRAPHICS::DRAW_RECT(0.825f, ((maxOptions * 0.000f++ /* This part has an issue and I can't understand what you mean by it*/) + 0.1765f), 0.23f, 0.035f, scrollerColor.r, scrollerColor.g, scrollerColor.b, scrollerColor.a); // Scroller
}
Due to the way your processor handles floating point arithmetic, this code can result in one more or less loop as pointed out by dbush (thanks!)
You can fix it as follows:
// Include math.h at the top of your code.
for (float i = 0; fabs(i - 0.034f) > 0.0001; i += 0.001f) {
GRAPHICS::DRAW_RECT(0.825f, ((maxOptions * 0.000f++ /* This part has an issue and I can't understand what you mean by it*/) + 0.1765f), 0.23f, 0.035f, scrollerColor.r, scrollerColor.g, scrollerColor.b, scrollerColor.a); // Scroller
}

multiple if conditions optimisation

I am building a simple C project (for arduino) and I have come across this question.It's not actually that language specific, it's more of an algorithm optimisation thing.
So, I need to check a value of X against a sensor reading.
If X <5 ...
else if x<10...
else if x<15...
else if x<20...
Then in each clause I have the same for loop,but the iterations change depending on the value of X.
In a general sense, how can these if conditions be replaced by something unified?I remember these "gradation" or "leveling" problems in highschool, but we still used if clauses.
In a comment below you've said (in reference to the second solution under the bar using an array):
I actually do not need the second dimension,as the value ranges are defined in the first dimension/column (5 10 15 20 etc)
In that case, it's really much simpler than the solutions below:
int loops = ((X / 5) + 1) * 5;
...assuming X is an int. That uses integer division, which truncates (e.g., 4 / 5 is 0), adds one, then multiplies the result by 5. Here's the same thing in JavaScript just for an on-site example (in JavaScript, since numbers are always floating point, we have to add in a flooring method, but you don't need that in Java):
var X;
for (X = 0; X < 25; ++X) {
var loops = (Math.floor(X / 5) + 1) * 5;
console.log("X = " + X + ", loops = " + loops);
}
Then in each clause I have the same for loop,but the iterations change depending on the value of X.
I'd set a variable to the number of iterations, then put the for loop after the if/else sequence.
int loops;
if (X < 5) {
loops = /*whatever*/;
} else if (X < 10) {
loops = /*whatever*/;
} else if (X < 15) {
loops = /*whatever*/;
// ...and so on...
} else {
loops = /*whatever for the catch-all case*/;
}
for (int i = 0; i < loops; ++i) {
// ...
}
If you're trying to avoid the if/else, if there are only a small number of possible sensor values, you could use a switch instead, which in some languages is compiled to a jump table and so fairly efficient.
If you want to have the ranges held as data rather than in an if/else sequence, you could use an array of values:
int[][] values = {
{5, 500},
{10, 700},
{15, 800},
{20, 1200},
{0, 1500} // 0 is a flag value
};
(There I'm using an array of int[], but it could be a nice clean class instance instead.)
Then loop through the array looking for the first entry where X < entry[0] is true (or where entry[0] is 0, to flag the last entry).
int loops = 0; // 0 will never be used, but the compiler doesn't know that
for (int[] entry : values) {
if (entry[0] == 0 || X < entry[0]) {
loops = entry[1];
break;
}
}
...followed by the for loop using loops.
Since your intervals are products of 5, it may be possible to just divide X by 5 and use the result as index in an array.
const size_t loops[] = {someval, anotherval, ..., lastval};
size_t i, nloops = loops[X / 5];
for (i = 0; i < nloops; i++) {
...
}

Can't decipher the output

#include<stdio.h>
int f(int n)
{
static int a;
if(n)
a=n%10+f(n/10);
return a;
}
int main()
{
printf("%d",f(12345));
}
The output is 15. My doubt is how the stack memory is being used.
Let's pretend to be the computer:
f(12345)
make int a, set to 0 (as static)
a = 12345%10 + f(1234)
note program counter, so we remember where to come back to
f(1234)
a = 1234%10 + f(123)
note program counter, so we remember where to come back to
f(123)
a = 123%10 + f(12)
note program counter, so we remember where to come back to
f(12)
a = 12%10 + f(1)
note program counter, so we remember where to come back to
f(1)
a = 1%10 + f(0)
note program counter, so we remember where to come back to
f(0)
return a, i.e. 0 (since we haven't changed it yet)
return a = 1%10 + 0 = 1
return a = 12%10 + 1 = 3
return a = 123%10 + 3 = 6
return a = 1234%10 + 6 = 10
return a = 12345%10 + 10 = 15
Job done.
You'll get the same result with following function implementation:
int f(int n) {
if (n)
return n%10 + f(n/10);
return 0;
}
In your case behavior will be the same, and that's why. Firstly, when you initialize static int variable, it default value is 0 (unlike to just int declaration inside the function body). Secondly, the only value of n when your function just takes a value and does not assign it is 0, because when the line a=n%10 + f(n/10) evaluated, the recursive f() call happens before assignment to a, and its value remains unchanged before f(0) call.
On every recursive call to f() I denote n and with additional '
so
n = 12345, a = 5
n' = 1234, a' = 4
n'' = 123, a'' = 3
n''' = 12, a''' = 2
n'''' = 1, a'''' = 1
n''''' = 0, a''''' = 0 (because a is static)
the answer is a + a' + a'' + .... = 15
Note: the a doesn't need to be static. int a = 0; will do.
The detailed stack usage is compiler dependent. But we can say roughly that for each call of function f, the "int n" is pushed onto the stack, thus occupying the size of an int.
If you call your function recursively N times, then the stack usage reaches N*sizeof(int) bytes.
You also probably need to add some bytes for the return value as well.

How does the preprocessor work in C?

Why is the answer for the below code 16? Can anybody explain the working of this program?
#define SQUARE(n) n*n
void main()
{
int j;
j =16/SQUARE(2);
printf("\n j=%d",j);
getch();
}
If we write the same code like below, then the answer is 4:
//the ans is 4 why?
#include<stdio.h>
#include<conio.h>
#define SQUARE(n) n*n
void main()
{
int j;
j =16/(SQUARE(2));
printf("\n j=%d",j);
getch();
}
The preprocessor just replaces the text, exactly as written.
So, the macro call SQUARE(2) becomes literally 2*2.
In your case, that means the whole expression becomes 16/2*2, which because of C's precedence rules evaluates to (16/2)*2, i.e. 16.
Macros should always be enclosed in parenthesis, and have each argument enclosed as well.
If we do that, we get:
#define SQUARE(n) ((n) * (n))
which replaces to 16/((2) * (2)), which evaluates as 16/4, i.e. 4.
The parens around each argument makes things like SQUARE(1+1) work as expected, without them a call such as 16/SQUARE(1+1) would become 16/(1+1*1+1) which is 16/3, i.e. not at all what you'd want.
Order of operations. Your expression is evaluating to:
j = 16 / 2 * 2
which equals 16. Make it:
#define SQUARE(n) (n*n)
which will force the square to be evaluated first.
You need to define your macro with insulating parentheses, like so:
#define SQUARE(n) ((n)*(n))
Otherwise
j = 16/SQUARE(2);
expands to
j = 16 / 2 * 2; which is equivalent to (16 / 2) * 2
When what you want is
j = 16 / (2 * 2);
1. When using macros that are to be used as expressions, you should parenthesise the whole macro body.
This prevents erroneous expansions like:
#define SQUARE(x) x*x
-SQUARE(5,5)
// becomes -5 * 5
2. If the macro arguments are expreessions, you should parenthesise them too.
This prevents a different type of problems:
#define SQUARE(x) x*x
SQUARE(5+2)
// becomes 5 + 2*5 + 2
Hence the correct way is to write it like this:
#define square(n) ((n)*(n))
-SQUARE(5+2)
// becomes -((5+2)*(5+2))
Using macros as functions is discouraged though (guess why), so use a function instead. For instance:
inline double square(n) { return n*n; }
The Expansion of macro will be like:
j = 16/SQUARE(2);
j = 16/2*2;
Which is equal to : j = (16/2)*2; Means j = 16;
and :
j = 16/(SQUARE(2));
j = 16/(2*2);
Which is equal to : j = 16/4; Means j = 4;
Because the macro will be expanded as:
j = 16/2*2;
The pre-compiler does not do any processing on the expansion. It places the expanded macro in your code as it is. Since you have not parenthesized the replacement text it wont do it for you in the main code as well. Make it :
#define SQUARE(n) ((n)*(n))
The first example is evaluated as:
16 / 2 * 2
(16 / 2) * 2
8 * 2
16
The second example is evaluated as:
16 / (2 * 2)
16 / 4
4
Add parenthesis to you preprocessor statement to control the order of operations:
#define SQUARE(n) ((n)*(n))
The outer parenthesis in ((n)*(n)) ensure that n is squared before any outside operation is performed. The inner parenthesis (n) ensure that n is correctly evaluated in cases where you pass an expression to SQUARE like so:
16 / SQUARE(2 * 2)
16 / ((2 * 2)*(2 * 2))
16 / (4 * 4)
16 / 16
1
you'll get
j =16/2*2; // (16 / 2) * 2 = 16
Its because Whenever macro name is used, it is replaced by the contents of the macro.its simple rule of working of macro.
Case 1 : result 16
define SQUARE(n) n*n
void main()
{
int j;
j =16/SQUARE(2);
printf("\n j=%d",j);
getch();
}
its get expand as below
j =16/SQUARE(2);
so in place of SQUARE(2) it will replace 2*2 because Macro is SQUARE(n) n*n
j = 16/2*2
j = (16/2)*2
j = 8*2
j =16
Case 2 : result 4
define SQUARE(n) n*n
void main()
{
int j;
j =16/(SQUARE(2));
printf("\n j=%d",j);
getch();
}
its get expand as below
j =16/(SQUARE(2));
so in place of SQUARE(2) it will replace 2*2 because Macro is SQUARE(n) n*n
j = 16/(2*2)
j = 16/(4)
j = 4
Hope this will help

Resources