Let’s take a look at #include. #include is a kind of C preprocessor directive. Its processing is simple: it inserts the contents of the header file at the position of the directive, thereby joining the header file and the current source file into a single source file — the same effect as copy-paste.

We are generally very familiar with including header files via #include "*.h", but actually #include can be used in other ways, for example as shown below: In the main.c source file, adding #include "print.c" is equivalent to copying the code from print.c into the specified position in main.c.

/* 
 *#include study examples 
 * main.c
 */
#include<stdio.h>

#include "print.c"  

int main() {
    print("test #include");

    return 0;
}

The source of print.c is as follows:

/* print.c */
void print(const char *str) {
    printf("%s \n", str);
}

We run gcc -E main.c to perform only preprocessing and inspect the result:

# 1 "main.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "main.c"

# 1 "/usr/include/stdio.h" 1 3 4
# 27 "/usr/include/stdio.h" 3 4
# 1 "/usr/include/features.h" 1 3 4
# 375 "/usr/include/features.h" 3 4
# 1 "/usr/include/sys/cdefs.h" 1 3 4
# 392 "/usr/include/sys/cdefs.h" 3 4
# 1 "/usr/include/bits/wordsize.h" 1 3 4
# 393 "/usr/include/sys/cdefs.h" 2 3 4
# 376 "/usr/include/features.h" 2 3 4
# 399 "/usr/include/features.h" 3 4
# 1 "/usr/include/gnu/stubs.h" 1 3 4
# 10 "/usr/include/gnu/stubs.h" 3 4
# 1 "/usr/include/gnu/stubs-64.h" 1 3 4
# 11 "/usr/include/gnu/stubs.h" 2 3 4
# 400 "/usr/include/features.h" 2 3 4
# 28 "/usr/include/stdio.h" 2 3 4

// too much intermediate code, omitted; keep only the key parts.

# 943 "/usr/include/stdio.h" 3 4

# 3 "main.c" 2

# 1 "print.c" 1

// you can see the included file's content was copied to the position of #include "print.c".
void print(const char *str) {
    printf("%s \n", str);
}
# 5 "main.c" 2

int main() {
    print("test #include");

    return 0;
}