第2天:函数与作用域
学习目标
掌握函数定义、调用和作用域规则,理解参数传递机制和函数重载。
学习内容
1. 函数声明与定义
- 函数声明(函数原型)
- 函数定义
- 函数重载
- 默认参数
- 内联函数
2. 参数传递机制
- 值传递:传递参数的副本
- 引用传递:传递参数的别名
- 指针传递:传递参数的地址
- 参数传递的性能考虑
3. 函数重载
- 重载的条件
- 重载解析过程
- 重载与类型转换
- 重载的注意事项
4. 作用域与生存期
- 局部作用域
- 全局作用域
- 块作用域
- 命名空间作用域
- 静态变量
5. 递归函数
- 递归的基本概念
- 递归的终止条件
- 递归的性能考虑
- 尾递归优化
重点概念
函数声明与定义
1 2 3 4 5 6 7 8 9 10 11 12 13
| int add(int a, int b); double calculateArea(double radius);
int add(int a, int b) { return a + b; }
double calculateArea(double radius) { const double PI = 3.14159; return PI * radius * radius; }
|
参数传递方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| void passByValue(int x) { x = 100; }
void passByReference(int& x) { x = 100; }
void passByPointer(int* x) { *x = 100; }
void passByConstReference(const string& str) { }
|
函数重载
1 2 3 4 5 6 7 8 9 10 11
| int add(int a, int b); int add(int a, int b, int c);
int add(int a, int b); double add(double a, double b);
void print(int a, double b); void print(double a, int b);
|
默认参数
1 2 3 4 5 6 7 8 9
| void printInfo(string name, int age = 18, string city = "Unknown") { cout << "Name: " << name << ", Age: " << age << ", City: " << city << endl; }
printInfo("Alice"); printInfo("Bob", 25); printInfo("Charlie", 30, "Beijing");
|
递归函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| int fibonacci(int n) { if (n <= 1) return n; return fibonacci(n - 1) + fibonacci(n - 2); }
int factorial(int n) { if (n <= 1) return 1; return n * factorial(n - 1); }
int factorialTail(int n, int acc = 1) { if (n <= 1) return acc; return factorialTail(n - 1, n * acc); }
|
作用域详解
局部作用域
1 2 3 4 5 6 7 8 9
| void function() { int localVar = 10; { int blockVar = 20; } }
|
全局作用域
1 2 3 4 5 6 7 8 9
| int globalVar = 100;
void function1() { globalVar = 200; }
void function2() { cout << globalVar << endl; }
|
静态变量
1 2 3 4 5 6 7
| void counter() { static int count = 0; count++; cout << "Count: " << count << endl; }
|
实践练习
练习1:基本函数操作
实现各种数学运算函数,包括加减乘除、幂运算等。
练习2:参数传递比较
比较值传递、引用传递和指针传递的性能差异。
练习3:函数重载应用
实现一个字符串处理类,支持多种参数类型的构造函数。
练习4:递归算法实现
实现常见的递归算法,如汉诺塔、快速排序等。
常见错误与注意事项
- 函数声明与定义不匹配:参数类型、个数、顺序必须一致
- 递归没有终止条件:会导致栈溢出
- 引用传递未初始化:会导致编译错误
- 函数重载歧义:编译器无法确定调用哪个函数
- 默认参数位置错误:默认参数必须从右到左连续
性能考虑
- 小对象使用值传递:避免不必要的间接访问
- 大对象使用引用传递:避免拷贝开销
- 只读参数使用const引用:既避免拷贝又防止修改
- 频繁调用的小函数使用内联:减少函数调用开销
学习检查点
扩展阅读
- C++ Primer 第6章:函数
- Effective C++ 条款20-25:函数设计
- 了解函数指针和函数对象的概念
返回第一周 | 上一天:变量与数据类型 | 下一天:数组与字符串