makefile - Breaking up large C program in Header files and C files -


i have break following code following files: main.c, student.c, students.h, mergesort.c, mergesort.h, aux.c , aux.h. have make makefile compile all. program mergesort implemented on linked list. i've separated code, have no clue in terms of headers files , include directives, , less of clue how create makefile. need include headers files, , need include in c files? example, if mergesort.c using functions students.c, have include students.h in mergesort.c? here's code original program:

#include <stdio.h> #include <stdlib.h>  #define name_len 25  struct node {   int number;   char name[name_len+1];   struct node* next; };  /* functions manage linked list.  functions prompt    user , read standard input if needed. */ struct node* insert        (struct node* student_list); void         print_student (struct node* student); void         print_list    (struct node* student_list); void         search        (struct node* student_list); struct node* delete        (struct node* student_list); void         delete_list   (struct node* student_list);  /* merge sort */ struct node* mergesort(struct node* student_list); struct node* merge    (struct node* list1, struct node *list2);                                       /* auxiliary functions */ int read_line(char line[], int len); /* read @ len characters                     standard input ,                     ignore rest of line. */ int line_skip(); /* read standard input end of line. */ int line_copy(); /* read standard input end of line             , copy standard output. */ int pause();     /* ask user press enter continue. */  int main() {   int option;   struct node* student_list = null;    (;;) {     printf("\n-- options menu -----------------\n");     printf("1: add student\n");     printf("2: search student number\n");     printf("3: delete student number\n");     printf("4: display students\n");     printf("5: sort students number\n");     printf("0: exit\n");     printf("\n");      printf("enter option: ");     if ( scanf("%d", &option) != 1 ) {       if ( feof(stdin) ) break;       printf("invalid option: "); line_copy(); pause();       continue;     }      /* read rest of line after option number.  usually,        1 new-line character */     line_skip();       if (option == 0) break;      switch(option) {     case 1: student_list = insert(student_list);    break;     case 2: search(student_list);                   break;     case 3: student_list = delete(student_list);    break;     case 4: print_list(student_list);               break;     case 5: student_list = mergesort(student_list); break;     default:       printf("incorrect option: %d\n", option); pause();     }   }    delete_list(student_list); /* not necessary in example */   printf("bye!\n");   return 0; }  struct node* mergesort(struct node* student_list) {   struct node* list1 = student_list;   struct node* list2 = student_list;    if (student_list == null || student_list->next == null)     return student_list;    while ((list2 = list2->next) != null &&           (list2 = list2->next) != null)     list1 = list1->next;    list2 = list1->next;    list1->next = null ;   list1 = student_list;    list1 = mergesort(list1);   list2 = mergesort(list2);    return merge(list1, list2); }  struct node* merge(struct node* list1, struct node* list2) {   struct node *list, *prev;    if (list1 == null) return list2;   if (list2 == null) return list1;    if (list1->number <= list2->number) {     list = list1; list1 = list1->next;   } else {     list = list2; list2 = list2->next;   }    prev = list;    while (list1 != null && list2 != null) {     if (list1->number <= list2->number) {       prev->next = list1;       list1 = list1->next;     } else {       prev->next = list2;       list2 = list2->next;     }     prev = prev->next ;   }    if (list1 != null)     prev->next = list1;   else     prev->next = list2;    return list; }  struct node* insert(struct node* student_list) {   struct node* student = malloc(sizeof(struct node));   /* why incorrect use "struct node student;" ? */    if (student == null ) {     printf("out of memory new student!\n"); pause();     return student_list;   }    printf("\nadding new student\n");   printf("enter student's number: ");   if (scanf("%d", &student->number) != 1) {     printf("incorrect student number: ");     line_copy(); pause();     free(student); /**/     return student_list;   }   line_skip();          /* skip newline character */    printf("enter student's name: ");   read_line(student->name, name_len);    student->next = student_list;   printf("student %d added.\n", student->number); pause();    return student; }  void print_student(struct node* student) {   printf("number:%3d  name: %s\n", student->number, student->name); }  void print_list(struct node* student_list) {   printf("\nstudent list:\n");   while (student_list != null) {     print_student(student_list);     student_list = student_list->next;   }   pause(); }  void search(struct node* student_list) {   int number;    printf("enter student number: ");   if (scanf("%d", &number) != 1) {     printf("incorrect student number: ");     line_copy(); pause();     return;   }   line_skip();    while (student_list != null && number != student_list->number)      student_list = student_list->next;    if (student_list == null)     printf("not found.\n");   else     print_student(student_list);   pause(); }  struct node* delete(struct node* student_list) {   int number;   struct node *prev, *cur;    printf("enter student number: ");   if (scanf("%d", &number) != 1) {     printf("incorrect student number: "); line_copy(); pause();     return student_list;   }   line_skip();    (cur = student_list, prev = null;        cur != null && cur -> number != number;        prev = cur, cur = cur->next)     ;    if (cur == null) {     printf("student not found!\n"); pause();     return student_list;   }    if (prev == null)     student_list = student_list->next;   else     prev->next = cur->next;    free(cur);   return student_list; }  void delete_list(struct node* student_list) {   struct node* temp;    while (student_list != null) {     temp = student_list;     student_list = student_list->next;     free(temp);   } }  /*auxiliary function int read_line(char line[], int len) {   int ch, = 0;    while ((ch = getchar()) != '\n' && ch != eof)      if (i < len)        line[i++] = ch;    line[i] = '\0';    return i; }  int line_skip() {   int ch;   while ( (ch=getchar()) != '\n' && ch != eof )     ;   return ch != eof; }  int line_copy() {   int ch;   while ( (ch=getchar()) != '\n' && ch != eof )     putchar(ch);   putchar('\n');   return ch != eof; }  int pause() {   printf("press enter continue...");   return line_skip(); } 

your headers contain type definitions , function declarations relevant sections of code. note if user code (primarily main.c) calls mergesort() , not merge(), mergesort.h header should declare mergesort() , merge() should static function in mergesort.c, hidden rest of code. header should define 'clients' need know; implementation details should kept hidden. remember ensure headers self-contained (so if mergesort.h needs know struct node, includes header declares struct node, example). ensure idempotent (so writing #include "header.h" twice won't cause compilation errors). done header guards such as:

#ifndef header_h_included #define header_h_included  …body of header file…  #endif /* header_h_included */ 

the source files contain implementations of functions declared in headers. source files include relevant headers. parts of code don't need know given structure type shouldn't need include header declares structure type.

the outline makefile can simple:

files.c = main.c student.c mergesort.c aux.c files.o = ${files.c:.c=.o}  all: students  students: ${files.o}     ${cc} ${cflags} -o $@ ${files.o} ${ldflags} ${ldlibs}  students.o:  students.h mergesort.o: mergesort.h aux.o:       aux.h 

since make knows how build xyz.o xyz.c, don't need specify dependencies. should declare headers used main.c (so need line such main.o: students.h mergesort.h aux.h, you've not indicated what's correct).


Comments

Popular posts from this blog

ruby on rails - RuntimeError: Circular dependency detected while autoloading constant - ActiveAdmin.register Role -

c++ - OpenMP unpredictable overhead -

javascript - Wordpress slider, not displayed 100% width -