Would somebody please explain how this program is executed? - call

below is a program in a statically-scoped language:
program main
int x, y;
void p1(value int y, void q(reference int)) {
void p2(reference int x) {
x := y + 2;
print(x);
q(y);
}
if x = y then q(y) else p1(y+1, p2)
}
void p2(reference int x) {
x := y + 2;
print(x);
}
x := 2;
y := x;
p1(0, p2);
end main
by "value" it means parameter transmitted by value, "reference" by reference.
Will function call "q(y)" in p2 cause infinite loop?

Since it's statically-scoped, you can change the variable names inside functions to avoid the confusion intended by the question. I'm replacing y in p1 with p1y, p2 in p1 with p1p2, x in p1p2 with p1p2x and x in p2 with p2x (it looks even uglier now, though). I also slightly changed the formatting.
program main
int x, y;
void p1(value int p1y, void q(reference int)) {
void p1p2(reference int p1p2x) {
p1p2x := p1y + 2;
print(p1p2x);
q(p1y);
}
if x = p1y then {
q(p1y);
} else {
p1(p1y+1, p1p2);
}
}
void p2(reference int p2x) {
p2x := y + 2;
print(p2x);
}
x := 2;
y := x;
p1(0, p2);
end main
Since this is homework, you should be able to take it from here easily, using whatever methods they taught you (follow the execution line by line, draw a stack, etc). But the final answer is yes, it will loop infinitely, printing 4 6 8 and so on.

It prints 4. In Java:
import java.util.concurrent.atomic.AtomicInteger;
public class Test {
public static void main(String... a) {
new Test().run();
}
AtomicInteger x = new AtomicInteger(0);
AtomicInteger y = new AtomicInteger(0);
void run() {
x.set(2);
y.set(x.get());
new P1().p1(new AtomicInteger(0), new P2());
}
interface Q {
void q(AtomicInteger x);
}
class P2 implements Q {
public void q(AtomicInteger x) {
x.set(y.get() + 2);
System.out.println(x.get());
}
}
class P1 implements Q {
public void q(AtomicInteger x) {
x.set(y.get() + 2);
System.out.println(x.get());
}
void p1(AtomicInteger y, Q q) {
if (x.get() == y.get()) {
q.q(y);
} else {
p1(new AtomicInteger(y.get()+1), this);
}
}
}
}

Related

Pointers to structs, C

I have these two structs, everything goes well, but when I try calculating poly->scope
The output is 0.0 , like nothing really happens.
Also, I get some errors I cannot understand, for example -
the line scanPoint(&poly->points[i]); says "Dereferencing NULL pointer"
Thanks for help.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct point
{
int x, y;
}point;
typedef struct polygon
{
int n;
point* points;
double scope;
}polygon;
void scanPoint(point*);
void scanPolygon(polygon*);
double distance(point*, point*);
void calculatePolygonScope(polygon*);
void freeMemory(polygon*);
int main()
{
polygon poly;
scanPolygon(&poly);
calculatePolygonScope(&poly);
freeMemory(&poly);
printf("Output: Scope of polygon: %.2lf\n", poly.scope);
return 0;
}
void scanPoint(point* p)
{
printf("Please Enter X of your point: \n");
scanf("%d", &p->x);
printf("Please Enter Y of your point: \n");
scanf("%d", &p->y);
}
void scanPolygon(polygon* poly)
{
int i;
printf("Please enter how many points does the polygon have? : \n");
scanf("%d", &poly->n);
poly->points = (point*)calloc(poly->n, sizeof(point));
for (i = 0; i < poly->n; i++)
{
scanPoint(&poly->points[i]);
}
}
double distance(point* p1, point* p2)
{
double x = pow(((double)p2->x - (double)p1->x), 2);
double y = pow(((double)p2->y - (double)p1->y), 2);
double dis = sqrt(x + y);
return dis;
}
void calculatePolygonScope(polygon* poly)
{
int i;
double temp = 0.0;
for (i = 0; i < poly->n-1;)
{
temp += distance(&poly->points[i], &poly->points[++i]);
}
poly->scope = temp;
}
void freeMemory(polygon* poly)
{
free(poly->points);
}
The function call distance(&poly->points[i], &poly->points[++i]); in calculatePolygonScope exhibits undefined behavior because it uses the value of i in two places, one of which modifies the value of i. From C17 6.5/2:
If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined. If there are multiple allowable orderings of the subexpressions of an expression, the behavior is undefined if such an unsequenced side effect occurs in any of the orderings.85)
85)This paragraph renders undefined statement expressions such as
i = ++i + 1;
a[i++] = i;
while allowing
i = i + 1;
a[i] = i;
To fix it, do the increment of i in the for loop control:
for (i = 0; i < poly->n-1; i++)
{
temp += distance(&poly->points[i], &poly->points[i + 1]);
}
If calculatePolygonScope is supposed to calculate the perimeter of the polygon, it is missing the edge between the first and last points. It could be changed as follows to include that edge:
void calculatePolygonScope(polygon* poly)
{
int i;
double temp = 0.0;
for (i = 0; i < poly->n-1; i++)
{
temp += distance(&poly->points[i], &poly->points[i + 1]);
}
if (poly->n > 1)
{
/* Last edge */
temp += distance(&poly->points[poly->n-1], &poly->points[0]);
}
poly->scope = temp;
}
As an aside, the distance function can be simplified by using the hypot function:
double distance(point* p1, point* p2)
{
return hypot(p2->x - p1->x, p2->y - p1->y);
}
or to avoid any possible integer overflow:
double distance(point* p1, point* p2)
{
return hypot((double)p2->x - p1->x, (double)p2->y - p1->y);
}
EDIT: OP is not allowed to use hypot, but the distance function can still be simplified by using simple multiplication to do the squaring, instead of using the more expensive (and potentially less accurate) pow function:
double distance(point* p1, point* p2)
{
double x = (double)p2->x - (double)p1->x;
double y = (double)p2->y - (double)p1->y;
double dis = sqrt(x * x + y * y);
return dis;
}
Note: It is not actually necessary to cast both operands of the subtraction operator to double. The other can be left as an int and will be converted to double automatically before the subtraction is performed.
You probably want this:
void calculatePolygonScope(polygon* poly)
{
int i;
double temp = 0.0;
for (i = 0; i < poly->n - 1; i++)
{
temp += distance(&poly->points[i], &poly->points[i + 1]);
}
poly->scope = temp;
}
With that modification the function returns the sum the polygon's segments except the last segment.
If the function is supposed to return the perimeter of the polygon, you need obviously to add another modification. I let you findout yourself how to do this as an exercise.

Function as a function parameter in C

void f(int a, char b, char* c) {
if(..) {
...
f(a,b,c); //recursive
}
...
}
void g(int a, double b, char* c, int d) {
if(..) {
...
g(a,b,c,d); //recursive
}
...
}
I want to make a separate function because I use the code within the if statement several times. But this function have to have a function as a parameter becuase I use recursive method. I know that we can use function as a parameters, but in the f function there are 3 parameters, in the g function have 4 parameters.
The code in the if statement in f is the same as the code in the if of g. Except for the function call in that code?
Simply I have no idea how to solve this issue.
You can use union to pack the variable number of arguments, as shown in sample code below.
It may be unusual to use union like this, but it works.
#include<stdio.h>
union u {
struct { int a; char b; char* c; } f;
struct { int a; double b; char* c; int d; } g;
};
void func_u_f (union u* ua) {
printf(" f = {a: %d, b: %c, c:%s}\n", ua->f.a, ua->f.b, ua->f.c);
ua->f.a++;
}
void func_u_g (union u* ua) {
printf(" g = {a: %d, b: %e, c:%s, d:%d}\n",
ua->g.a, ua->g.b, ua->g.c, ua->g.d);
ua->g.a++; ua->g.b *= 2.0; ua->g.d++;
}
void r (int i, void (*func) (union u*), union u* ua) {
if (i < 3) { /* or whatever conditions to terminate recursion */
printf ("Recursion %d\n", i);
func(ua);
r (++i, func, ua);
} else {
printf ("Exit recursion at %d\n", i);
return;
}
}
int main () {
union u u1, u2;
/* f */
u1.f.a = 10; u1.f.b = 'X'; u1.f.c = "I am u.f.";
r(0, &func_u_f, &u1);
/* g */
u2.g.a = 10; u2.g.b = .4e-6; u2.g.c = "I am u.g."; u2.g.d = 98;
r(-2, &func_u_g, &u2);
return 0;
}
I am proposing you an easy fix that doesn't work in general because it involves the use of a sentinel value.
Let's say that the the variable d that you pass to g is always positive. Than you can choose -1 as sentinel value.
You always pass four parameters to the function myIf and then check whether d is -1. If it is, then you call f with three parameters, otherwise you call g.
int main() {
myIf(a, b, c, d);
return 0;
}
void myIf(int a, int b, char *c, int d)
{
if( d == -1 ) {
f(a, b, c);
}
else {
g(a, b, c, d);
}
}
I'm not sure exactly what you're trying to do. But if you're worried about code duplication in the if statements, you can refactor that our to another function:
if (isCondition()) ...
bool isCondition() { return ... }

why pass as argument of a function a function?

i have a little question.
i'm studying C with devc++ (as start) and i have seen as argument function you can pass a function, this is ok but why?
for example u can write as argument:
void myfunc(void(*func)(int)){}
but if u simple call function with his name and argument it is not better?
like example:
void myfunction (){name of func to call(myargs); }
there's a difference?
it seems the same thing but with more simple and short code
edit:
i want only know
void map (int (*fun) (int),int x[ ], int l) {
for(i = 0; i < l; i++)
x[i] = fun(x[i]);
}
why u use this instead of:
void map (int x[ ], int l) {
for(i = 0; i < l; i++)
x[i] = nameoffunction(yourargument);
}
You can use a function pointer as a parameter if you want your function to do different things depending on what the user wants.
Here's a simple example:
#include <stdio.h>
int add(int x, int y)
{
return x + y;
}
int subtract(int x, int y)
{
return x - y;
}
int multiply(int x, int y)
{
return x * y;
}
int divide(int x, int y)
{
return x / y;
}
int operation(int x, int y, int (*func)(int, int))
{
printf(" x=%d, y=%d\n", x, y);
return func(x,y);
}
int main()
{
int x = 8, y = 4;
printf("x+y=%d\n", operation(x,y,add));
printf("x-y=%d\n", operation(x,y,subtract));
printf("x*y=%d\n", operation(x,y,multiply));
printf("x/y=%d\n", operation(x,y,divide));
return 0;
}
A very good example is the classic sorting function qsort. It's a library function, which means that you only have access to it's prototype. In order to make qsort general, you have to write your own compare function. A typical implementation looks like this for regular integers:
int cmpfunc (const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}
And then, if you have an array arr of integers you can sort it with qsort(arr, sizeof(arr), cmpfunc)
You might ask why this is not built in the qsort function? After all, it would be easy to make it work for both floats and integers. Yes, but imagine if you have an array of structs that look like this:
struct {
char *firstname;
char *lastname;
int age;
} persons[10];
How would you sort this? Well, that's not obvious. You might want all three. In that case, write three different compare functions.
i want only know
void map (int (*fun) (int),int x[ ], int l) {
for(i = 0; i < l; i++)
x[i] = fun(x[i]);
}
why u use this instead of:
void map (int x[ ], int l) {
for(i = 0; i < l; i++)
x[i] = nameoffunction(yourargument);
}
Let's answer the question with a question - what if you want to perform more than one type of mapping? What if you want to map both x2 and √x?
You could certainly do something like
void map( int x[], int l, int type )
{
for ( int i = 0; i < l; i++ )
{
if ( type == MAP_SQUARED )
x[i] = int_square( x );
else if ( type == MAP_ROOT )
x[i] = int_root( x );
...
}
}
which works, but is hard to read and cumbersome to maintain - every time you want to perform a new mapping, you have to add a new case to the map function.
Compare that to
void map( int x[], int l, int (*fun)(int) )
{
for ( int i = 0; i < l; i++ )
x[i] = fun( x[i] );
}
...
map( x, l, int_square );
map( y, l, int_root );
You don't have to hack the map function to get different mappings - you only have to pass the function that operates on the individual elements. If you want to perform a new mapping, all you have to do is write a new function - you don't have to edit the map function at all.
The C standard library uses this form of delegation in several places, including the qsort function (allowing you to sort arrays of any type in any order) and the signal function (allowing you to change how a program reacts to interrupts dynamically).

QuickSort in C library

The Second Param of qsort
Now I want to sort a set of points by x.Following is my code:
typedef struct {
int x;
int y;
} point;
int cmpfunc( const void * a, const void * b){
point *point1 = (point *)(a);
point *point2 = (point *)(b);
if(point1->x < point2->x){
return -1;
}
return 0;
}
int main(){
point *points = (point *)malloc(sizeof(point)*3);
points[0].x = 1;
points[0].y = 2;
points[1].x = 0;
points[1].y = 4;
points[2].x = 4;
points[2].y = 3;
qsort(points,2,(sizeof(points[0])),cmpfunc);
int i=0;
while (i<3){
printf("x=%d",points[i].x);
printf("y=%d\n",points[i].y);
i++;
}
return 0;
}
Please notice qsort(points,2,(sizeof(points[0])),cmpfunc);
The result is correct when I pass the second param value 2 not 3.What's wrong with my code?
To sort on the x axis, you need something like:
static void cmpfunc(const void *a, const void *b)
{
const point *pa = a, *pb = b;
return pa->x < pb->x ? -1 : pa->x > pb->x;
}
It must return less than, equal to, or greater than zero. See the manual page for more.
Oh, and you really shouldn't "drop const" like that, for no reason, and of course you never need to cast from void * to a pointer to struct like we have here. Keep it simple, and learn these things so you don't feel a need to "throw in a cast for good measure".

square root using Babylonian method returns wrong value?

For the function isqroot() to calculate the square root using Babylonian method with one degree of precision and return it in a struct.
I'm unable to return the value to the struct and when I compile it is returning garbage value.
Here is my code:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
struct rootStruct {
int rootInt;
int rootFraction;
};
typedef struct rootStruct RootStruct;
RootStruct* isqroot (int n) {
/*We are using n itself as initial approximation*/
RootStruct* root=(RootStruct* )malloc(sizeof(RootStruct));
float x = n;
float y = 1;
float e = 0.1; /* e decides the accuracy level*/
while(x - y > e) {
x = (x + y)/2;
y = n/x;
}
root->rootInt = (int)x/2;
root->rootFraction = (int)(x-root->rootInt)*100;
return root;
}
int main(){
RootStruct* roo+t=(RootStruct* )malloc(sizeof(RootStruct));
printf("the sqrt is %d\n%d\n",root->rootInt,root->rootFraction);
return 0;
}
What is wrong with this code?
You never call isqroot()... so root->rootInt and root->rootFraction are never set.
You also have a typo in
RootStruct* roo+t=(RootStruct* )malloc(sizeof(RootStruct));
it should be
RootStruct* root=(RootStruct* )malloc(sizeof(RootStruct));
without the +. However, this is unnecessary as you allocate memory in isqroot() and should probably be replaced by
RootStruct* root = isqroot(9);
Then don't forget to free() the memory at the end of main().
Just to note, you also shouldn't case the result of malloc() in C.
You have also implemented the algorithm incorrectly, it should be
RootStruct* isqroot (int n) {
RootStruct* root=(RootStruct* )malloc(sizeof(RootStruct));
float y = 1;
float e = 0.1; /* e decides the accuracy level*/
while(fabs(n - y*y) > e) {
y = (y + (n / y)) / 2;
}
root->rootInt = (int) y;
root->rootFraction = (int) (y - root->rootInt) * 100;
return root;
}
where the complete corrected program is then
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
struct rootStruct {
int rootInt;
int rootFraction;
};
typedef struct rootStruct RootStruct;
RootStruct* isqroot (int n) {
RootStruct* root=(RootStruct* )malloc(sizeof(RootStruct));
float y = 1;
float e = 0.1; /* e decides the accuracy level*/
while(fabs(n - y*y) > e) {
y = (y + (n / y)) / 2;
}
root->rootInt = (int) y;
root->rootFraction = (int) (y - root->rootInt) * 100;
return root;
}
int main() {
RootStruct* root = isqroot(9);
printf("The sqrt is %d.%d\n", root->rootInt, root->rootFraction);
return 0;
}
The Wikipedia article on Computing Square Roots has a very easy to understand section on the Babylonian method.

Resources