C++函数
1.为什么要用函数?
- 实现代码的重用性
- 易维护
- 封装性(保密)
/** * Fibonacci函数的实现 * @param x * @return */ int Fibonacci(int x) { if(x == 1 || x ==2) return 1; return Fibonacci(x - 1) + Fibonacci(x - 2); } int main() { int x; cout << "请输入Fibonacci的项数" << endl; cin >> x; int m; m = Fibonacci(x); cout << m; return 0; }
我们就能重复的调用封装起来的函数来实现功能,并且函数也易维护。
2.为什么要用函数重载?
假如我们在C中要定义一个打印print函数,它可以输出整型,字符型,字符串。虽然这些函数的功能类似,但是我们必须将他们声明成不同的名字让编译器进行区分,比如:
void print_int(int a); void print_char(char c); void print_string(char *str);
而在C++中我们可以利用函数重载以便于将这些函数的名字统一起来:
void print(int a); void print(char c); void print(char *str);
函数的名字仅仅是让编译器直到它调用的是哪个函数,用户并不关心函数的名字。而函数重载可以再一定程度上减轻程序员起名字,记名字的负担。
3.什么是值传递
按值传递:在调用函数中将原函数的值拷贝一份过去被调用的函数,在被调用函数中对该值的修改不会影响原函数的值。
#include<iostream> using namespace std; void changeNumber(int x); int main() { int a = 10; cout << "a = " << a << endl; changeNumber(a); cout << "Now a = " << a << endl; return 0; } void changeNumber(int x) { x = x + 5; }
可以看到,a并没有被改变。原因很简单,按值传递,当调用changeNumber()函数的时候,以 a 作为实际参数,在程序跳到changeNumber()函数的时候,会拷贝一份a的数据,也就是说,在内存空间中重新开辟了一块空间,它的作用就是用来存储a的值,并且这块空间的名称为 x,也就是changeNumber()中的这个x,注意,这个x所在的空间和a所在的空间是完全不同的两块内存(通过对他们分别输出地址可以得出),既然他们根本不属于同个地方,那么对x所作的任何修改都无法影响a。
4.什么是地址传递?
区别于值传递
按地址传递:在调用函数的时候将原函数的值所在的地址拷贝一份过去,被调用函数对这个地址所作的修改会影响原来的值。
#include<iostream>
using namespace std;
void changeNumber(int* x);
int main(void) { int a = 10; cout << "a = " << a << endl; changeNumber(&a); cout << "Now a = " << a << endl; return 0; }
void changeNumber(int* x) { *x = *x + 5; }
这里的代码就是按地址传递,首先在changeNumber()的声明中,使用了int*类型而不是int类型,其次在main()函数调用changeNumber()函数的时候使用的实参是&a而不是a,这就传递了一个地址给changeNumber()函数,这个changeNumber()就可以完成修改a的任务。
5.如何编写递归函数?
递归,递归就是一个函数在它的函数体内调用它自身。执行递归函数将反复调用其自身,每调用一次就进入新的一层。
其实递归函数在使用时只需要明确一点:我写这个函数是干嘛用的,比如在用递归写计算Fibonacci级数的C语言程序时,只需要明确我写的函数是用来计算Fibonacci(x - 1) + Fibonacci(x - 2),写起来就会很简单。
/** * Fibonacci函数实现递归调用 * @param x * @return */ int Fibonacci(int x) { if(x == 1 || x ==2) return 1; return Fibonacci(x - 1) + Fibonacci(x - 2); } int main() { int x; cout << "请输入Fibonacci的项数" << endl; cin >> x; int m; m = Fibonacci(x); cout << m; return 0; }
而且要明确一点,那就是:递归调用的时候必须要有终止条件,也就是递归终点。否则程序就会一直递归,直到栈溢出。