Why is this define directive seem to not be working? - c

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.

Related

Why is the CodeBlocks compiler not recognizing a function that I declared in a header file in C?

I recently looked into defining functions using a header file in C.
I followed a tutorial online, but I have come across an issue:
If I use command prompt and run the executable file I created in my project folder, it takes the input from my main.c file and passes it through the function like I expected it to.
The command that I typed in Command Prompt was:
gcc matrix_product.c main.c
Within main I can call the function (which I named matrix_product), and it recognizes it. When I try to build it inside CodeBlocks, however, the compiler indicates 2 errors:
undefined reference to 'matrix_product'
error: ld returned 1 exit status
This is the code:
main.c
#include <stdio.h>
#include <stdlib.h>
#include "matrix_product.h"
#define N 3
int main()
{
int i,j;
int m[N][N]={
{1,2,3},
{4,5,6},
{7,8,9}
};
matrix_product(m,3);
for(i=0;i<N;i++){
if(i==1){printf("M^2 = ");
}else{printf(" ");}
for(j=0;j<N;j++){
printf("%d ",m[i][j]);
}
printf("\n");
}
return 0;
}
matrix_product.c
#include <stdio.h>
#include "matrix_product.h"
void matrix_product(int m[][3],int DIM)
{
int i,j,k;
int tmp[DIM][DIM];
for(i=0;i<DIM;i++){
for(j=0;j<DIM;j++){
tmp[i][j]=m[i][j];
m[i][j]=0;
}
}
for(i=0;i<DIM;i++){
for(j=0;j<DIM;j++){
for(k=0;k<DIM;k++){
m[i][j]+=tmp[i][k]*tmp[k][j];
}
}
}
}
matrix_product.h
#ifndef MATPROD
#define MATPROD
void matrix_product(int m[][3],int DIM);
#endif // MATPROD
main.c seems to be the only source file added to the project in CodeBlocks. Add the source file matrix_product.c to the project by using Project->Add files and it'll compile that too and link (ld) with the object file it produces.
Just having the file in the same folder does not make CodeBlocks understand that it should include the file in the project.

Hide functions and global variables in the header file

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).

implicit declaration of functions?

I'm still learning C and I understand that to get rid of most implicit declaration warnings, you add the prototype header at the beginning. But I'm confused as to what you do when you have outside methods being used in your code.
This is my code when I'm using the outside methods
#include <stdio.h>
#include <string.h>
int main(void)
{
int arrayCapacity = 10;
int maxCmdLength = 20;
int A[arrayCapacity];
int count = 0; /* how many ints stored in array A */
char command[maxCmdLength + 1];
int n;
while (scanf("%s", command) != EOF)
{
if (strcmp(command, "insert") == 0)
{
scanf("%d", &n);
insert (n, A, arrayCapacity, &count);
printArray(A, arrayCapacity, count);
}
else if (strcmp(command, "delete") == 0)
{
scanf("%d", &n);
delete(n,A,&count);
printArray(A, arrayCapacity, count);
}
else
{
scanf("%d", &n);
printArray(A, arrayCapacity, count);
}
}
return 0;
}
The methods printArray, insert, and delete are all in the form of: printArray.o, insert.o, delete.o
This is how I compiled my program: gcc -Wall insert.o delete.o printArray.o q1.c
and I get these warnings:
q1.c: In function âmainâ:
q1.c:20: warning: implicit declaration of function `insert'
q1.c:21: warning: implicit declaration of function `printArray'
q1.c:30: warning: implicit declaration of function `delete'
I've tried including this in headers but I get errors saying file or directory not found.
Any help appreciated.
Put them in a header file foo.h like so:
extern void printArray(int *A, int capacity, int count);
...
then include that file in your source
#include "foo.h"
You need to include the correct headers to get rid of such warnings.
If you get a "file not found" error, try to include them as
#include "myheader.h"
and put your header files in the same directory as your source code.
Generally speaking, #include "file" is for programmer-defined headers while #include <file> is or standard headers.
You should be able to just put in the function prototype at the top of the file like you do for other functions in the same file. The linker should take care of the rest.
Where did you get those .o files from? If you have written them yourself, then you should create the corresponding .h files. If you got these files from somewhere else, then you should search for the headers in the same place.
If all called functions are written before the main() function the compiler will know their name, return type and parameter signature and can match all three of these properties with each following function invocation.
Some programmers like to write a function signature first, and do the implementation at a later time.
The only time a function declaration is essential is when using co-routines: functionA invokes functionB which in turn invokes functionA.
Done as follows:
type a(...signatureOfA...)
/* compiler now knows about a() */
type b(...signatureOfB...)
{…
// implementation of b
a(…arguments for a…);
/* compiler knows about above */
…}
type a(...signatureOfA...)i
{…
// implementation of a
b(…arguments for b…);
/* compiler knows about above */
…}
int main()
{
a(… arguments for a…);
/* compiler knows */
return(code);
}

Can preprocessor directive #include be disabled/excluded?

For example: If I have two .h files
process1.h and process2.h
and they contain two function with different output variables.
process1.h:
function(int var)
{
return 2*var;
}
process2.h:
function(int var)
{
return 10*var;
}
Can this be done in main.c:
int main()
{
int a = 2;
#include "process1.h"
printf("%d",function(a)); //output is 4
EXCLUDE #INCLUDE "process1.h" ????? <----can this be done in any way??
#include "process2.h"
printf("%d",function(a)); //output is 20
}
No, you cannot "un-include" a file. Think of all the preprocessor directives (lines starting with #) as happening before the actual C compiler even sees the source file. They just operate on the text of the file, and the preprocessor could be implemented as a separate step that just feeds new text into the actual compiler.
The best way to modify the actions of an include depending on the caller is to use further macros inside the included files, that you can #define before including them.
Still, your overall syntax is off, you can't (typically) nest functions in C.
No, and you should not try to write a program with two functions of the same name.
In the special case that the functions are actually defined in the header file (instead of just prototypes), you can do this:
#define function function_file1
#include "file1.h"
#undef function
#define function function_file2
#include "file2.h"
#undef function
int
main (void)
{
int a = 2;
printf ("%d\n", function_file1 (a));
printf ("%d\n", function_file2 (a));
}
BUT if you rename a function prototype then you haven't actually renamed the real function, so you'll get undefined symbol error when you link.
In any case, if you have two functions defined with the same name then it won't link anyway, not matter what else you do in the sources. (In C++, it is sometimes possible to define two things with the same name, but the One-Definition-Rule means the linker is allowed to assume they are both the same thing really and just pick one.)
This is why libraries are supposed to use names that won't be used elsewhere - usually by adding a common prefix to all symbol names (e.g. my_unique_lib_initialize()).
Why not use array of function pointers. Sure you need to initialize it at the start but I think it probably solves what you want to do.
int process1_function(int var);
int process2_function(int var);
int main(void)
{
int i, a = 10;
int (* functions[2])(int);
functions[0] = process1_function;
functions[1] = process2_function;
for(i=0; i < 2; i++)
{
printf("%d", (functions[i])(a));
}
return 0;
}
If you do not need to dynamically change which function you're going to call you can also just prefix the functions:
int process1_function(int var);
int process2_function(int var);
int main(void)
{
printf("%d",process1_function(a));
printf("%d",process2_function(a));
return 0;
}

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