In C, suppose var1 is a variable in foo1() and foo2() wants to access var1, however, foo1() doesn't call foo2(), so we can't pass it by parameter. At the same time, only foo1() and foo2() will access it, so I wouldn't like to declare it as global variable. It will be similar with the "friend semantics" in c++, is there any way to implement this in C?
void foo1() {
...
var1;
....
}
void foo2() {
...
how to access var1?
...
}
you pass the variable to both functions.... in general functions shouldn't hold state.
quickly you find passing variables is not so nice and becomes fragile, so instead, you pass structs.... then functions start working on the state of structs.
typedef struct
{
int var1;
} blah_t;
void foo1(blah_t* b)
{
b->var1=0;
}
void foo2(blah_t* b)
{
b->var1++;
}
this is the very simplistic seed idea behind doing OO C.
You need to declare var1 outside the scope of the functions and then send it as a parameter to both. Alternatively, declare it as a global variable.
by reference is one way: (in this example the memory for i is local to caller())
void caller()
{
int i = 5;
foo(&i);
bar(&i);
printf("\n final i is %d",i);
}
void foo(int *i)
{
printf("%d",*i);
*i += 5;
}
void bar (int *i)
{
printf("%d",*i);
*i += 5;
}
global: (usually considered horrible i would have a name more like GLOBAL_I or something)
int i = 0;
void caller()
{
i=5;
foo();
bar();
printf("\n final i is %d",i);
}
void foo()
{
printf("%d",i);
i += 5;
}
void bar (int i)
{
printf("%d",i);
i += 5;
}
Regarding similar with the "friend semantics" in c++. C does not have the same capability.
Regarding so we can't pass it by parameter
The only option in C for accessing a variable from function to function without passing as a function parameter is to use some type of global scope variable.
In the event void foo1() and void foo2() exist in different C modules...
but you still want to be able to access the same variable, and ensure its value is the same at all times, in all places within your project, then consider using extern scope:
Within a header file that is common to both (multiple) modules, a project scope global can be implemented as follows.
file.h
void foo1(void);
void foo2(void);
extern int var1;
file1.c
#include "file.h"
int var1 = 5; //in only 1 module, declare and initialize the
//extern defined in the common header -file.h-
int main(void)
{
printf("value of var1 is %d\n", var1);//original value of var1
foo1();
printf("value of var1 is %d\n", var1);//var1 modified by foo1()
foo2();
printf("value of var1 is %d\n", var1);//var1 modified by foo2()
return 0;
}
void foo1(void)
{
var1 = 15;//Now that the project global variable
//has already been declared and defined, it can simply
//be used, in this file...
}
file2.c
#include "file.h"
void foo2(void)
{
var1 = 20;... and in this one
}
No. The variable only exists on the function stack while foo1() is running. The stack will vanish when leaving the function. You could make the variable static to keep it alive, but then you can't access it from the outside either without hacks.
This answer is inspired by the 'Module' concept, found in many other languages, which can be approximated using gcc's nested functions. Variable var1 is within scope for both foo1() and foo2(), but is out of scope for everything else. The solution uses neither global vars nor parameters.
void foo(int fn)
{
static int var1;
void fn1(void)
{
var1 = 15;
}
void fn2(void)
{
var1 = 20;
}
(fn == 1)? fn1(): fn2();
printf("Value of var1 is now %d\n", var1);
}
void foo1(void){foo(1);}
void foo2(void){foo(2);}
int main (void)
{
foo1();
// Expected stdout: Value of var1 is now 15
foo2();
// Expected stdout: Value of var1 is now 20
}
Related
I had this assignment at school, wherein I had to find the output of the following C code, and also, to explain the output.
#include<stdio.h>
int i;
void fun1(void);
void fun2(void);
int main()
{
fun1();
fun2();
return 0;
}
void fun1(){
i=20;
printf("%d\t",i);
}
void fun2(){
int i=50;
printf("%d",i);
}
The output is 20 50
Because in fun1() the Global Variable 'i' is assigned to 20 and printed. And in fun2() the variable 'i' is a Local Variable, which is declared and initialized to 50, which is then printed.
I have this following question out of curiosity, how do I use the global variable 'i', in fun2()?
A simple solution would be to simply change the name and avoid the whole thing. But my curiosity is due to Java, where there is a keyword "this" to access class variable instead of a local variable.
so is there any way to do that in C?
The only way is to hide the declaration of the local variable in a code block.
For example
#include <stdio.h>
int i = 10;
void fun2( void )
{
int i = 20;
printf("local i = %d\n",i);
{
extern int i;
printf( "global i = %d\n",i);
}
}
int main(void)
{
fun2();
}
The program output is
local i = 20
global i = 10
There is no way to access a global parameter inside a function that has a local variable with the same name. It is usually bad practice to create such local variables in C though, as you saw, it is not prohibited.
In C++ you can solve it using namespaces but there is no equivalent in C.
The best way is to pass parameters to the function
void fun2(int fromExternalWorld){
int i=50;
printf("%d ",fromExternalWorld);
printf("%d\n",i);
}
int main(void)
{
fun2(i);
}
Otherwise is not possible to have two symbols with same name visible in the same scope.
You could cheat and create a pointer to the global i before declaring the local i:
void fun2( void )
{
int *ip = &i; // get address of global i
int i = 50; // local i ”shadows" global i
printf( "local i = %d, global i = %d\n", i, *ip );
}
EDIT
Seeing as this answer got accepted, I must emphasize that you should never write code like this. This is a band-aid around poor programming practice.
Avoid globals where possible, and where not possible use a naming convention that clearly marks them as global and is unlikely to be shadowed (such as prefixing with a g_ or something similar).
I can't tell you how many hours I've wasted chasing down issues that were due to a naming collision like this.
See the comments to see what is being referred as declaration.
If the whole variable declaration part was missing, what would be the problem?
Appears that variable definition and initialization either simultaneously or separately like in the example would suffice.
#include <stdio.h>
// Variable declaration:
extern int a, b;
extern int c;
extern float f;
int main () {
/* variable definition: */
int a, b;
int c;
float f;
/* actual initialization */
a = 10;
b = 20;
c = a + b;
printf("value of c : %d \n", c);
f = 70.0/3.0;
printf("value of f : %f \n", f);
return 0;
}
If the declaration was missing then it would create no problem in main function since the locally defined variables i.e. a,b,c,f will be used in the functionality of main till its scope ends.
The declaration merely tells that the definition lies elsewhere (in some other .c file) or the definition lies after the function main in the same .c file.
There will be no problem here if the mentioned declaration is missing.
// Variable declaration:
extern int a, b;
extern int c;
extern float f;
This tells the compiler that these variables are defined somewhere else(in another file).
/* variable definition: */
int a, b;
int c;
float f;
This is where you define variables but they are not the same as the external variables you declared since they are in the inner scope of the main function.
The scope is the place where variables live. extern keyword notes that the scope is global.
You can define variables with the same name in an inner scope and access only them as you did in the main function but it's not a good practice.
void foo()
{
int a = 5;
printf("%d\n", a); // 5
// Creating an inner scope
{
int a = 20;
printf("%d\n", a); // 20
}
printf("%d\n", a); // 5
}
The correct way to use the extern keyword with variables is like this.
//h1.h
extern int global_var; // Declaration of the variable
//c1.c
#include h1.h
int global_var = 0; // Definition of the global var. Memory is allocated here.
//main.c
#include h1.h
int main()
{
printf("global var value is %d\n", global_var); // use of the var defined and
// initialized in c1.c
return 0;
}
This program will print 0 since the variable is defined and initialized in c1.c.
Extern extends the visibility of the C variables and C functions. so that lets the compiler know that there is another place that those vars are declared and memory was allocated for them elsewhere.
for example in another c file.
if you compile a c file containing a global var for example:
int c = 5;
and you create a function on you c file that uses this c var, for example:
int someFunc(void){
return c;}
if you run someFunc in your main and print its return value, you will get 5. but you must compile both c files together.
in your program, you only use the locally allocated var declared in your main function.
When it comes to simple variables, there is really no difference between the declaration and definition. There is a difference when it comes to structs and functions. Here is an example:
// Declarations
struct myStruct;
int foo();
int main()
{
...
}
// Definitions
struct myStruct {
int a, b;
};
int foo() {
return 42;
}
In your case, you are hiding the previous declarations so that they are not accessible before the end of the scope. This is commonly called shadowing. It's basically the same thing as this:
int main()
{
int i=0;
printf("i: %d\n", i);
{
int i=42; // Now the previous i is inaccessible within this scope
printf("i: %d\n", i);
}
// And now it is accessible again
printf("i: %d\n", i);
}
I am making a program in C in which I am trying to use the values of local variable in other function. Lets say I have two function foo1 foo2.
int foo1()
{
int a=2,b=3,c;
c=a+b;
return c;
}
int foo2(int c)
{
printf("Value of C is %d",c);
}
is this method correct, if not what else is the way to use values of local variable in other function?
first of all, this two functions foo1() and foo2() are not related...
and local variables have block scope only.
If you want to use them in other functions make them global or use pass by value and pass by reference methods to pass the variables from one function to others...
You cannot, and you should not use local variables from other functions directly.
But in your case you are lucky: the value from foo1() you are interested in is returned to the caller.
This way you can use it as you like:
...
int value = foo1();
foo2(value);
...
or even shorter:
...
foo2(foo1());
...
You can do this -
int foo1()
{
int a=2,b=3,c;
c=a+b;
return c;
}
// c will be passed to the function and printed
int foo2(c)
{
printf("Value of C is %d",c);
}
// get the result of foo1()
int val = foo1();
// call foo2() with the result of foo1()
foo2(val);
One way is to make c variable global so that every function can use it.
other way is to call this returning function in foo2() so that the returned value can be printed.
one way:
int foo1(){
int a=2,int b=3;
int c=a+b;
return c;
}
int foo2(){
printf("value of c = %d",foo1()); //returned value of function foo1() used
}
other way is :
int c=0; //defined global
void foo1()
{
int a=2,int b=3;
c=a+b;
}
void foo2()
{
printf("value of c = %d",c);
}
I declare in test.h file
extern void test(int *ptr);
extern void myFunc();
extern int num;
I then include the h file in my test1.c file.
I write my functions in test2.c:
void myFunc( )
{
test(&num);
}
void test(int *num )
{
*num = 9;
}
in test1.c I write:
int num = 5;
myFunc();
My question is, how can i use the num variable/pointer in test() without passing it to myFunc()?
The file structure has to stay the same, thats why I am trying to refresh my C on this,
Than you
Check your scope.
void myFunc( )
{
test(&num);
}
This function can't see the variable num unless num is global, and so it's GIGO (garbage in, garbage out).
I know it looks to you like num IS global, but here's the trick:
int num = 5;
myFunc();
I can't see the full code, but because of your formatting I'm guessing that this is using a local copy of num instead of the extern because you're declaring a new variable in local scope inside of the function where you're calling myFunc(). The extern isn't being used.
if int num is global then any function can use it. Second case if you declare int num as local then I think it is an error or you can't access global num inside function where num is already present as local or write your complete code.
How can I access a shadowed global variable in C? In C++ I can use :: for the global namespace.
If your file-scope variable is not static, then you can use a declaration that uses extern in a nested scope:
int c;
int main() {
{
int c = 0;
// now, c shadows ::c. just re-declare ::c in a
// nested scope:
{
extern int c;
c = 1;
}
// outputs 0
printf("%d\n", c);
}
// outputs 1
printf("%d\n", c);
return 0;
}
If the variable is declared with static, i don't see a way to refer to it.
There is no :: in c but you can use a getter function
#include <stdio.h>
int L=3;
inline int getL()
{
return L;
}
int main();
{
int L = 5;
printf("%d, %d", L, getL());
}
If you are talking about shadowed global var, then (on Linux) you can use dlsym() to find an address of the global variable, like this:
int myvar = 5; // global
{
int myvar = 6; // local var shadows global
int *pglob_myvar = (int *)dlsym(RTLD_NEXT, "myvar");
printf("Local: %d, global: %d\n", myvar, *pglob_myvar);
}
If you want your code to look sexy, use macro:
#define GLOBAL_ADDR(a,b) b =(typeof(b))dlsym(RTLD_NEXT, #a)
...
int *pglob_myvar;
GLOBAL_ADDR(myvar, pglob_myvar);
...
Depending on what you call shielded global variable in C, different answers are possible.
If you mean a global variable defined in another source file or a linked library, you only have to declare it again with the extern prefix:
extern int aGlobalDefinedElsewhere;
If you mean a global variable shadowed (or eclipsed, choose the terminology you prefer) by a local variable of the same name), there is no builtin way to do this in C. So you have either not to do it or to work around it. Possible solutions are:
getter/setter functions for accessing global variable (which is a good practice, in particular in multithreaded situations)
aliases to globals by way of a pointer defined before the local variable:
int noName;
{
int * aliasToNoName = &noName; /* reference to global */
int noName; /* declaration of local */
*aliasToNoName = noName; /* assign local to global */
}
what is a "shielded global variable" in pure C?
in C you have local variables, file local/global variables (static) and global variables (extern)
so file1.c:
int bla;
file2.c
extern int bla;
Yet another option is to reference the global before defining your local, or at least get a pointer to it first so you can access it after defining your local.
#include <stdio.h>
int x = 1234;
int main()
{
printf("%d\n",x); // prints global
int x = 456;
printf("%d\n",x); // prints local
}