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];
Related
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.
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;
}
I declared a struct in main.c file and i have functions in func1.c func2.c func1.h func2.h files.
main.c:
#include <stdio.h>
#include "func1.h"
#include "func2.h"
struct mystruct{
someting
};
main(){
struct mystruct var ={...};
myfunc(var);
}
func1.h:
void myfunc(struct mystruct);
And definition is in func1.c. Similar for func2 files. I got compilation errors, it is obvious that problem is header file dont have declaration of mystruct and so cant use it.
So what is the way to overcome that problem? Adding a new header file for struct or using extern keyword what i read. What is approprite choice i couldnt figure out at that point.
struct mystruct{
//something
};
Should be defined in a header file which all your c files that need it has access to.
mytypes.h
#ifndef mytypes_h
#define mytypes_h
struct mystruct{
int something;
};
#endif
func1.h
#ifndef func1_h
#define func1_h
#include "mytypes.h"
void myfunc(struct mystruct);
#endif
func1.c
#include "func1.h"
void myfunc(struct mystruct){
//do soemthing with struct
}
Then your main can include func1.h which already mytypes.h
main.c
#include "func1.h"
int main(){
}
A toy code illustrating my problem is as follows:
stuff.h:
#ifndef STUFF
#define STUFF
int a;
int testarr[]={1,2,3};
#endif
fcn.h:
#include "stuff.h"
int b[]={5,6,7};
void fcn();
main.h:
#include "stuff.h"
#include <stdio.h>
fcn.c:
#include "main.h"
void fcn() {
printf("Hello\n");
}
main.c:
#include "main.h"
#include "fcn.h"
int main() {
fcn();
printf("HI\n");
}
An attempt to compile fails with:
/g/pe_19976/fcn_2.o:(.data+0x40): multiple definition of `testarr'
/g/pe_19976/main_1.o:(.data+0x40): first defined here
After doing some reading, I realize that defining the array testarr in the header file is a problem. But the thing is, in my real code, several files need access to testarr and it needs to have the same assigned values everywhere. I guess I could put it in main.h (?) but even if that would work, in my real code it logically belongs in stuff.h. How do I solve this conundrum?
BTW, based on something else I found, I tried defining testarr as extern but got the same problem.
When you put a variable definition into a header file, any .c file that includes it will have a copy of that variable. When you then attempt to link them, you get a multiple definition error.
Your header files should contain only a declaration of the variable. This is done using the extern keyword, and with no initializer.
Then in exactly one .c file, you put the definition along with an optional initializer.
For example:
main.c:
#include "main.h"
#include "fcn.h"
int a;
int testarr[]={1,2,3};
int main() {
fcn();
printf("HI\n");
}
stuff.h:
#ifndef STUFF
#define STUFF
extern int a;
extern int testarr[];
#endif
fcn.h:
#include "stuff.h"
extern int b[];
void fcn();
fcn.c:
#include "main.h"
int b[]={5,6,7};
void fcn() {
printf("Hello\n");
}
It is not clear why you are using so many global variables. The array
int testarr[]={1,2,3};
is defined as many times as there are compilation units (in your example there are at least two compilation units) that include the corresponding header.
Declare the array in a header like
extern int testarr[3];
and define it in a cpp module.
int testarr[]={1,2,3};
The same is valid for other global variables that have external linkage.
As for this remark
BTW, based on something else I found, I tried defining testarr as
extern but got the same problem.
Then the array with the specifier extern shall not be initialized in a header. Otherwise it is a definition of the array.
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;
}