Auto VS Static Variable Scope in C programming - c

Helloo!! I am currently learning about variable scope in C programming, auto, static and extern. I am running this code below and I am not sure why it works. I thought auto variables are only defined in the function it is defined in and does not retain its value? How is it that this code is working? Shouldn't the int a,b be static variables instead?
#include <stdio.h>
void sum(void)
{
auto int a,b;
a = 91; b = 7;
printf("%d + %d = %d\n",a,b,a+b);
}
int main()
{
puts("Calling the sum() function:");
sum();
puts("done");
return(0);
}

Your variables are not retaining anything. They're always the same value because you're explicitly assigning them the same values in sum().
a = 91; b = 7;
If you change your code to accept the variables as parameters instead, you'll get the output you would expect.
#include <stdio.h>
void sum(int a, int b)
{
printf("%d + %d = %d\n",a,b,a+b);
}
int main()
{
puts("Calling the sum() function:");
sum(91, 7);
sum(23, 9);
auto int x = 44;
auto int y = 24;
sum(x, y);
puts("done");
return(0);
}
If you try to access x or y from within sum() now, you'll get an error that they aren't in scope.

Related

Both call by value and call by reference work?

I thought that calling function by value will never work, and I should always use call by reference, but trying this code...
// call by value
#include<stdio.h>
int Add(int a, int b)
{
int c = a + b ;
return c ;
}
int main()
{
int x = 2 , y = 4 ;
int z = Add(x,y);
printf("%d\n",z);
}
output will be: 6
it works fine in both ways (call by value & call by reference),
// call by reference
#include<stdio.h>
int Add(int* a, int* b)
{
int c = *a + *b ;
return c ;
}
int main()
{
int x = 2 , y = 4 ;
int z = Add(&x,&y);
printf("%d\n",z);
}
output will be: 6
not like the famous swap function example - when calling by value it doesn't swap -
// call by value
#include <stdio.h>
void swap(int a, int b)
{
int temp;
temp = b;
b = a;
a = temp;
}
int main()
{
int x = 1 , y = 2;
printf("x = %d , y = %d\n", x,y);
swap(x, y);
printf("after swapping\n");
printf("x = %d , y = %d\n", x,y);
return 0;
}
.. it only worked calling by reference
// call by reference
#include <stdio.h>
void swap(int *a, int *b)
{
int temp;
temp = *b;
*b = *a;
*a = temp;
}
int main()
{
int x = 1 , y = 2;
printf("x = %d , y = %d\n", x,y);
swap(&x, &y);
printf("after swapping\n");
printf("x = %d , y = %d\n", x,y);
return 0;
}
So How can I judge if "calling by value" going to work or not ?!
So How can I judge that call by value method is valid or not ?!
Well, it depends on what your function is about to do.
In your above example, you only need the values of (x,y) for computing, but you never plan to change their value during your function. While call-by-reference will work in this case, it is unneccessary.
In the other (indirectly given) example you obviously want to change two variable's content (that is - swap it). You can access these variables from the main-function in your Swap-function, but how can you make the change persistent? That's only possible by call-by-reference, because you have to write the changed content into a variable that survives the function.
The following will not work:
// call by value
#include<stdio.h>
void Swap(int a, int b)
{
int c = a;
a = b;
b = c;
// from here on a, b, c will be destroyed
// therefore the change cannot be seen outside the function
}
int main()
{
int x = 2 , y = 4 ;
Swap(x,y);
printf("x: %d --- y: %d\n",x,y);
}
So as a rule to keep in mind:
If you want to make a change that's supposed to survive the function's end, use call-by-reference. If you just work with some data but do not want to (or must not) change their value, use call-by-value.

How to modify a local variable of one function from other function?

int main ()
{
int a, b;
call(&b);
printf("%d, %d",a , b);
}
void call(int *ptr)
{
}
Desired output:
50, 100
How to write the call function so as to modify both the variables to get the desired output??
Not sure where the values 50 and 100 are coming from or exactly what you are asking but maybe this will help with your question.
Since C is pass by value you need to send pointers to actually change the value inside another function.
Since the call function will have pointer values you need to dereference the pointers before changing the value.
Here is an example:
void call(int *a, int *b)
{
*a = 50;
*b = 100;
}
int main()
{
int a, b;
call(&a, &b);
printf("%d, %d\n", a, b);
}
While we are exploring the many ways this output could be achieved, consider that the function could store state in a static variable:
#include <stdio.h>
void call(int *ptr);
int main(void)
{
int a, b;
call(&a);
call(&b);
printf("%d, %d\n",a , b);
}
void call(int *ptr)
{
static int store = 0;
store += 50;
*ptr = store;
}
Program output:
50, 100
Note that you may also be able to do this as follows, without any modifications to main(). But be warned that this method invokes undefined behavior! It is undefined behavior to write to a location past the end of an array object, and in the case of a and b, these are considered to be array objects of size 1. Here we are assuming that this write will work, and that a and b are stored next to each other in memory. We further assume that a has the higher address in memory.
I would say that you should never do this, but I can see no other way to modify a from the function call() without knowing the address of a. You have been warned.
void call(int *ptr)
{
*ptr = 100;
*(ptr + 1) = 50;
}
Try something like this:
void call(int *ptr)
{
*ptr = 100;
}
int main ()
{
int a, b;
a = 50;
call(&b);
printf("%d, %d",a , b);
}
See demo
Maybe you want this:
int main ()
{
int a, b;
call(&a, &b);
printf("%d, %d",a , b);
}
void call(int *ptr1, int *ptr2)
{
*a = 50;
*b = 100;
}
To change a local variable in function a by calling function b you have two options.
1) Let function b return a value that you assign to the variable in function a. Like:
int b() {return 42;}
void a()
{
int x = b();
printf("%d\n", x);
}
This does, however, not seem to be what you are looking for.
2) Pass a pointer to the variable to function b and change the variable through that pointer
void b(int* p) // Notice the * which means the function takes a pointer
// to integer as argument
{
*p = 42; // Notice the * which means that 42 is assigned to the variable
// that p points to
}
void a()
{
int x;
b(&x); // Notice the & which means "address of x" and thereby
// becomes a pointer to the integer x
printf("%d\n", x);
}
int main()
{
int a,b;
call(&b);
printf("%d, %d\n", a,b);
}
int call(int *ptr)
{
int *m;
m = ptr++;
*ptr = 50;
*m = 100;
}

Swapping variables with a function doesn't affect the call site

A few lessons ago I learned about variables, and got a question in my homework about swapping two numbers - I used a third variable to solve this question.
The solution looked somewhat like this:
#include <stdio.h>
int main(void) {
int x, y;
scanf("%d %d", &x, &y);
// swappring the values
int temp = x;
x = y;
y = temp;
printf("X is now %d and Y is now %d", x, y);
}
Now I'm learning about functions, and I wanted to try and solve the previous question with a helper swap function.
This is the code I've written:
#include <stdio.h>
void swap(int x, int y) {
int temp = x;
x = y;
y = temp;
}
int main(void) {
int a = 3, b = 4;
swap(a, b);
printf("%d %d\n", a, b);
}
I don't know why, but the output is still 3 4 even though I changed the value inside the swap() function.
Why is this happening?
Pass address of x and y as arguments to function. Right now they are local variables, changes are not made to original variables .
Do as follows-
void swap(int *x,int *y){
/* dereference pointers and swap */
int temp = *x;
*x = *y;
*y = temp;
}
And call in main like this -
swap(&x,&y);
What you are doing is passing parameter by value. It means that during the function call, copies of parameters are created. So inside the function you are working on copies of actual variables.
Instead you need to pass it as a reference. Please read more about pass-by-value vs pass-by-reference.
#include <stdio.h>
void swap(int& x,int& y) //Instead of passing by value just pass by reference
{
int temp=x;
x=y;
t=yemp;
}
int main() {
int a=3,b=4;
swap(a,b);
printf("%d %d\n",a,b);
return 0;
}
EDIT:
C does not have references. Above code will work in c++ instead. To make in work in C, just use pointers and de-reference it inside the function.

C: Having an issue with scope

so I'm studying for a final and we are given this block of codeL
#include <stdio.h>
int a;
void addOne(void) {
a++;
printf(“W. a = %d\n”, a);
}
int removeOne(int a) {
int b = a – 1;
printf(“R. b = %d\n”, b);
}
void swap(int a, int *b) {
int temp = a;
a = *b;
*b = temp;
}
int main() {
a = 5;
int b = 20;
if (b > 15) {
int a = 53;
removeOne(b);
addOne(a);
printf(“X. a = %d\n”, a);
}
printf(“Y. a = %d, b = %d\n”, a, b);
swap(a, &b);
printf(“Z. a = %d, b = %d\n”, a, b);
return 0;
}
We are instructed to give the outputs of the program. I'm having trouble with the addone(a) where I came up with 54, the correct answer was 6. Is it 6 because when the function is declared it has the void (don't remember the technical term but the information it takes in to the function) rather than something like int a?
My more direct question is why does the function take the a initialized in the main function rather than the a in the if?
The reason that the answer is 6:
Note at the top that a is declared as a global. Later, in main there is a call to addOne(a) inside of a code block. That code block defines a local variable a as well. The a that is passed in that scope is the local a (53). It is passed into a function that accepts an unnamed void variable. In that function, however, there is a reference to a. Due to scoping, this will be the global a (5), so a++ will result in an output of 6.
That is a horrible exam question.

C Program Compile Error: Undefined reference to function 'compare'?

Here is my code:
#include <stdio.h>
#include <stdlib.h>
int compare(int a, int b);
main()
{
int x,y;
x = 2, y = 1;
printf("%d", compare(x,y));
int compare(int a, int b)
{
int returnValue = 0;
if(a>b)
returnValue = 1;
else if(a<b)
returnValue = -1;
else
returnValue = 0;
return(returnValue);
}
}
And this is the compiler error that I recieve:
In function `main':
asdf.c:(.text+0x21): undefined reference to `compare'
collect2: error: ld returned 1 exit status
I have looked into this problem, and every question that I can find with this error is because people are importing functions from different files. These two functions are in the same file, and the compare() function is declared before the main(). I would appreciate any help as to why I am getting this error.
Thank you for your time.
You must define function outside the main function.
your code should be:
#include <stdio.h>
#include <stdlib.h>
int compare(int a, int b);
main()
{
int x,y;
x = 2, y = 1;
printf("%d", compare(x,y));
}
int compare(int a, int b)
{
int returnValue = 0;
if(a>b)
returnValue = 1;
else if(a<b)
returnValue = -1;
else
returnValue = 0;
return(returnValue);
}
The function compare must be out side the main program. Either you define the function header before the main() and have the function after the main or have the function before the main().
#include <stdio.h>
#include <stdlib.h>
int compare(int a, int b);
main()
{
int x,y;
x = 2, y = 1;
printf("%d", compare(x,y));
}
int compare(int a, int b)
{
int returnValue = 0;
if(a>b)
returnValue = 1;
else if(a<b)
returnValue = -1;
else
returnValue = 0;
return returnValue;
}
Nested function does not exist in C. But again speaking that it's a compiler specific
You can see gcc extension for nested function which is nonstandard.
So for solution simply move your function definition to outside the main.
You've declared the global function compare at file scope, but only defined a nested function main::compare. As commenters have pointed out, this is not standard C, it's a gcc extension that you don't want to be using.
Move compare out to file scope:
int main()
{
// do stuff
return 0;
}
int compare(int a, int b)
{
// do stuff
return value;
}
Put compare function out of main function. C language doesn't allow functions defined inside other functions.
Code
#include <stdio.h>
#include <stdlib.h>
int compare(int a, int b);
int main(void )
{
int x,y;
x = 2, y = 1;
printf("%d\n", compare(x,y));
}
int compare(int a, int b)
{
return ((a<b) - (a>b));
}
You have two different functions compare: One at global scope, which is only declared, but not defined, and one defined at local scope. The local compare can only be called from local scope, but only after it is defined. (Declaring a nested function inside the body of main before its definition doesn't work, because the C standard permits declarations in function bodies, but treats them as global.)
If you must use nested functions, move the definition of your local compare to the beginning of main. Nested functions are non-standard.
It is better to move the definition of compare outside the function into file scope. If you keep the definition of compare close to where it's called and make it static, you will get the same behaviour.

Resources