How to use multiple source and header files

cexternheadertypedef

I recently learnt how can we use multiple source files with header files to make code portable and hierarchical. In order to do so, I tried to create my tree program using this principle. Here are my files

b_tree_ds.h – This will contain a declaration of datastructure of node of a tree, which can be called to various functions implementing different functionality of the tree (which may be in different source files)

typedef struct node {
    struct node* left;
    struct node* right;
    int key;    // contains value
}NODE;

When i try adding a extern as in typedef extern struct node it gives a error of multiple storage class but if I miss it, I get error for multiple definitions.

Here are my other source files

traverse.h – contains declaration of traverse function

void traverse_print (NODE* p);

Here also I get error for unknown identifier NODE

traverse.c – contains definition to that function

#include <stdio.h>
#include "b_tree_ds.h"
#include "traverse.h"

void traverse_print(NODE* p)
{
    if(p->left != NULL)
    {
        traverse_print(p->left);
    }

    if (p->right != NULL)
    {
        traverse_print(p->right);
    }

    printf ("\n%d",p->key);
}

Finally main.c

#include <stdio.h>
#include "traverse.h"

void main()
{
    // input
    NODE p;

    printf("\nInput the tree");
    input_tree (&p);

    printf("\n\nThe tree is traversing ...\n")
    traverse_print(&p);
}

void input_tree (NODE *p)
{
    int in;
    int c;
    NODE *temp;

    printf("\n Enter the key value for p: ");
    scanf("%d", &in);
    p->key  =in;
    printf ("\n\nIn relation to node with value %d",in);
    printf ("Does it have left child (Y/N): ")
    if ((c = getchar()) == Y);
    {
        //assign new memory to it.
        temp = (NODE *)malloc(sizeof(NODE));
        input_tree(temp);
    }
    printf ("\n\nIn relation to node with value %d",p->key);

    printf ("\nDoes it have right child (Y/N): ")
    if ((c = getchar()) == Y);
    {
        //assign new memory to it.
        temp = (NODE *)malloc(sizeof(NODE));
        input_tree(temp);
    }
}

This is my first attempt to such practice, please suggest is the structuring of my program good or should I try something else.

Best Answer

You may be having problems because you haven't yet got a strong reason to split things up. A good reason would help you identify which parts belong together, and which parts are separate. So start with a simpler approach.

Split the program into three files, main.c, which contains main(), node.h, the header which ensures declarations are common across all the program, and hence is understood by the compiler, and node.c, the functions which manipulate the NODE structure.

Put the typedef ... NODE; and all the declarations of functions which manipulate NODE into one the node.h header file. So you could merge the existing header files into one, and call it node.h.

As Joop Eggen recommends, put #ifndef _NODE_H_ ... #endif around node.h contents to protect it against accidentally being #included twice.

Test that file is correct with a minimal main.c file containing:

#include "node.h"

int main() { return 0; }

and compile it. That should give no compilation errors. If it contains errors the fault is in the header file.

Put the functions that manipulate NODE, into a file called node.c, which will initially be:

#include "node.h"

compile and link that with main.c (gcc main.c node.c), and there should be no errors.

Build up the program is stages, adding code to the main.c file, the node.c file, and add declarations of functions in the node.c file into node.h. Add small amounts of code, and compile frequently (with warnings switched on, e.g. gcc -Wall main.c node.c) and test to make sure it is doing what you expect.

The program will eventually be complete.