In my principles of programming class we are talking about different calling methods. Some we discussed were:
call by value
call by reference
call by value/result
and call by name
I can't find an example of how call by name works. Anyone care to give me an example? I think that when you take an xml file as input this is similar to call by name. Could someone give me a more traditional example?
I'll work in a hypothetical programming language. Let's assume we have a function p(x) that prints out x and then returns it. Now let's define a function:
function foo(x, y) { return y+1; }
Now let's call it with some arguments:
foo(p(123),p(456))
x and y are going to be substituted for the parameters, so the call to foo above is going to result in:
return p(456)+1;
So we're going to print 456 to the screen and return 457. In another evaluation strategy, we would evaluate the function parameters first (printing 123 and 456 to the screen in the process) and then substitute 456 for y in the function body, eventually returning 457.
It's contrived, but I hope you get the idea. It's all about substitution.
http://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_name
In call by value, you evaluate arguments, retrieving values that are then passed to the function.
foo(bar()) is evaluated as arg = bar();, then foo(arg) is called, and in the body of the function, this newly allocated arg variable is accessible, modifiable, ...
In call by name, you substitues in the body of the function any references to arguments by their code used during the call. Then, evaluating the body, you will evaluate the arguments.
foo(bar()) with foo(arg) { return arg; } will be evaluated as foo(arg) { return bar(); }
Call by name work as call by reference when actual parameter be scaler, but be different when actual parameter is expression or array then actual parameter is re-evaluated on each access.
here is simple example
begin
integer n;
procedure p(k: integer);
begin
print(k);
n := n+1;
print(k);
end;
n := 0;
p(n+10);
end;
call by value output => 10 10
call by name output => 10 11
Related
I've seen a C program that prints 1 to 1000 without using any looping structure or conditional statements, but I don't understand how it works. Can anyone go through the code and explain each line?
See live demo here. Why does it result in a runtime error?
#include <stdio.h>
#include <stdlib.h>
int main(int i)
{
printf("%d\n",i);
((void(*[])()){main, exit})[i / 1000](i + 1);
return 0;
}
((void(*[])()){main, exit})[i / 1000](i + 1);
This line create a two-element array of function pointers, with the first element containing the main function, and other element containing the exit function.
It then indexes this array by i / 1000. This either gets the main function if i < 1000 or the exit function when i == 1000.
It then calls the function pointer that it just indexed with i+1 as the argument.
It's a recursive function, with the stopping condition determined with an array index rather than a conditional. I don't think it's valid C however; main's signature is wrong, and the cast to a function pointer removes the return type from the main function.
Breaking down the line that you asked about
((void(*[])()){main, exit})
This is an array literal, which creates an unnamed temp array of two function pointers, and initializes those pointers to point at main and exit
[i / 1000]
This indexes that temp array. Integer division truncates towards 0, so when 0 <= i < 1000, this gets element 0 (the pointer to main) and when 1000 <= i < 1999, it gets element 1 (the pointer to exit)
(i + 1);
This calls the pointed at function with i+1 as an argument.
There are a bunch of things here that are undefined behavior. Declaring main as having a single int argument is illegal according to the standard, though generally will work, getting the number of command line arguments as the single argument. Getting a pointer to main is likewise undefined, as main is a special function that may have a non-standard calling convention.
This code is a good example of how far you can bend C without breaking it. You shouldn't attempt to understand this until you can write understandable C.
Here are the key features and assumptions:
First, assume that the program is called without arguments. The parameter i is in the place usually called argc, so it will have the initial value 1 (the number of elements in the array of arguments, usually called argv).
Next, assume that the single-argument form of main doesn't cause any problems. Officially supported forms of main are with no arguments, 2 arguments (argc, argv), and sometimes 3 arguments (argc, argv, envp).
So the first printf prints 1.
Next we have a compound literal. It might be easier to understand if you look at a simpler one first:
(int[]){10,20}
That's an anonymous array of 2 ints, with values 10 and 20. int[] is the type. It goes in parentheses before a braced list of values. So what's this:
(void(*[])()){main, exit}
void(*[])() is a type. It means array of function pointers with the signature void (*foo)(). The type name in parentheses followed by a braced list is compound literal, just like the (int[]){10,20} example. In this case, it creates an array of 2 function pointers whose elements are main and exit.
Assume that the mismatch between the function pointer type (returns void) and main (returns int) doesn't cause a problem.
This:
((void(*[])()){main, exit})[i / 1000]
is our anonymous array of 2 elements, inside some redundant parentheses, followed by [i / 1000]. That's just normal array indexing syntax. If i/1000 is 0, you get the first element of the array (thearray[0]), which is main. That happens for all i is between 0 and 999. If i/1000 is 1, which happens when i==1000, we're looking at thearray[1], which gets us the second element: exit.
So far, we have an expression taht is equal to main when i<1000 and equal to exit when i==1000.
Now look at the whole statement:
...that_big_thing_that_is_either_main_or_exit...(i + 1)
A function pointer, followed by a parenthesized argument list. That's a function call. Whichever function we chose from the array, now we're going to call it, providing an argument that is equal to the incoming argument (i) plus 1.
So the first call, when i is 1, selects main for the function and i+1 = 1+1 = 2 for the argument. It calls main(2).
main(2) does a printf which prints the 2, and then calls main(3).
main(3) does a printf which prints the 3, and then calls main(4).
...and so on until...
main(999) does a printf which prints the 999, and then calls main(1000).
main(1000) does a printf which prints the 1000, and then calls exit(1001).
None of the calls to main ever return, and the return 0 never happens, because the exit terminates the process. The fact that the process returns an exit code of 1001 rather than 0 appears to be the reason for ideone's "runtime error" message.
The main function is called recursively.
void print_nb(int n)
{
if (n <= 1000)
{
printf("%d\n", n);
print_nb(n + 1);
}
}
Like Sourav Ghosh said, it's prohibited to use with main() recursively, better use another function.
#include<stdio.h>
find(int x, int y)
{
return((x<y)?0:(x-y));
}
int main(void)
{
int a=find(5,find(5,4));
printf("%d",a);
return 0;
}
The above program gives output as 4. I ran with different values and learnt that the code snippet is to find minumum of two numbers. But, I can't seem to understand how it is working. Can someone explain it for me? I know how the ternary operator works, I didn't get the function call inside function call part.
int a=find(5,find(5,4));
find(5,4) returns 1
find(5,1) returns 4
First the find() function gets executed with 5 and 4 as its paramters. which will cause x<y condition to fail and returns x-y which is 5-4 =1
Later you have find(5,1) which again makes the x<y condition fail returning 5-1 which is 4
Try to break it.
See it this way.
when you say int a=find(5,find(5,4));
then the find function inside the find function i.e find(5,4) returns 1;
Now the resultant value makes it int a=find(5, 1);
And when find find(5,1); is called it returns 4 :)
What's there to "get"?
The function call is, like any other call, evaluated "inside out". All the argument values must be known before the call is made. So, the second argument is find(5,4), thus that call happens first. Then the value of that call is used as an argument in the second, outer, call.
To add to the previously given answers, it is always better to explicitly specify the return type of a function.
Change your find() function signature to
int find(int x, int y);
Next, regarding the function execution order, the flow is inside-out, means, the inner function will be executed first, the return value will be used to execute the outer call.
Diagramatically,
int a=find(5,find(5,4));
can be decomposed as
int a=find(5,find(5,4)); //consider step 1.0
| /*inner find() executes first, returns 1*/
V
int a=find(5, 1 /*result of find(5,4)*/); //consider step 1.1
| /*result of inner find() used for outer find()*/
V
int a=find(5, 1)); //consider step 1.2
| /*outer find() executes second, returns 4*/
V
int a= 4; //consider step 1.3
/* value 4 is assigned to a*/
I'm very new to C, and am writing a few programs to try and understand how variables can be passed and changed in between functions. I wrote a simple program below:
int number;
int test( int number ) {
number = 3;
return(number);
}
int main () {
printf ("\nPlease enter in any number between (10 - 99,999)!\n");
scanf("%d", &number);
test(number);
printf ("\nYour number probably wasn't: %d\n", number);
}
The point was to enter in a number, but no matter what you enter that number would be changed to 3. For some reason though when i call test on that number, it will not change to 3 but instead be whatever the user entered. Note that I am trying to change the variable number, and not have any other variable hardcoded as 3.
How come this does not work?
Change
test(number);
to
number = test(number);
Otherwise the value returned by test will be discarded and you will get the number you entered, not 3.
Another way to get the desired effect is to pass the pointer to number:
void test( int *number ){..}
and call the function as
test(&number);
Some answers suggested that to use number as global variable. I advice you that do not use global variable when it is unnecessary.
You are changing a local variable in the function test, not the actual variable. You want number = test(number); as the second to last line in your main() function.
Your function test doesn't deal with the original number that you passed to it. Instead, it gets a copy of this variable and plays around with it locally. Any changes you make to number in this function will get lost (unless you pass in a reference, which you will learn about later, presumably). The correct way to get around this is, as you have already done, return the value of number. However, you don't use that returned value at all. When you say number = test(number);, you are telling the computer to take that returned value and assign it to the original number (the one in your main), which is what you want.
int number; //a
int test( int number ) { //b
number = 3;
return(number);
}
Within test, there are actually two variables named number,
a (which is the number used in main too), and b which has priority.
You´re changing the parameter b to 3.
However, the parameter is only a copy of the original passed value in main
(as usual in C and C++), and gets discarded and the end of test.
Furthermore, you´re not using the return value in main, so 3 is gone.
Perhaps you misunderstand the idea of 'variable scope'.
int number;
The first occurrence of the variable 'number' is declared outside of all functions (and braces). Hence, it has "global" scope.
int test( int number ) {
The variable 'number' defined as an argument to test() has a limited scope. Its life, and visibility, is limited to the braces of the test() function. Outside these braces, this 'number' variable does not exist.
The 'global' variable 'number' and the 'test()' variable 'number' are distinct from each other, each with its own unique value.
Being they are named the same, the 'global' variable 'number' becomes inaccessible inside the 'test()' braces. Hence, any manipulation of the 'number' within the braces of 'test()' does not have any effect on the 'global' variable 'number'.
number = 3;
The above has no effect on the 'global' variable 'number'. Rather it only initializes the 'local' variable 'number' to 3.
return(number);
The above will return the value of the 'local' variable 'number' (3).
}
int main () {
printf ("\nPlease enter in any number between (10 - 99,999)!\n");
scanf("%d", &number);
The line above sets the 'global' variable 'number' to a value entered by the user.
test(number);
The line above passes the value of the 'global' variable 'number' to test. It does not capture the 'return' value (3) returned by test. If desired, the above line could be rewritten:
number=test(number);
The above line would set the 'global' variable 'number' to the return value of test (3).
printf ("\nYour number probably wasn't: %d\n", number);
}
All answers so far seem to ignore the fact that you are trying something which does not make much sense. You are returning what is basically a constant from your function, but using a passed value as some intermediate storage while that is completely unnecessary. Either of those two will work:
void test( int& number ) {//We don't need to return anything, because we pass number by reference, and so changes made to it will persist outside this functions scope
number = 3;
}
int test(){
return 3; //We just return 3, we don't need any arguments passed to the functions in this version
}
Now in the first case you call the functions as
test(number); //number will be changed by test because it's passed by reference
in the second case you call the functions as
number = test(); //Here test just returns 3 and we assign that value to number.
Edit:
Just for completeness sake I will add the third version that you can use:
void test(int* number){//Here we pass a pointer to an integer to test
*number = 3;//and change the value pointed to be number to 3. Read * as 'value pointed at by'. So this says 'value pointed at by number = 3'
}
in this case you call the function as
test(&number)//read & as 'pointer to'. So now we pass 'pointer to a' to test.
Note that this version is basically a less elegant and more error prone version of the first version I mentioned (at least in this specific scenario). Their usage and effects are more or less equal, but in the first version you do not need to concern yourself with dereferencing and the general fact that you are working with pointers.
Your code never does anything with the value test returns. Your code would be easier to understand if you didn't call both variables (the one in main and the one in test) number.
You have 2 options. One is
number = test(number);
Second is refer Pointers in C. Pass by address would do the trick for you.
It doesn't work because you're doing a pass by value instead of a pass by reference. If you want the value of number to be always 3 without doing an assign when you call the function, then you should do something like:
void test(int *number){
*number = 3;
}
and call like:
test(&number);
This documentation gives an example of how to write a varargs function, printf() .
As the documentation, printf() will find the first % in the string and use va_arg(argp, int) to get the first argument pointer; find the second % in the string and use va_arg(argp, int) again to get the second argument pointer......
So, I wrote a code snippet:
int Var = 0;
int Func (int X)
{
Var = Var + X;
return Var;
}
int main (void)
{
printf ("%d\n%d", Func (3), Func (5));
}
It will print:
8 <-- 5+3
5 <-- 5
I know calling multiple functions in printf() is undefined behavior, but why not print:
3 <-- 3
8 <-- 3+5
just as the sample code in that documentation?
ps: If my question is not clear, please help me edit it. Thanks
The order that function parameters are evaluated in C is platform dependent (not undefined, just unspecified).
See this blog that talks about it: Funny thing about C parameter evaluation order…
If you want to force the order, you would call Func() before the printf():
int a = Func(3);
int b = Func(5);
printf("%d\n%d", a, b);
While it's true that parameter evaluation order isn't defined, parameter placement is. The so called C calling convention states that parameters are pushed to the stack from right to left. This order is needed precisely to support variable parameter functions. Normally, as each parameter is evaluated, it is inmediately pushed into the stack (although some obscure optimizations in order to optimize memory writes might alter this), so we could expect that parameter evaluarion works by evaluating them from right to left.
That would mean that Func(5) is first evaluated, pushes 5 into the stack, then Func(3) is evaluated, pushing 8 to the stack. Parameter order, as it will be printed by printf are 8 and 5.
I'm a student and new to C. One of the questions for my homework reads as follows:
max is a function that accepts two int parameters and returns the
value of the larger one. Four int variables, population1 ,
population2 , population3 , and population4 have already been
declared and initialized. Write an expression (not a statement!)
whose value is the largest of population1 , population2 ,
population3 , and population4 by calling max . (HINT: you will need
to call max three times and you will need to pass the return values
of two of those calls as arguments to max . REMEMBER: write an
expression, not a statement.)
I understand the logic of it:
Call the function max with the first two variables, the function will return the larger of the two and then take that value (somehow pass it without assigning to a fifth declared variable) and compare it to the third variable's value. Take the larger of the second pairing (again passing it without the benefit of a new variable - remember it's an expression, not a statement) and compare it to the forth value. However I haven't been able to write the correct syntax.
Also, understand that this is a 100 level class. So anything higher level will not be accepted for this particular question. No libraries to be #include(d).
Well you seem to understand how to do it, and yes the question seems to ask you to not assign returned values to new varibles. You can basically chuck in a max() as a parameter to another max(), and the return of the inner max() will be the int for the outer max() parameter.
Since c is strict, it won't compile unless the return type for the function is the same as the parameter (in this case, both are int, so it's fine)
max(2, max(3, 4)); // inner returns 4, which puts 4 into the outer max, and compares 2 to 4
Function calls can be nested. Here's a hint:
max(population1, max(...))
Can you come up with the correct code for the ...?
A function which returns something different that nothing (void) can be used inside an expression freely. An expression is defined recursively since it is made by sub-expressions until you reach terminal symbols (as constants or function calls).
So there is nothing strange in understanding the syntax, a call to max is synctatically equivalent to a numeric constant.
int x = 5;
int y = max(5,10);
int z = 5 + 10;
int k = max(5,10) + 3;
int j = max(3 + 2, 8);
These are all legal. Of course the assignment is just for clarity, as as assignment is a statement, not just an expression anymore.