Hide functions and global variables in the header file - c

I created a program in C that can find the determinant of a matrix
void fun1(); /*regardless of parameters they take*/
void fun2();
void fun3();
void fun4();
void fun5();
int global_var1; /*they are used among the above functions*/
int global_var2;
int global_var3;
int determinant;
int main(void){
int x,y;
for(x=0; x<something ; x++){
for (y=0 ; y<another_thing; y++){
fun1();
fun2();
fun3();
}
fun4();
fun5();
}
printf("Determinant is: %d\n", determinant);
return 0;
}
void fun1(){/*code goes here to process the matrix*/;}
void fun2(){/*code goes here to process the matrix*/;}
void fun3(){/*code goes here to process the matrix*/;}
void fun4(){/*code goes here to process the matrix*/;}
void fun5(){/*code goes here to process the matrix*/;}
Now I need to use this program to find the determinant of a given matrix in another project.
I created a header file, named it "matrix.h" and I replaced the int main(void) with int find_determinant() to be used in the new project.
the prototype of the second program:
#include "matrix.h"
int main(void){
find_determinant(); /*regardless of para it takes, it works perfectly*/
return 0;}
it works properly, nothing wrong with it, but the only problem that if I want to give this header file "matrix.h to someone to use it in his program, he can know the signature of other functions (useless for him alone and confusing) that were used to help in finding the determinant in int find_determinant().
My question is:
How can I hide (make them inaccessible) those functions and global variables and show only the int find_determinant() function in the second C file/program that contains #include "matrix.h" ?

Although you can put executable code in a header file, a good practice is to have your header file only contain declarations (for global variables) definitions and function prototypes. If you don't want to give your source code implementation, then you need to compile your functions into object code and provide the object file (either as a static archive or shared library) along with the header file. Whoever wants to use your function will then link his/her program to your objecet file/shared lib. This way, you can keep your source code implementation to yourself. Your header file would be:
#ifndef __SOME_MACRO_TO_PREVENT_MULTIPLE_INCLUSION__
#define __SOME_MACRO_TO_PREVENT_MULTIPLE_INCLUSION__
int find_determinant();
#endif
Beware of multiple inclusion problems (I have shown above how to avoid this so that if your matrix.h file is included several times, programs will still compile).

Related

How to use an shared variable between multiple interacting C files? [duplicate]

This question already has answers here:
How do I use extern to share variables between source files?
(19 answers)
Closed 6 years ago.
I am trying to declare an variable x in a file demo_f1.c and use it in two files demo_f2.c and demo_f3.c having two functions void f2() and void f3(), respectively.
I have a driver program that uses the variable x and both of these functions, but it gives me an error while I try to compile the driver program.
demo_f1.c
int x=2;
demo_f2.c
#include"C:\TC\BIN\demo_f1.C"
void f2()
{
extern int x;
printf("In f2 x:%d\n",x);
}
demo_f3.c
#include"C:\TC\BIN\demo_f1.C"
void f3()
{
extern int x;
printf("In f3 x:%d\n",x);
}
Driver.c
#include"stdio.h"
#include"conio.h"
#include"C:\TC\BIN\demo_f1.C"
#include"C:\TC\BIN\demo_f2.C"
#include"C:\TC\BIN\demo_f3.C"
void main()
{
clrscr();
printf("In main program,x:%d\n",x);
f2();
f3();
getch();
}
The error:
Compiling C\TC\BIN\Driver.C:
Error C\TC\BIN\DEMO_F1.C 1: Variable 'x' is initialized more than once
Error C\TC\BIN\DEMO_F1.C 1: Variable 'x' is initialized more than once
Why am I getting this error? How can I correct it?
To make your code compile, you simply need to remove extern int x; from f2() and f3(). For a more complete answer read How do I use extern to share variables between source files in C? as grahamj42 suggests.
You are including demo_f1.c three times in driver.c, one directly and two indirectly through demo_f2.c and demo_f3.c. In consequence, the compiler finds three times the line "int x=2;"
You can use the mechanism with #ifndef typically used in header files. Make demo_f1.c like this:
#ifndef DEMO_F1_C
#define DEMO_F1_C
int x=2;
#endif
Alternatively, to avoid including the .c file, you could have:
demo_f1.h
#ifndef DEMO_F1_H
#define DEMO_F1_H
extern int x;
#endif
demo_f1.c
#include "demo_f1.h"
int x = 2;
And the other files would include demo_f1.h.

Why is this define directive seem to not be working?

I am a rookie programmer here. I am trying to learn C. I am trying to have a main program run another file. However, I am getting compile time errors. My IDE says: Error. Implicit declaration of function print and also it says ROW and COL are not defined here. Of course I have 3 files and I don't see why I am getting these errors. I think I defined ROW and COL properly in the header file like you're supposed to. Can someone see a problem with this simple code? Right now I have the following code:
//p750_eightqueens.h
#ifndef P750_EIGHTQUEENS_H_INCLUDED
#define P750_EIGHTQUEENS_H_INCLUDED
#define ROW 8
#define COL 8
void go(int row, int col);
void print(int array[ROW][COL]);
#endif // P750_EIGHTQUEENS_H_INCLUDED
//p750_eightqueens.c
void go(int row, int col) {
int a[ROW][COL],i,j;
for(i=0;i<ROW;i++) {
for(j=0;j<COL;j++){
a[i][j]=(i==row&&j==col?1:0);
}
}
print(a);
}
void print(int array[ROW][COL]) {
int i,j;
for(i=0;i<ROW;i++) {
for(j=0;j<COL;j++){
printf("%i",a[i][j]);
if (j!=COL-1) printf(" ");
}
printf("\n");
}
}
//now in main.c
#include<stdio.h>
#include<stdlib.h>
#include "p750_eightqueens.h"
int main(){
go(4,4);
return 0;
}
You need to include your header file in p750_eightqueens.c, too.
Your .c files are compiled independently of each other, so your p750_eightqueens.c doesn't know about your defines and function declarations.
If you compile a C-program each compilation unit (.c-file) is compiled on it's own and needs all includes and declarations that are used in that file. After that you have object files (.o) which are then combined to a single executable by the linker. The linker searchs for the implementations of the used functions and puts it together so that different compilation units can call functions in others.

Header Files in C

I have been reading about C for a while now and decided lets write a little add program, nothing fancy at all. My understanding of C headers is that they are "interfaces" (such as like java and other languages) but where you can also define variable that either have set values or not..
So I wrote this:
#include <stdio.h>
#include <stdlib.h>
#include "sample.h"
int main(int argc, char** argv) {
printf("hello World\n");
add(12, 18);
return (EXIT_SUCCESS);
}
int add(int a, int b){
int value = a+b;
printf("value = %d\n", value);
return 0;
}
It has a header file that looks like such:
#ifndef SAMPLE_H_GUARD
#define SAMPLE_H_GUARD
int add(int a, int b);
#endif
I thought header files, and this is where I am lost on their definition, was suppose to define the use of add, so all I would have to do is call add - From my understanding, I define the rules of add and then implement the functionality of add....
Also, A lot of the material I have read shows one header file for multiple C files. where as a lot of projects today have one header per one c, meaning Sample.h belongs to Sample.c and nothing else.
Can some one shed some light on this?
Could I have done this like so:
main.c
#include <stdio.h>
#include <stdlib.h>
#include "sample.h"
int main(int argc, char** argv) {
printf("hello World\n");
add(12, 18);
return (EXIT_SUCCESS);
}
add.c
#include <stdio.h>
#include <stdlib.h>
#include "sample.h"
int add(int a, int b){
int value = a+b;
printf("value = %d\n", value);
return 0;
}
sample.h
#ifndef SAMPLE_H_GUARD
#define SAMPLE_H_GUARD
int add(int a, int b);
#endif
I believe in the book I was reading: C Programming Language they had a calculator example split up like this, my question is how does C know where add is defined? It knows the rules for it based on the header file, i think, but not where the actual implementation is ....
There example where they split of the files like such doe not have something like #include "add.c" all they do is include the header file in the files that either implement or use this functionality.
Note: obviously the calculator example and my example are going to be different but fundamentally the same - for those who have the book. I am just lost on how to use header files effectively and efficiently.
A header file in C would declare the function add for those modules that need it, but not define the function. The function is still to be defined in its own module (e.g., in your case, add.c).
So in general, to make a function foo available to several modules, you would normally:
Choose a header file (maybe it's own if there are other associated
defines, etc) to declare foo. For example, perhaps foo.h would
have void foo(...);
In some module, perhaps foo.c, you would define the complete
function foo.
In any module that wants to call foo, you would #include "foo.h"
(or whatever header you used) and call the function.
When you compile/link the code, you would make sure all modules,
including foo.o or whatever module has foo defined in it, were
present.
A declaration, given in the header file, provides (of course) the function name, the function return type as well as listing all the parameters and their types. This is all the compiler needs to know to figure out how to call the function from the calling module. At link time, addresses are all resolved so that the modules then know exactly where the function is in its own particular module.
My understanding of C headers is that they are "interfaces" (such as
like java and other languages) but where you can also define variable
that either have set values or not..
This is not correct. You cannot "define" variables - well, you can but that will cause multiple definitions error while compiling code if you include header more than once.
Could I have done this like so:
Regarding your code - both variants are correct. C language uses headers to read declarations and hence headers are optional as well. You can have your code split into as many as you want .h and .c files. Compiler will create an object file for each .c file. All .h files included in a c file are basically embedded in that C file "before compilation" i.e. in preprocessing phase. Linker then comes in picture which combines objects to produce the executable.
Please don't hesitate if something is not clear in my answer.

Calling inline functions from file in C

Basically, I have a FileA.c:
//FIleA.c
void inline something()
{
//short code here
}
void inline another()
{
//short code here
}
Now I want to call these inline functions in another file main.c without using a header file.
How should I declare the prototypes of these functions in main.c?
//main.c
#include "FileA.c"
void something();
void another();
// or ???
int main()
{
something();
another();
something();
another();
return 0;
}
This answer actually suggests that there's no possible use case for defining inline functions in another .c file in this way.
On the other hand, if you #include "FileA.c" in your main file anyway, then you don't need to do anything, because you are using a header file (ending the name of an included file with .c doesn't change what it fundamentally is, it just confuses people reading your code).

Use of extern: getting 'file not found'

//fpoin1.c
#include<stdio.h>
#include<conio.h>
#include<fpoin.c>
void swap(int,int);
void main()
{
int i=0;
i++;
if(i<=5)
{
printf("%d",i);
swap(59,23);
getch();
}
//fpoin.c
#include<stdio.h>
#include<conio.h>
extern int i;
void swap(int ,int );
int main()
{
int i=3;
int p,q;
swap(p,q);
printf("\np=%dq=%d",p,q);
getch();
return 0;
}
void swap(int p,int q)
{
int t=p;
p=q;
q=t;
}
When I compile fpoin1, it says "fpoin.c not found", but both are in same directory.
What is missing?
This should fix it:
#include "fpoin.c"
Using "" or <> affects how the compiler searches for a file/header. You should use <> for "system" and "library" includes, and use "" when including your own files.
But, you shouldn't include a .c file. You should compile each of these, then link them together, using e.g. this gcc one-liner: gcc -Wall -o appname fpoin.c fpoin1.c
You will also need to decide which of your two main() functions you want to use. You must have exactly one main()
Additionally, your swap function will not work as you expect, since you pass its arguments by value. Try this:
void swap(int * p, int * q) {
int t=*p;
*p=*q;
*q=t;
}
...
swap(&p, &q)
Of course, you cannot then call swap(59,23) - There's no variables to modify. What was swap(59,23) supposed to do?
One normally only includes .h files, and links other .c files, but if you are going to include a local file, it should be done with "..." and not <...> delimiters, so:
#include "fpoin.c"
The <...> indicates a system header.
In your case, just switching to linking won't quite be good enough, as your main() will be multiply-defined either way. You might want to rethink your modularization a bit.
Using < and > in the #include says to the compiler that you are including a "standard header". Standard headers need not be real files on your disk: the compiler uses magic to include standard headers.
To include real files, use quotes in the #include line
#include "fpoin.c"
One more thing: don't get used to including code. Write files with declarations only and include them (tipically files with .h extension).

Resources