Global variable showing abrupt behavior - c

here is my code.
#include <stdio.h>
#define MAX(a,b) ((a)>(b)?(a):(b))
#define SZA(a) (sizeof(a)/sizeof(a[0]))
int anish=0; // global variable showing abrupt behaviour
int a[]={0,1,5,8,9,10,17,17,20,24,30};
int n= SZA(a);
int cache[100];
int road(int len)
{
anish++;
if(cache[len]!=-1)
return cache[len];
if(len<=0)
return 0;
int max=0;
int i;
for(i=1;(i<n && len>=i);i++)
{
max=MAX(max,a[i]+road(len-i));
}
return cache[len]=max;
}
void f()
{
anish=13;
}
int main()
{
int i;
for(i=0;i<=13;i++)
cache[i]=-1;
int len=10;
// f();
printf("%d %d\n",road(len),anish);
return 0;
}
In this, road() is a recursive function and I want to calculate the number of times this function is being executed. So, I am doing this via a global variable anish.
But the value of anish is not changing in this road() function, while in function f() value of anish is being modified.
Any reason for this absurd behavior?

your c code shows an outdated anish variable
succesive printf's shows different value
this has something to do with c's internals
it has something to do with this : Parameter evaluation order before a function calling in C
loki astari said:
The order that function parameters are evaluated is unspecified
behavior. (This won't make your program crash, explode, or order
pizza... unlike undefined behavior.)
The only requirement is that all parameters must be fully evaluated
before the function is called.

In
printf("%d %d\n",road(len),anish);
the order in which the arguments are evaluated is unspecified. In this case, it seems anish is evaluated before road(len), so the value passed to printf is the unmodified value.
Evaluate road(len) before calling printf and store the result in a temporary variable.

Try this instead:
int main()
{ int i;
for(i=0;i<=13;i++)
cache[i]=-1;
int len=10;
// f();
printf("%d\n",road(len));
printf("%d\n", anish);
return 0;
}
Most likely what is happening is printf() is using the value of anish before road(len) returns.
See this for the details.

If you do it like this, it'll work:
printf("%d ",road(len));
printf("%d\n",anish);
may be its because of something inside the printf definition,

Related

Hidden rocks of func3(func1(), func2())?

Is there any problem with using another function call as a function parameter in C?
int foo1(int a){/*does something */ return a;}
int foo2(int b){/*does something */ return b;}
int foo3(int a, int b){return a+b;}
int result = foo3(foo1(1),foo2(2)); /*result is 3 */
To expand on tstanisl's comment
int foo1(int a) { puts("ONE"); return a++; }
int foo2(int b) { puts("TWO"); return b++; }
int foo3(int a, int b) { return a+b; }
int result = foo3(foo1(1),foo2(2));
There is no specific order for the prints. Any of
ONE TWO
TWO ONE
is possible. Can even change next time you recompile (or run) your executable!
There's no problem with the code in your question.
That code looks very much like it's intended to demonstrate a potential problem with calls like foo3(foo1(1),foo2(2)), but it fails to do so.
For example:
int foo1(int a){return a++;}
The expression a++ has a side effect, but one that's irrelevant. The parameter a is a local variable, and it ceases to exist when the function returns. It might as well be just return a; (except for possible undefined behavior if the increment overflows).
This:
int n = 42;
int func(int param) { return param++; }
returns the value 42 and does not affect the value of n. The ++ applies to a copy of n, not to n itself. Function arguments in C are passed by value.
The potential problem with that kind of call is that the order of the evaluation of the arguments is unspecified. The calls foo1(1) and foo2(2) have no side effects that are visible to the caller, but a call like foo3(a++, a++) would, and could yield different results depending on the unspecified order in which the arguments are evaluated. (I'm not 100% certain whether that case has undefined behavior; it depends on whether there's a sequence point between the evaluations of the arguments. But that uncertainty alone is more than enough reason to avoid writing code like that.)

What happens when you call a function with return value without assigning it to any variable?

#include <stdio.h>
#include <stdlib.h>
int f(int x) {
return x;
}
int main ( int argc,char * argv[]) {
int a=4;
f(a);
printf("PASSED!\n");
return 0;
}
What happens when you call f(a) without assigning it to anything?
What happens when you call a function with return value without assigning it to any variable?
The return value of a function need not be used or assigned. It is ignored (usually quietly).
The function still executes and its side effects still occur.
Consider the 3 functions: int scanf(), int f(), and int printf(), their return values are all ignored yet the functions were still executed.
int a=4;
scanf("%d", &a);
f(a);
printf("PASSED!\n");
It is not good to ignore return values in robust code, especially scanf().
As commented by #Olaf, a warning may be enabled by some compilers.
Explicit ignoring the result of a function is sometime denoted with (void) to quiet that warning.
(void) f(a);
Using your example, we can look at how it evaluates line by line. Starting in main.
int a=4;
We now have a variable a with the value 4.
f(a);
So now the function f is called with a, which has a value of 4. So in the function f, the first parameter is named x and it just returns that parameter x.
So the evaluation of
f(a);
is just
4;
And a program like this compiles and runs perfectly fine.
int main(int argv, char *argv[]) {
1 + 1;
return 0;
}
What happens when you call f(a) without assigning it to anything?
--> Nothing at all.
What happens when you call a function (which has return value) without assigning it to anything?
-->The function will be executed, either make no sense like your case or make a lot of senses like modifying a static variable or a global variable. The return value will be ignored.
The return value will normally be stored in a register and will not fade.
It will be overwritten when the register is needed by the compiler.
If the function is inline it may be detected by the compiler that the value isn't used and ignore the value from being computed at all.

Declare a void function in C

I am learning C and I am studying functions. So, I read that when I implement my own function I have to declare it before the main(). If I miss the declaration the compiler will get an error message.
As I was studying this example (finds if the number is a prime number),
#include <stdio.h>
void prime(); // Function prototype(declaration)
int main()
{
int num, i, flag;
num = input(); // No argument is passed to input()
for(i=2,flag=i; i<=num/2; ++i,flag=i)
{
flag = i;
if(num%i==0)
{
printf("%d is not prime\n", num);
++flag;
break;
}
}
if(flag==i)
printf("%d is prime\n", num);
return 0;
}
int input() /* Integer value is returned from input() to calling function */
{
int n;
printf("\nEnter positive enter to check: ");
scanf("%d", &n);
return n;
}
I noticed that a function prime() is declared, but in the main, a function, input(), is called and also the function input() is implemented at the bottom. Ok, I thought it was a mistake and I change the name from prime to input.
However if I delete the declaration and I don’t put any there, the program is compiled without errors and it runs smoothly. (I compile and run it on Ubuntu.)
Is it necessary to declare a void function with not arguments?
If you don't have a forward declaration of your function before the place of usage, the compiler will create implicit declaration for you - with the signature int input(). It will take the name of the function you called, it will assume that the function is returning int, and it can accept any arguments (as Bartek noted in the comment).
For this function, the implicit declaration matches the real declaration, so you don't have problems. However, you should always be careful about this, and you should always prefer forward declarations instead of implicit ones (no matter if they are same or not). So, instead of just having forward declaration of the void prime() function (assuming that you will use it somewhere), you should also have a forward declaration of int input().
To see how can you pass any number of the arguments, consider this:
#include <stdio.h>
// Takes any number of the arguments
int foo();
// Doesn't takes any arguments
int bar(void)
{
printf("Hello from bar()!\n");
return 0;
}
int main()
{
// Both works
// However, this will print junk as you're not pushing
// Any arguments on the stack - but the compiler will assume you are
foo();
// This will print 1, 2, 3
foo(1, 2, 3);
// Works
bar();
// Doesn't work
// bar(1, 2, 3);
return 0;
}
// Definition
int foo(int i, int j, int k)
{
printf("%d %d %d\n", i, j, k);
return 0;
}
So, inside the definition of the function you're describing function arguments. However, declaration of the function is telling the compiler not to do any checks on the parameters.
Not declaring a prototype and relying on default argument/return type promotion is dangerous and was a part of old C. In C99 and onward it is illegal to call a function without first providing a declaration or definition of the function.
my question is, is it necessary to declare a void function with not arguments?
Yes. For this you have to put void in the function parenthesis.
void foo(void);
Declaring a function like
void foo();
means that it can take any number of arguments.
If prime is not used, then omit the declaration.
The code won't compile as C++, because the compiler would complain that function input is used but not declared. A C compiler might issue a warning, but C is more relaxed and does an implicit declaration of input as int input() which means that you can pass any value to input and input returns an int.
It is good style to always provide a function declaration before using the function. Only if you do this the compiler can see if you are passing too few, too many or wrongly typed arguments and how to correctly handle the return value (which might be short or char instead of int).

c, pointers, and argument list to printf. confused

Can someone explain why the value of the variable test isn't changed when I run the short code snippet below?
#include <stdio.h>
int f1(char * foo) {
*foo = 'a';
return 0;
}
void main(void) {
char test = 'n';
printf("f1(&test)=%d. test's new value? : %c", f1(&test), test);
}
I know I'm probably missing something really simple. I just don't understand why test isn't changed in f1() because I'm passing it's address in, right? Why does it matter that the actual function call happens in the list of arguments to printf() ?
If I take the call to f1() out of the printf argument list like so:
#include <stdio.h>
int f1(char * foo) {
*foo = 'a';
return 0;
}
void main(void) {
char test='n';
int i;
i = f1(&test);
printf("f1(&test)=%d. test's new value? : %c", i, test);
}
things work as expected.
thanks in advance.
The order in which the arguments to a function call are evaluated is unspecified. Put another way, you can't tell for sure when f1(&test) will be evaluated.
So in your example, perhaps f1(&test) is evaluated after test: slightly counter-intuitively, you don't get to see the side effects of that invocation. But if you print test again after the call, you will indeed see them.
Bottom line, just be careful with function that have side-effects and you should be set.
There is no set order in which function parameters are evaluated. You're banking on the idea that the arguments are evaluated left to right, which can't be assumed.
Just change where you make your function call
#include <stdio.h>
int f1 (char* foo) {
*foo='a';
return 0;
}
int main(void)
{
char test='n';
f1(&test);
printf("test=%c\n", test);
return 0;
}

Returning and manipulating returned values in C

I'm having a hard time understanding the ways C handles returned values. Say for example we have:
int one = 0;
one = foo(); // Why isn't one being assigned 10?
// Clearly there is a difference between these two
printf("%d", one); // one is still 0
printf("%d", foo());
int foo()
{
return 10;
}
I can't seem to elucidate why there is a difference, and why one won't work over the other.
Thank you!
The following program's output is 1010. I compiled it with gcc -Wall -std=c99 main.c -o main.exe So, I think it's either your compiler problem, or you were wrong when claimed that printf("%d", one); prints zero.
#include <stdio.h>
int foo(void);
int main()
{
int one = 0;
one = foo();
printf("%d", one);
printf("%d", foo());
return 0;
}
int foo()
{
return 10;
}
The first argument of printf() is a const char *, (a pointer to an array of const char's), and with printf(foo()) you're trying to use a pointer to address 10, which obviously is out of the range of the program, causing it to not work. However, with printf("%d", one) you are telling printf to print out a number, which does work.
C function is not "function" as in math (or as in functional programming).
It just sequence of actions needed to obtain return value, and this mean that function may obtain side effects.
So think about your example - what if foo() will look like this:
int foo()
{
printf("some text");
return 10;
}
In other words, if you use variable with returned value - you just use value, but if you use function call, you do all computations needed for obtaining value.

Resources