ScholarQuill logoScholarQuillUniversity Notes
  • Notes
  • Past Papers
  • Blogs
  • Todo
Login
ScholarQuill logoScholarQuillUniversity Notes
Login
NotesPast PapersBlogsTodo
More
SubjectsDiscussionCGPA CalculatorGPA CalculatorStudent PortalCourse Outline
About
About usPrivacy PolicyReportContact
Notes
Past Papers
Blogs
Todo
Analytics
    Current Subject
    🧩
    Programming Fundamentals
    CC-112
    Progress0 / 39 topics
    Topics
    1. Introduction to Problem Solving, Algorithms, Programming, and C Language2. Problem Solving, a brief review of Von-Neumann Architecture3. The C Programming Language, Pseudo-code, Concept of Variable4. Data types in Pseudo-code, The C Standard Library and Open Source5. Input/Output, Arithmetic expressions, Assignment statement, Operator precedence6. Concept of Integer division, Flowchart and its notations7. Typical C Program Development Environment, Role of Compiler and Linker8. Test Driving C Application9. Introduction to C Programming: A Simple C Program: Printing Text, Adding Two Integer10. Memory Concepts, Arithmetic in C, Operators11. Decision Making: Equality and Relational Operators12. Structured Program Development: The if, if...else, while Nested Control Statements13. Program Control: for, switch, do...while, break, continue, Logical Operators14. Functions: Modularizing Program in C, Math Library Functions15. Function Definitions and Prototypes, Function-Call Stack and Stack Frames16. Stack rolling and unrolling, Headers, Passing Arguments by Value and by Reference17. Random Number Generation, Scope Rules, Recursion, Recursion vs Iteration18. Arrays: Defining Arrays, Character Arrays, Static and Automatic Local Arrays19. Passing Arrays to Function, Sorting and Searching Arrays20. Multidimensional and Variable Length Arrays21. Pointers: Pointer Definitions and Initialization, Pointer Operators22. Passing Arguments to Function by Reference, Using the const and sizeof Operator23. Pointer Expressions and Arithmetic, Pointers and Arrays, Array of Pointers24. Function Pointers25. Characters and Strings: Strings and Characters, Character Handling Library26. String Functions, Library Functions27. Formatted Input/Output: Streams, Formatted Output with printf, Formatted Input with scanf28. Structures: Defining Structures, Accessing Structure Member, Structures and Functions29. typedef, Unions30. Bit Manipulation and Enumeration: Bitwise Operators, Bit Fields, Enumeration Constants31. File Processing: Files and Streams, Creating, Reading and Writing data to a Sequential and a Random-Access File32. Preprocessor: #include, #define, Conditional Compilation, #error and #pragma33. # and ## Operators, Predefined Symbolic Constants, Assertions34. Other Topics: Variable Length Argument List, Using Command Line Arguments35. Compiling Multiple-Source-File Programs, Program Termination with exit and atexit36. Suffixes for Integer and Floating-Point Literals, Signal Handling37. Dynamic Memory Allocation: calloc and realloc, goto38. Advance Topics: Self-Referential Structures, Linked Lists39. Efficiency of Algorithms, Selection and Insertion Sort
    CC-112›Compiling Multiple-Source-File Programs, Program Termination with exit and atexit
    Programming FundamentalsTopic 35 of 39

    Compiling Multiple-Source-File Programs, Program Termination with exit and atexit

    6 minread
    1,054words
    Intermediatelevel

    Compiling Multiple-Source-File Programs, Program Termination with exit and atexit

    In larger C programs, it's common to break the code into multiple source files for better organization and maintainability. Additionally, C provides functions like exit() and atexit() to manage program termination and perform cleanup operations. Let’s dive into both these topics.


    1. Compiling Multiple-Source-File Programs

    When working with large programs, it’s common practice to break the program into multiple source files. This approach helps in organizing the program logically and makes it easier to maintain and scale.

    Why Multiple Source Files?

    • Modularity: Different parts of the program are logically grouped together in separate files (e.g., utility functions in one file, main program in another).
    • Reusability: Common code can be reused across multiple programs.
    • Easier Debugging: Smaller, focused files make debugging easier.
    • Collaboration: Multiple developers can work on different parts of the code simultaneously.

    Basic Compilation Process for Multiple Source Files

    Let’s consider a project with two source files:

    1. main.c — This contains the main function and program logic.
    2. helper.c — This contains helper functions used in main.c.
    Example Code:

    main.c

    #include <stdio.h>
    
    // Declaration of the helper function
    void helperFunction();
    
    int main() {
        printf("Program started\n");
        helperFunction();  // Calling the helper function
        return 0;
    }
    

    helper.c

    #include <stdio.h>
    
    // Definition of the helper function
    void helperFunction() {
        printf("This is a helper function\n");
    }
    
    Steps to Compile Multiple Source Files:
    1. Compile each source file:

      • You can compile each source file separately into an object file.
      • For example, using the gcc compiler:
        gcc -c main.c  # This compiles main.c into main.o
        gcc -c helper.c  # This compiles helper.c into helper.o
        
    2. Link the object files together:

      • Once the object files are created, you can link them together to create the final executable.
      • For example:
        gcc main.o helper.o -o program  # This links both object files into an executable named 'program'
        
    3. Run the program:

      • Finally, run the program:
        ./program
        

    Why This Works:

    • The gcc -c option compiles the source files into object files (.o files).
    • The linker (gcc) then combines the object files into a single executable.
    • The object files contain machine code but are not yet a complete program, so the linker is needed to resolve external references (like helperFunction() in main.c) and combine everything into a runnable executable.

    2. Program Termination with exit() and atexit()

    When writing programs in C, it's often necessary to properly handle program termination. The exit() function and the atexit() function are used for this purpose, allowing a program to terminate cleanly and perform necessary cleanup tasks before the program exits.

    exit() Function

    The exit() function is used to terminate a program immediately, regardless of where it is called. It also ensures that any resources (such as open files) are cleaned up properly before termination.

    • Syntax:

      void exit(int status);
      
      • status: The status code that is returned to the operating system. A value of 0 typically indicates successful completion, while a non-zero value indicates an error or abnormal termination.
    • How it Works:

      • Termination: The program terminates immediately when exit() is called.
      • Cleanup: Before the program terminates, exit() performs some standard clean-up activities like flushing file buffers and closing open files.
    • Example:

      #include <stdio.h>
      #include <stdlib.h>
      
      int main() {
          printf("Program is starting\n");
      
          // Exit with status code 0 (success)
          exit(0);  // Program terminates here
      
          // This part will not be executed
          printf("This will not be printed\n");
      
          return 0;
      }
      

      Explanation:

      • After exit(0) is called, the program terminates, and the statement printf("This will not be printed\n"); is never executed.

    atexit() Function

    The atexit() function registers a function that will be executed when the program terminates. This is useful for performing clean-up tasks such as releasing memory or closing files before the program exits.

    • Syntax:

      int atexit(void (*func)(void));
      
      • func: A pointer to a function that takes no arguments and returns no value. This function will be executed when the program terminates.
    • How it Works:

      • You can register a function to be called upon normal program termination using atexit().
      • Multiple functions can be registered, and they will be executed in the reverse order of their registration when the program exits.
    • Example:

      #include <stdio.h>
      #include <stdlib.h>
      
      void cleanup() {
          printf("Cleaning up resources...\n");
      }
      
      int main() {
          // Register the cleanup function to be called at program exit
          if (atexit(cleanup) != 0) {
              printf("Failed to register cleanup function\n");
              return 1;
          }
      
          printf("Program is running\n");
      
          // Program termination
          exit(0);  // Calls cleanup() before exiting
      
          return 0;
      }
      

      Explanation:

      • The cleanup() function is registered to be called when the program exits via atexit().
      • When exit(0) is called, the cleanup() function is invoked before the program terminates.
      • The output will be:
        Program is running
        Cleaning up resources...
        

    Key Points of exit() and atexit()

    Function Purpose Key Notes
    exit() Terminates the program immediately. - Can specify an exit status (e.g., 0 for success).
    atexit() Registers a function to be called at program termination. - Used to clean up resources like memory or files before exit.
    Exit Status exit() returns a status code to the operating system (0 for success, non-zero for failure). - This exit status can be retrieved by the operating system or parent process.

    Summary

    • Compiling Multiple Source Files: When you have multiple source files in a C program, you can compile them separately into object files and then link them together to create a single executable. This modular approach improves maintainability and scalability.
    • Program Termination with exit(): The exit() function terminates the program immediately, allowing you to specify a status code. It performs cleanup operations, such as flushing output buffers and closing files, before termination.
    • Using atexit(): You can use atexit() to register cleanup functions that will be executed when the program terminates normally. This ensures that necessary resources are freed before the program exits.

    These tools allow you to manage program termination gracefully and organize large programs efficiently, enhancing the overall functionality and maintainability of your code.

    Previous topic 34
    Other Topics: Variable Length Argument List, Using Command Line Arguments
    Next topic 36
    Suffixes for Integer and Floating-Point Literals, Signal Handling

    Past Papers

    Open this section to load past papers

    Click on Show Past Papers to see past papers.
    On This Page
      Reading Stats
      Est. reading time6 min
      Word count1,054
      Code examples0
      DifficultyIntermediate