user2932587
user2932587

Reputation:

What Should go in my Header File in C++?

I'm just getting started on my first ever C++ program and am pretty much just learning as I go. The program is supposed to have 3 different files, a header file (prog1.h), a prog1.cpp file (not sure the right terminology for this one) and a test file that includes main: to test our program (prog1_test.cpp).

Not asking for help on any of this (yet, I'm sure I'll be posting another question once I get into it), but figured you'd need to know what the program is supposed to do in order to understand my question. Our program is supposed to read in some numbers from a file and put these numbers into a 2D array. It's then supposed to assign characters to each number value and print the current array and the "picture" created with the characters. Then it will go through the array, making sure that each number doesn't differ in value from it's neighbors by more than 1, if it does, the program is to replace that number with the average of its neighboring values. The program will then print out this corrected array and "picture" created with the characters assigned to the corrected array.

I know that header files are supposed to include code that will be used across multiple files, but am having trouble figuring out what parts of my program need to go in this file. For example, would my code to open, read, and close the data file be included here, or no since the file is only being opened, read, and closed once?

Upvotes: 6

Views: 16711

Answers (3)

David C. Rankin
David C. Rankin

Reputation: 84521

The use of various header files, and code/implementation files separate and apart from the application file is done to promote maintainability and reuse of code. By collecting all related functions, variables and data structures in a single file, we prevent having to duplicate that code in every subsequent application we write.

Take for example your situation where you will be developing routines related to matrices or arrays. This scheme allows you to collect the common routines dealing with your arrays into a single file, say arrays.c. Now regardless of how many more programs you write, you have a common file that contain your array routines. Now if you write 5 more applications that need your array routines, you have them ready to go in arrays.c.

For maintainability, let's say you now have a more efficient way of handling input from a file to your array. Instead of having to go back and update the read_array function in 5 different application program files, you simply update the one read_array function in arrays.c and you have accomplished updating that routine for all applications that use it.

How does the header file fit in? In order to use your array functions in other applications, the applications need a common way of including the code to make it available for use. That is done by including your arrays.h header file in each application that needs it. OK, so what goes in arrays.h and what goes in arrays.c? Your header files will include the header files, function declarations, data structures and variables for your array routines that are necessary to implement the function definitions contained in arrays.c. That way any application that wishes to make user of your array routines need only include the line #include "arrays.h" at the beginning of its file to have access to your array functions contained in arrays.c

An example (in C) will help sort things out. Say you have several array functions that read lines in a text file into strings read_array, print the lines prn_array and then frees the memory used by the array and strings free_array. You have collected your array functions in array.c. (we know we will include array.h at the top.) So, for example:

#include "array.h"

char **read_array (char *filename)
{
    char *buffer = NULL;
    size_t len = 0;
    ssize_t read;
    char **array = NULL;
    int cnt = 0;

    FILE *fp;
    fp = fopen (filename, "r");      //open file , read only
    if (!fp) {
        fprintf (stderr, "failed to open file for reading\n");
        return NULL;
    }

    array = calloc (AMAX, sizeof (*array) * AMAX); /* allocate pointers, set NULL */

    while ((read = getline (&buffer, &len, fp)) != -1) { /* read each line */

        if (cnt == AMAX) {
            fprintf (stderr, "Error: AMAX reached\n");
            break;
            /* you will realloc *array here in real life */
        }

        if (buffer[read-1] == '\n') {   /* strip newline              */
            buffer[read-1] = 0;
            read -= 1;
        }

        array[cnt] = strdup (buffer);   /* copy buffer to array[cnt]   */
        cnt++;                          /* increment counter           */
    }

    fclose (fp);                        /* close file stream (fp)      */
    return array;
}

void prn_array (char **array)
{
    register int j = 0;
    while (array[j]) {
        printf ("  array[%d]: %s\n", j, array[j]);
        j++;
    }
}

void free_array (char **array)
{
    register int j = 0;
    while (array[j]) {      /* for each allocated string */
        free (array[j]);    /* free pointer to string    */    
        j++;
    }
    free (array);           /* free array                */
}

Now let's create our header. We collect our function declarations along with any variables or data structures used and also include the system headers and any other included header files required by our functions in array.h:

#ifndef MY_ARRAY_H
#define MY_ARRAY_H  1

/* headers required for array.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define AMAX 100

/* function declaration */
char **read_array (char *filename);
void prn_array (char **array);
void free_array (char **array);

#endif  /* MY_ARRAY_H */

Notice we have wrapped the contents of our header inside a test #ifndef MY_ARRAY_H which just asks the compiler if MY_ARRAY_H is defined yet, ifndef (if not defined), we let the compiler know that everything that follows our #define until we reach the end of the if statement #endif we are defining as MY_ARRAY_H so that if another file tries to include the same header -- the compiler knows it already has it and doesn't need to include it again. (not required, but we also give our define of MY_ARRAY_H the value 1)

So how do we put our custom header array.h and our custom functions for handling arrays in arrays.c to work for us? We write an application that makes use of the functions in arrays.c and to declare all the functions in arrays.c in our application, we simply include array.h in our application. (called application.c below):

#include <stdio.h>
#include "array.h"                      /* include array.h  */

int main (int argc, char *argv[]) {

    if (argc < 2) {
        printf ("filename.csv please...\n");
        return 1;
    }

    char **my_array = NULL;             /* declare pointers */

    my_array = read_array (argv[1]);    /* call read_array  */
    prn_array (my_array);               /* call prn_array   */
    free_array (my_array);              /* call free_array  */

    return 0;
}

compile the application.c and array.c files:

gcc -Wall -Wextra -o application application.c array.c

run it on any short text file (less than 100 lines)

$ ./application input.txt
  array[0]: 1.  This is a simple input file with line numbers
  array[1]: 2.  for use with application showing the use of
  array[2]: 3.  header file: array.h
  array[3]: 4.  array functions defined in: array.c
  array[4]: 5.  (blank)
  array[5]: 6.  compiled with the following:
  array[6]: 7.  gcc -Wall -Wextra -o application application.c array.c
  array[7]: 8.  --------
  array[8]: 9.  Now you know!

Now you can see the benefit of creating a separate file holding the related functions, variables, and data structures we will use and creating a header file. We can reuse that code in any application we like simply by including the header file arrays.h in our application. We can update and maintain all our array functions in one place and updating our arrays.c will update all other applications that make use of that code.

I know I have left much out, but make sure you are solid on these concepts. They are fundamental to working with multiple source files and includes in C/C++.

Upvotes: 4

Null
Null

Reputation: 1970

Header files contain function and class declarations. These simply declare the name of the function, its return type, and its argument list. The .cpp file contains the definitions of these functions -- i.e. the actual implementation. The header file is visible to the rest of the program if you #include it in other files, but the implementation details are hidden in the .cpp file.

Anything declared/defined in the .cpp file that is not in the .h file is not visible to the rest of the program, so you can define internal variables, helper functions, etc. in the .cpp file and those implementation details will not be visible. An example of this is foo() in my example below.

A very rough sketch of your program would look like this:

In prog1.h:

#include <iostream> // and whatever other libraries you need to include

#define ARRAY_SIZE 100 // and other defines

// Function declarations

// Read number from file, return int
void read_number(int array[ARRAY_SIZE][ARRAY_SIZE]);

char assign_char(int n);

void print_array(int array[ARRAY_SIZE][ARRAY_SIZE]);

void neighbor_check(int array[ARRAY_SIZE][ARRAY_SIZE]);

In prog1.cpp:

// included headers, defines, and functions declared in prog1.h are visible
#include "prog1.h"

void read_number(int array[ARRAY_SIZE][ARRAY_SIZE]) {
    // implementation here
}

char assign_char(int n) {
    char c;
    // implementation here
    return c;

}

void print_array(int array[ARRAY_SIZE][ARRAY_SIZE]) {
    // implementation here
}

void neighbor_check(int array[ARRAY_SIZE][ARRAY_SIZE]) {
    // implementation here
}

// not visible to anything that #includes prog1.h
// since it is not declared in prog1.h
void foo() {
    // implementation here
}

In prog1_test.cpp:

// included headers, defines, and functions declared in prog1.h are visible
#include "prog1.h"
// any other includes needed by main()

int main() {
   int array[ARRAY_SIZE][ARRAY_SIZE];

   read_number(array);

   for (int i = 0; i < ARRAY_SIZE; i++) {
       for (int j = 0; j < ARRAY_SIZE; j++) {
           assign_char(array[i][j]);
       }
   }

   neighbor_check(array);

   print_array(array);

   return 0;
}

Upvotes: 6

user2641018
user2641018

Reputation: 108

Following basic things should appear in your header file.

  1. class body with function declaration , data variable, constructor and destructor declaration.
  2. declaration of all functions in class. Note: not a function body or definition.
  3. inline functions.
  4. define
  5. all library include header files. so you need to add only one header file in you respective .c file of this header file.
  6. structures
  7. ifndef block
  8. forward declaration of class if you need it some times.
  9. doxygen comments for the functions and classes and variables.
  10. description of this file as comment in top of you header file for doxygen. etc...

Header file should not have any code.

Upvotes: 0

Related Questions