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›# and ## Operators, Predefined Symbolic Constants, Assertions
    Programming FundamentalsTopic 33 of 39

    # and ## Operators, Predefined Symbolic Constants, Assertions

    5 minread
    931words
    Intermediatelevel

    Preprocessor Operators in C: # and ## Operators, Predefined Symbolic Constants, Assertions

    In C, the preprocessor offers several useful tools for manipulating source code before the actual compilation begins. Among these are the # and ## operators, predefined symbolic constants, and assertions. These tools enhance flexibility, readability, and debugging during the development process.


    1. # and ## Operators

    The # and ## operators are used in macro definitions to manipulate the arguments passed to the macro. They allow you to create more powerful and flexible macros.

    # Operator (Stringizing Operator)

    The # operator is known as the stringizing operator. It converts the argument passed to the macro into a string literal.

    Syntax:

    #define MACRO_NAME(arg) "string" #arg "string"
    

    Example:

    #include <stdio.h>
    
    #define STRINGIFY(x) #x
    
    int main() {
        printf("Macro as string: %s\n", STRINGIFY(Hello, World!));  // Prints: "Hello, World!"
        return 0;
    }
    

    Explanation:

    • STRINGIFY(Hello, World!) converts the argument Hello, World! into a string literal "Hello, World!".
    • In this case, the argument x is surrounded by double quotes, transforming it into a string.

    ## Operator (Token Pasting Operator)

    The ## operator is known as the token pasting operator or concatenation operator. It combines two tokens into a single token. This can be especially useful when generating complex code inside macros, where you need to concatenate multiple identifiers.

    Syntax:

    #define CONCATENATE(x, y) x ## y
    

    Example:

    #include <stdio.h>
    
    #define CONCATENATE(x, y) x ## y
    
    int main() {
        int xy = 10;
        printf("The value of xy: %d\n", CONCATENATE(x, y));  // Prints: The value of xy: 10
        return 0;
    }
    

    Explanation:

    • CONCATENATE(x, y) combines the two tokens x and y into xy, which refers to the variable int xy = 10;.
    • The ## operator concatenates the two arguments into a single token, effectively creating xy as a variable name.

    2. Predefined Symbolic Constants

    The C preprocessor defines several predefined symbolic constants that provide useful information about the environment in which the code is compiled. These constants are available without needing any additional definitions.

    Common Predefined Constants:

    • __LINE__: Expands to the current line number in the source file.
    • __FILE__: Expands to the name of the current source file as a string.
    • __DATE__: Expands to a string representing the date when the source file was compiled (e.g., "Sep 21 2021").
    • __TIME__: Expands to a string representing the time when the source file was compiled (e.g., "10:45:12").
    • __STDC__: Expands to 1 if the compiler conforms to the ANSI C standard.

    Examples:

    #include <stdio.h>
    
    int main() {
        printf("Line number: %d\n", __LINE__);  // Prints the current line number
        printf("File name: %s\n", __FILE__);    // Prints the name of the current file
        printf("Compilation date: %s\n", __DATE__); // Prints the date when compiled
        printf("Compilation time: %s\n", __TIME__); // Prints the time when compiled
        return 0;
    }
    

    Explanation:

    • __LINE__, __FILE__, __DATE__, and __TIME__ expand to relevant information about the compilation process.
    • These constants are useful for debugging and logging information related to the compilation environment.

    3. Assertions: assert()

    Assertions are a way to test assumptions made by the programmer during development. An assertion verifies whether a given condition is true; if the condition evaluates to false, the program will terminate and print an error message. Assertions are commonly used for debugging and ensuring that certain conditions hold during runtime.

    The assert() function is part of the <assert.h> library.

    Syntax:

    #include <assert.h>
    
    assert(condition);
    
    • condition: This is the expression that should evaluate to true. If the expression is false, the program will abort.

    Example:

    #include <stdio.h>
    #include <assert.h>
    
    int main() {
        int x = 5;
        assert(x == 5);  // This will not cause any issue because x == 5 is true.
    
        x = 10;
        assert(x == 5);  // This will terminate the program because x == 5 is false.
    
        printf("This line will not be executed.\n");
    
        return 0;
    }
    

    Explanation:

    • assert(x == 5) will check if x is equal to 5. If true, the program continues. If false, the program aborts, and an error message is displayed.
    • When the assertion fails (in this case when x is 10), the program prints a message similar to:
      Assertion failed: (x == 5), file program.c, line 9
      
    • This can be useful during development to catch bugs and invalid assumptions about the state of the program.

    Disabling Assertions:

    Assertions can be disabled by defining the NDEBUG macro before including <assert.h>:

    #define NDEBUG
    #include <assert.h>
    

    With NDEBUG defined, the assertions will be excluded from the compiled program, effectively making them no-ops.


    Summary of Concepts

    Concept Description
    # Operator (Stringizing) Converts an argument into a string literal.
    ## Operator (Concatenation) Concatenates two tokens into one.
    Predefined Constants Constants like __LINE__, __FILE__, __DATE__, and __TIME__ that give information about the compilation environment.
    assert() Used for debugging by ensuring that a given condition is true at runtime. If false, the program terminates.

    Conclusion

    The # and ## operators provide powerful tools for manipulating macro arguments in C, enabling string conversion and token concatenation. Predefined symbolic constants offer valuable insights into the environment in which the code is compiled, and assertions help ensure that runtime conditions hold as expected during development. These tools help create more robust, maintainable, and error-free C code.

    Previous topic 32
    Preprocessor: #include, #define, Conditional Compilation, #error and #pragma
    Next topic 34
    Other Topics: Variable Length Argument List, Using Command Line Arguments

    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 time5 min
      Word count931
      Code examples0
      DifficultyIntermediate