Accessing a variable outside a c file - c

I'm trying to do this code, and I split it up into .c files (lets say file1.c and file2.c) and file1.h file. I'm not allowed to change which parameters I can send to the function, so I need to find another way to "send"/access another variable. I tried to make the variable static in the header file file1.h, and include it in the file2.c. The function in file1.c look something like this:
int function(int *array, int a, int b){
...
...
if(global_variable == 1){
point = array[(a+b)/2];
}else if(global_variable == 0){
point = array[b];
}
and in the file2.c I have a function something like this:
double function2(t_sort_funcp fun, const case_t c, int array_length, result_t *buf, t_generate_array_funcp g_array){
int array[array_length];
switch (c)
{
case first:
global_variable = 1;
g_array(array, array_length);
return debugg(fun, array, array_length);
break;
case second:// Wors case is an inverted sorted array.
global_variable = 0;
g_array(array, array_length);
return debugg(fun, array, array_length);
break;
case third:
global_variable = 1;
g_array(array, array_length);
return debugg(fun, array, array_length);
break;
}
return 0;
}
In the file1.h I have:
#ifndef ALGORITHM_H
#define ALGORITHM_H
#include <stdbool.h> // bool
static int global_variable;
#endif
as you can see, I'm trying to change the global_variable variable in file2.c and use it in file1.c but that does not work, the if-statement in file1.c always executes the code in the else-statement, even if I changed the variable to 1.
NOTE: file2.c always executes before file1.c

Do it the opposite way
#ifndef ALGORITHM_H
#define ALGORITHM_H
#include <stdbool.h> // bool
extern int global_variable;
#endif
In one of the .c files
int global_variable;
Include the .h file in all files which require access to this variable.
static in global scope makes the variable only available in one compilation unit (file).

You can use extern with a cpp conditional.
Below are samples files.
FILE: file1.h
#ifndef ALGORITHM_H
#define ALGORITHM_H
#include <stdbool.h> // bool
#ifdef FILE1_C
int global_variable;
#else
extern int global_variable;
#endif
#endif
FILE: file1.c
// I am file1.c
#define FILE1_C
#include "file1.h"
FILE: file2.c
// I am file2.c
#include "file1.h"
UPDATE:
definitely wrong way. Why this weird ifdef complication –
0___________
No, it's not the wrong way. I do this all the time. The idea is that you have both definitions in the same place/file. If you put the global in a .c file, it's harder to see if you change the type.
Here's a more expanded case:
#ifndef ALGORITHM_H
#define ALGORITHM_H
#include <stdbool.h> // bool
#ifdef FILE1_C
#define EXTRN_FILE1 /**/
#else
#define EXTRN_FILE1 extern
#endif
EXTRN_FILE1 int global_variable;
EXTRN_FILE1 double global_variable_2;
#ifdef FILE1_C
int global_variable_3 = 37;
#else
extern int global_variable_3;
#endif
#endif
And, we may want to put the globals in a different .c file. If we rename FILE1_C to (e.g.) DEFINE_GLOBALS, we can put #define DEFINE_GLOBALS in any .c. If we change our minds later, it's trivial to move the #define from (e.g.) file1.c to file2.c.

Related

how to share functions in c [duplicate]

Can anyone explain how to create a header file in C with a simple example from beginning to end.
foo.h
#ifndef FOO_H_ /* Include guard */
#define FOO_H_
int foo(int x); /* An example function declaration */
#endif // FOO_H_
foo.c
#include "foo.h" /* Include the header (not strictly necessary here) */
int foo(int x) /* Function definition */
{
return x + 5;
}
main.c
#include <stdio.h>
#include "foo.h" /* Include the header here, to obtain the function declaration */
int main(void)
{
int y = foo(3); /* Use the function here */
printf("%d\n", y);
return 0;
}
To compile using GCC
gcc -o my_app main.c foo.c
#ifndef MY_HEADER_H
# define MY_HEADER_H
//put your function headers here
#endif
MY_HEADER_H serves as a double-inclusion guard.
For the function declaration, you only need to define the signature, that is, without parameter names, like this:
int foo(char*);
If you really want to, you can also include the parameter's identifier, but it's not necessary because the identifier would only be used in a function's body (implementation), which in case of a header (parameter signature), it's missing.
This declares the function foo which accepts a char* and returns an int.
In your source file, you would have:
#include "my_header.h"
int foo(char* name) {
//do stuff
return 0;
}
myfile.h
#ifndef _myfile_h
#define _myfile_h
void function();
#endif
myfile.c
#include "myfile.h"
void function() {
}
header files contain prototypes for functions you define in a .c or .cpp/.cxx file (depending if you're using c or c++). You want to place #ifndef/#defines around your .h code so that if you include the same .h twice in different parts of your programs, the prototypes are only included once.
client.h
#ifndef CLIENT_H
#define CLIENT_H
short socketConnect(char *host,unsigned short port,char *sendbuf,char *recievebuf, long rbufsize);
#endif /** CLIENT_H */
Then you'd implement the .h in a .c file like so:
client.c
#include "client.h"
short socketConnect(char *host,unsigned short port,char *sendbuf,char *recievebuf, long rbufsize) {
short ret = -1;
//some implementation here
return ret;
}

Passing array of structures to a function in different file in C

I need to pass an array of structures defined in a file "file1.c" to a function, lets say "myFunc()", defined in another file "file2.c". The thing is that I don't know how to set the prototype of myFunc() in my header file "header.h" or in the function itself in my file2.c because the struct will only be defined in file1.c . Here is an example.
file1.c
#include "header.h"
#define dim 30
#define searchAgents 30
struct Wolf{
double pos[dim];
double fitness;
}Pack[searchAgents];
int main(){
myFunc(Pack); //not sure it's ok
return 0;
}
file2.c
#include "header.h"
void myFunc(struct Wolf Pack[]){ //I don't know how to set this argument
Pack[0].pos[0] = 1; //just an example
}
header.h
#ifndef HEADER_H_
#define HEADER_H_
void myFunc(struct Wolf); //I don't know how to set this prototype
#endif
I read about passing structures to functions but it's different when you have your function defined in another file. Thanks for your time.
header.h
#ifndef HEADER_H_
#define HEADER_H_
//Add all needed includes
#define dim 30
#define searchAgents 30
typedef struct Wolf{
double pos[dim];
double fitness;
}Pack; //Declaration
void myFunc(Pack *);
#endif
In main
#include "header.h"
int main(){
Pack packArray[searchAgents]; //Definition or initialization if you like
myFunc(packArray);
return 0;
}
file2.c
#include "header.h"
void myFunc(Pack *pack){ //just a pointer to Pack structure
pack[0].pos[0] = 1;
}
You can try making Pack[] as an extern type variable
extern keyword tells the compiler that the variable is define in some other .c file which is compiled along with this file with -o option in gcc compiler .
ex
extern Pack[10];

Include Guard still inserting Global Variables

I have 3 *.c files (file1.c, file2.c and file3.c) and 1 *.h file (file3.h) in a project (Visual Studio).
/*******************************
file3.h
********************************/
#ifndef FILE3_H
#define FILE3_H
int gintVariable = 400;
#endif
/*******************************
file1.c
********************************/
#include "file3.h"
#include <stdio.h>
#include <conio.h>
int modifyGlobalVariable(void);
void printGlobalVariable(void);
int main(void)
{
modifyGlobalVariable();
printGlobalVariable();
printf("Global variable: %d\n", gintVariable++);
getch();
return 0;
}
/*******************************
file2.c
********************************/
#include "file3.h"
int modifyGlobalVariable(void)
{
return gintVariable++;
}
/*******************************
file3.c
********************************/
#include "file3.h"
#include <stdio.h>
void printGlobalVariable(void)
{
printf("Global: %d\n", gintVariable++);
}
When I build the solution in VS, it is giving error as "_gintVariable already defined in file1.obj".
I did check in the pre-processor output, the gintVariable is included in all the *.c files even though I have included include guards.
What mistake I am doing?
You should use 'extern' while declaring a global variable in header file.
Define it in any one of *.c file.
This should fix the issue.
For more on header files, read
How do I use extern to share variables between source files?
Including guards prevents multiple inclusion (or, more precisely, multiple compilation of the .h file content) in a single translation unit.
It is useful against this problem:
/* glob.h */
#ifndef H_GLOB
#define H_GLOB
struct s { int i; };
#endif
/* f.h */
#ifndef H_F
#define H_F
#include "glob.h"
struct s f(void);
#endif
/* g.h */
#ifndef H_G
#define H_G
#include "glob.h"
struct s g(void);
#endif
/* c.c */
#include "f.h" /* includes "glob.h" */
#include "g.h" /* includes "glob.h" */
void c(void) {
struct s s1 = f();
struct s s2 = g();
}
The inclusions is like a diamond:
glob.h
/ \
f.h g.h
\ /
c.c

Creating your own header file in C

Can anyone explain how to create a header file in C with a simple example from beginning to end.
foo.h
#ifndef FOO_H_ /* Include guard */
#define FOO_H_
int foo(int x); /* An example function declaration */
#endif // FOO_H_
foo.c
#include "foo.h" /* Include the header (not strictly necessary here) */
int foo(int x) /* Function definition */
{
return x + 5;
}
main.c
#include <stdio.h>
#include "foo.h" /* Include the header here, to obtain the function declaration */
int main(void)
{
int y = foo(3); /* Use the function here */
printf("%d\n", y);
return 0;
}
To compile using GCC
gcc -o my_app main.c foo.c
#ifndef MY_HEADER_H
# define MY_HEADER_H
//put your function headers here
#endif
MY_HEADER_H serves as a double-inclusion guard.
For the function declaration, you only need to define the signature, that is, without parameter names, like this:
int foo(char*);
If you really want to, you can also include the parameter's identifier, but it's not necessary because the identifier would only be used in a function's body (implementation), which in case of a header (parameter signature), it's missing.
This declares the function foo which accepts a char* and returns an int.
In your source file, you would have:
#include "my_header.h"
int foo(char* name) {
//do stuff
return 0;
}
myfile.h
#ifndef _myfile_h
#define _myfile_h
void function();
#endif
myfile.c
#include "myfile.h"
void function() {
}
header files contain prototypes for functions you define in a .c or .cpp/.cxx file (depending if you're using c or c++). You want to place #ifndef/#defines around your .h code so that if you include the same .h twice in different parts of your programs, the prototypes are only included once.
client.h
#ifndef CLIENT_H
#define CLIENT_H
short socketConnect(char *host,unsigned short port,char *sendbuf,char *recievebuf, long rbufsize);
#endif /** CLIENT_H */
Then you'd implement the .h in a .c file like so:
client.c
#include "client.h"
short socketConnect(char *host,unsigned short port,char *sendbuf,char *recievebuf, long rbufsize) {
short ret = -1;
//some implementation here
return ret;
}

how do i avoid this linking error?

if i have defined a global variable(with initialization) in header file, and included this file in two file and try to compile and link, compiler gives linking error
headers.h:
#ifndef __HEADERS
#define __HEADERS
int x = 10;
#endif
1.c:
#include "headers.h"
main ()
{
}
2.c:
#include "headers.h"
fun () {}
The linker complains because there will be multiple definitions of x once it puts all the object files together to create the executable. You have two different source files including the same header file, and that header file defines a variable x having a value of 10, so you end up with two definitions of x (one in 1.c and another in 2.c).
To avoid multiple definition linker errors, put this in a header file (for example globals.h):
#ifndef GLOBALS_H
#define GLOBALS_H
/*
* The "extern" keyword means that this variable is accessible everywhere
* as long as this declaration is present before it is used. It also means
* that the variable x may be defined in another translation unit.
*/
extern int x;
#endif
Then put this in one source file:
#include "globals.h"
int x = 10;
This is a classic case where you want either the variable declared or declared-and-defined.
If you define it in both source files, you will get a double-definition linker error. One way to handle this is to only set __HEADERS for one of the source files so that it is the one where the variable is defined.
All other source files get the declaration only.
>>headers.h
#ifndef __HEADERS
int x = 10;
#else
extern int x;
#endif
>>1.c
#define __HEADERS
#include "headers.h"
int main (void) {
return 0;
}
>>2.c
#include "headers"
void fun (void) {
}
Of course, it's best to leave definitions out of header files altogether in case you accidentally define __HEADERS in two source files. Try:
>>headers.h
extern int x;
>>1.c
#include "headers.h"
int x = 10;
int main (void) {
return 0;
}
>>2.c
#include "headers"
void fun (void) {
}
#include works exactly the same as if you copied and pasted the text from the header file.
Consider it in that way and you will see that you have therefore put the line int x=10 into both your source files.
A fixed version is below:
>>headers.h
#ifndef __HEADERS
#define__HEADERS
extern int x; // extern tells the compiler it will be linked from another file
#endif
-----------------
>>1.c
#include "headers.h"
int x = 10; // must have it in ONE file for linking purposes
main ()
{
}
---------------------
>>2.c
#include "headers"
fun () {}
Define __HEADERS in the ifndef.
Put declarations, not definitions, in your headers:
// header
extern int x;
// implementation
int x = 10;
3. 2.c has the include wrong.
So:
// headers.h
#ifndef __HEADERS
#define __HEADERS
extern int x;
#endif
// 1.c
#include "headers.h"
int x = 10;
main ()
{
}
// 2.c
#include "headers.h"
fun () {}
You can define x anywhere. Just make it one place.

Resources