Functions & Modular Thinking
I. In-Class Exercises
Programming Exercises
II. Knowledge Summary
✨ Core Concept of Functions
The essence of a function is to teach the computer how to do something — it bundles a group of instructions together and gives them a name. Functions can have inputs and outputs, which increases their versatility.
Function-based thinking is a modular way of thinking that helps us isolate functionality, increases code reusability, and greatly simplifies code writing.
✨ Creating Functions
Creating a function involves a function declaration and a function definition.
Function Declaration
A function declaration only needs to specify the function's return type, function name, and parameters. It must be written before any calls or definitions — typically placed before the main program. If the function body is provided at the time of declaration, a separate definition is not needed.
A function declaration must include:
- Return type of the function
- Name of the function (can be empty)
- Parameters of the function (can be none)
// Function declaration
return_type function_name(param1_type param1, param2_type param2, ...);int my_max(int a, int b);Function Definition
A function definition specifies the actual implementation of the function. If the implementation was already provided in the declaration, a separate definition is not needed.
A function definition includes:
- The declaration — the return type, function name, and parameters
- The function body
- A return statement (void functions may omit the return statement)
1// Function declaration
2return_type function_name(param1_type param1, param2_type param2, ...);
3
4
5// Function definition
6return_type function_name(param1_type param1, param2_type param2, ...) {
7 code to execute
8
9 return return_value
10}1// Function declaration
2int my_max(int a, int b);
3
4// Function definition
5int my_max(int a, int b) {
6 if (a > b) {
7 return a;
8 }
9 return b;
10}✨ Important Notes About Functions
1. Function Return Types
A function's return type can be:
- Basic data types: integer, floating-point, character, boolean
- Complex data types: string and other complex data
- void: for procedure-like functions that do not return a value
2. void Functions
A function can have no return value. Functions without a return value should use void as the return type.
3. Function Names
Function naming rules are the same as variable naming rules. Generally, functions cannot share the same name unless they perform the same task with different parameters (different number or types of parameters) — this is called overloading.
4. Return Statements
Functions use the return statement to return a value. Once a return statement is executed, any code after it will not run.
For void functions, write return; directly. Void functions can also omit the return statement — the compiler will automatically add return; at the end.
✨ Calling Functions
To call a function, simply use the function name followed by parentheses. For functions with parameters, provide the actual arguments inside the parentheses.
1#include <bits/stdc++.h>
2using namespace std;
3
4// Function declaration
5int my_max(int a, int b);
6
7int main() {
8 int num1, num2;
9 cin >> num1 >> num2;
10 int max_number = my_max(num1, num2);
11 cout << max_number << endl;
12}
13
14// Function definition
15int my_max(int a, int b) {
16 if (a > b) {
17 return a;
18 }
19 return b;
20}✨ Function Overloading
When multiple functions share the same name but have different parameters (different number or types of parameters), they are called overloaded functions.
The following two functions both return the smaller of two numbers, but the first compares int data while the second compares double data.
1#include <iostream>
2//#include <bits/stdc++.h>
3using namespace std;
4
5double min(int num1, int num2);
6double min(double num1, double num2);
7
8int main() {
9 cout << min(2, 4) << endl;
10 cout << 3 / min(2, 4) << endl;
11 cout << min(0.2, 0.8) << endl;
12// cout << min(0.2, 2) << endl;
13 return 0;
14}
15
16double min(int num1, int num2) {
17 if (num1 < num2) {
18 return num1;
19 }
20 return double(num2);
21}
22
23double min(double num1, double num2) {
24 if (num1 < num2) {
25 return num1;
26 }
27 return num2;
28}✨ Execution Example of Function Calls
The complete flow of a function call can be illustrated by the following diagram:
Below is an example using the "Pure Composite Number" problem to demonstrate how a function is called and returns.
Problem: Determine whether every digit of a number is a composite digit (4, 6, 8, 9). If so, the number is called a pure composite number.
1// Check whether a digit is a composite digit (4, 6, 8, 9)
2bool isCompositeDigit(int d) {
3 return d == 4 || d == 6 || d == 8 || d == 9;
4}
5
6// Check whether a number is a pure composite number
7bool isPureComposite(int n) {
8 while (n > 0) {
9 int d = n % 10;
10 if (!isCompositeDigit(d)) {
11 return false;
12 }
13 n = n / 10;
14 }
15 return true;
16}Execution trace (n = 468):
| Step | Function | n | d | isCompositeDigit(d) | Action |
|---|---|---|---|---|---|
| 1 | isPureComposite | 468 | 8 | call -> true | continue |
| 2 | isPureComposite | 46 | 6 | call -> true | continue |
| 3 | isPureComposite | 4 | 4 | call -> true | continue |
| 4 | isPureComposite | 0 | - | - | Loop ends, return true |
Execution trace (n = 462):
| Step | Function | n | d | isCompositeDigit(d) | Action |
|---|---|---|---|---|---|
| 1 | isPureComposite | 462 | 2 | call -> false | return false (early exit) |
Key insight: A function call is like a "jump" — the main program jumps into the function to execute, and after the function finishes, it jumps back to the main program to continue. Each time a function is called, parameters receive new values, and the function's internal variables do not affect external ones.
✨ When to Use Functions
Signal 1: The same code appears multiple times. If you find yourself copying and pasting code, it is a sign that you should extract it into a function.
Signal 2: The logic can stand alone. For example, "check if a number is prime," "find the greatest common divisor," or "swap two numbers" — these are complete, independent operations suitable for encapsulation as functions.
Signal 3: The code is too long to read easily. When the main function exceeds 50 lines, consider splitting its logic into multiple functions, each completing a clear task.
Steps to design a function:
- Define the purpose: What should this function do? Describe it in one sentence.
- Determine the inputs: What parameters are needed? What are their types?
- Determine the output: What type is the return value? void or something else?
- Implement the logic: Write the function body.
- Test: Verify the function with several test cases.
✨ Common Mistakes with Functions
- Mismatched declaration and definition parameters: Declaring
int my_max(int a, int b);but definingint my_max(int a, double b) {...}— the different parameter types cause the compiler to treat them as two different functions. - Forgetting the return statement: If a non-void function has no return statement, the compiler may only issue a warning without an error, but the return value is undefined, leading to hard-to-find bugs.
- Using function-local variables outside the function: Variables defined inside a function are local variables that only exist within the function. After the function finishes, local variables are destroyed. If you need to pass a result out, use return.
- Swapping parameter order in function calls: For example, writing
strcpy(src, dst)asstrcpy(dst, src)— this kind of mistake is even more common with custom functions. - Forgetting the termination condition in recursive calls: Although this lesson does not cover recursion, if a function calls itself directly or indirectly without a termination condition, the program will loop infinitely until a stack overflow crash.
III. Homework
Knowledge Quiz
- Functions and Modular Thinking - Quiz## Programming Exercises