
In the world of programming, the biggest difference between beginners and experts often lies not in how many algorithms they know, but in how they organize their code.
Have you ever experienced a situation where, to implement a repetitive function, you keep usingCtrl+C and Ctrl+V, only to find that the main function has become long and unwieldy, and when you need to modify a detail, you have to change it in dozens of places at once?
If your answer is yes, then congratulations, you are creating what is known as a “spaghetti code”.
Today, we will take you deep into understanding the core essence of C language—functions, and learn how to manage your code like a mechanic manages a toolbox.
01
Myth Correction: Functions are not Mathematical Formulas
First, we need to correct a concept. In mathematics, a function (Function) emphasizes the “mapping relationship” (e.g., y=f(x)).
However, in computer science (especially in C language),Function should be understood as a “functional block” or “subroutine”.
Its core purposes are only two:
-
Modularity: Breaking down complex logic.
-
Reusability: Write once, use everywhere.
02
Addressing Pain Points: Why Use Functions?
Let’s look at a typical “beginner’s code”
#include <stdio.h>
int main() { // Simulating a chaotic code // Requirement: Output separator -> Output loop data -> Output separator -> Output loop data...
// First operation printf("--------------------\n"); for (int i = 0; i < 5; i++) { printf("iiiii\n"); }
// Second operation (copy-paste) printf("--------------------\n"); for (int i = 0; i < 5; i++) { printf("iiiii\n"); }
// Third operation (continue copy-pasting...) printf("--------------------\n"); // ... Hundreds of lines of repeated code omitted...
return 0;}
What is the problem with this writing style?
Imagine you are repairing a television. You find that you need a screwdriver, so you run home to get one; after removing a screw, you find you need the same type of screwdriver again, and you actually run home to get a new one.
This “one-time use” logic is not only tiring but also extremely inefficient. If there are 100 instances of such logic in the code, once the boss says: “Change the separator to a wavy line ~~~~,” you will have to manually modify it 100 times. This is a nightmare.
The correct approach is: Take a “toolbox” to repair the television. The toolbox contains the tool “screwdriver” (Function), which you can use as many times as needed (Call).
03
Core Refactoring: Declaration, Definition, and Calling of Functions
To address the above pain points, we need to extract the repeated code. This involves three key steps in using functions in C language:Declaration, Call, and Definition..
1. Code Refactoring Practice
We need to separate the functions of “printing the separator” and “printing the loop i”. Please see the standard writing:
#include <stdio.h>
// 【1. Function Declaration (Function Prototype)】// Tell the compiler: “I will use these two function names later, please allow it”// Here, void means the function does not return any value (we will explain what this means later)void print_line(); void loop_i();
// Program entryint main() { // 【2. Function Call (Function Call)】 // Like calling an assistant: “Bring the toolbox” // At this point, the code logic is very clear, and the reader can see at a glance what is being done
print_line(); // Call the function to print the separator loop_i(); // Call the function to print the loop
print_line(); // Reuse again loop_i(); // Reuse again
print_line();
return 0;}
// 【3. Function Definition (Function Definition)】// Here are the specific implementation details inside the “toolbox”// When the compiler reaches the call instruction, it will jump here to execute the code
void print_line() { printf("--------------------\n");}
void loop_i() { for (int i = 0; i < 5; i++) { printf("iiiii\n"); }}
04
In-depth Analysis: Why Must We “Declare First”?
Careful students may have noticed that we wrote the specific code implementation (function definition) below the main function, while above the main function, we wrote a line of code with a semicolon. This is called “function prototype declaration”..
Why do this?
The C language compiler reads the code from top to bottom, line by line.
-
If we write the specific implementation of print_line() directly below the main function without declaring it in advance.
-
When the compiler reads main and encounters print_line(); it will be confused: “What is this? I have never seen this name before.” This will lead to an error or warning (Implicit declaration).
-
The purpose of declaration: is like giving the compiler a “list”.
-
You tell the compiler: “Brother, I have a function called print_line that does not return a value(void), and has no parameters(). The specific implementation will be done later, just don’t throw an error, let me pass.”
05
A Simple “Hello World” Function Example
To reinforce understanding, let’s look at the simplest greet function example:
#include <stdio.h>
// 1. Declare void greet();
int main() { // 2. Call (Call) // Call as many times as you want, extreme reusability greet(); greet(); greet();
return 0;}
// 3. Define (Definition)void greet() { printf("Hello!\n");}
Output:
Hello!Hello!Hello!
Through this simple example, we can see that the main function becomes very clean. It no longer cares about how to print Hello, it only controls the flow.
Professional Correction
In the original learning process, we may encounter some vague concepts; here, as a technical article, we need to clarify the standards:
1. Function Naming Conventions
-
We used print_line. This follows the common C language naming convention of snake_case, where words are connected by underscores and all are lowercase. This is more common than PrintLine (Pascal case) in C language.
2. Declaration Location
-
Although you can write the function definition directly above the main function (thus not needing a separate declaration), the standard practice in the industry is usually:
-
To write declarations in the .h header file. (This will be discussed in detail later)
-
To write definitions in the .c source file. (This will be discussed in detail later)
-
Or, when writing in a single file, strictly follow the “Top Declaration -> Middle Main -> Bottom Definition” structure. This ensures that the main function is always in the most prominent position, making it easy to read the program logic.(Key points to learn in this lesson)
06
Conclusion
Functions (Function) are the building blocks of programming in C language.
-
Encapsulation: Hides complex details and exposes simple interfaces.
-
Reusability: Rejects reinventing the wheel, rejects copy-pasting.
-
Maintenance: Modify one place, affect globally.