函数:
- 函数的作用:函数可以用来定义可重用的代码,并组织和简化这些代码。
二、函数的缺点:函数的调用要一定的时间和空间的开销。
三、函数的分类:内联函数,普通函数。
1、普通函数:
1)函数的定义:函数由返回值类型、函数名、参数和函数主体构成。
如: returnValueType functionName(list of parameters)
{
//function body;
}
- 返回值的类型:
void类型。当函数只执行特定的操作,而不返回值时,返回值类型部分使用关键字void。同时在函数最后可不写return xxx,或者书写“return;”结束函数返回调用者。对于void函数的调用必须作为一条语句。
当函数为非void类型时,函数可以返回一个具体的值。也可以结合指针返回一个指针,或结合引用返回一个引用。
- 函数的参数:
在函数头中定义的变量称为形式参数(formal parameter)或简称为参数。调用函数时被传递的值为实际参数或自变量。参数类表中指明了参数的类型和次序和数量。
同时函数也可以定义缺省的参数。当函数有多个参数时,参数只能从后向前挨个缺省,否者将导致程序出现错误。如:
正确定义:void function(int x, int y=0, int z=0);
错误定义:void function(int x=0, int y, int z=0);当调用一个函数时,如果一个参数未给出,那么在他之后的所有参数也不能给出。如:
function(1, ,20)//is illegal
function(1);or function(1,2,3)//is right
- 函数的原型::
函数的原型声明了一个函数,但没有实现它。可在main函数之前进行函数的声明并在main函数之后进行函数的实现。或者在函数声明时进行函数的实现。在函数的原型中不必出现参数的名字,只列出参数的类型便可,C++编译器在处理函数的原型时实际上是忽略参数名的。
- 函数的调用:
当函数完成相应的工作,并返回调用者之后与之关联的活动记录将从栈中释放,对于栈中元素的存取按照先进后出的方式(last-in first-out)。
- 参数的传递:
- 值传递:值传递传递的参数有着自己的内存对形参进行操作不会改变实参的值。
如:void test(int a)
{
a+=10;
cout << "a的值:" << a << "\n" << "a的地址:" << &a << endl;
}
int main()
{
int number=10;
test(number);
cout << "number的值:" << number << "\n" << "number的地址:" << &number << endl;
return 0;
}
结果为:
a的值:20
a的地址:0x6ffde0
number的值:10
number的地址:0x6ffe0c
- 指针传递:传入参数的地址,通过地址获取实参对其进行操作,会改变它的值。
如:
void test(int* a)
{
*a+=10;
cout << "a指向的地址:" << a << "\n" << "a指向的地址的值:" << *a << endl;
}
int main()
{
int number=10;
test(&number);
cout << "number的地址:" << &number << "\n" << "number的值:" << number << endl;
return 0;
}
结果如下:
a指向的地址:0x6ffe0c
a指向的地址的值:20
number的地址:0x6ffe0c
number的值:20
- 引用传递:在参数传递时加上&符,其余和值传递相同。想当于是对变量起的别名,他们共享内存,操作的实际上是同一个地址。注意:1 使用引用传递时形参和实参的类型必须相同。2 实际参数必须是一个变量。
如:int& r = count 声明引用变量r来引用变量count
如:void test(int& a)
{
a+=10;
cout << "a指向的地址:" << &a << "\n" << "a的值:" << a << endl;
}
int main()
{
int number=10;
test(number);
cout << "number的地址:" << &number << "\n" << "number的值:" << number << endl;
return 0;
}
结果如下:
a指向的地址:0x6ffe0c
a的值:20
number的地址:0x6ffe0c
number的值:20
- 函数的重载:可以用同样的名字命名函数,只要函数的签名不同。重载函数可以使程序更加清晰和更具有可读性。注意当两个或者多个函数匹配调用时,编译器就不能区分出哪一个是最佳匹配的函数,就会导致模糊调用(ambiguous invocation),出现编程错误。
模板函数:模板函数的定义以template开始后面跟一个参数列表。每一个参数前面都要有一个关键字typename如:
Template<typename T>
T maxValue(const T& value1, const T& value2)
{
//function body;
}
2、内联函数:
内联函数用于提高短函数的性能,避免了函数调用时的开销。内联函数是不会被调用的,编译器是将代码复制到每一个调用点上。将一个函数声明为内联函数只需要在函数声明前加上关键字inline。如:
Inline void f(int month, int year)
注意内联函数inline关键字只是向编译器放送一个请求,C++编译器会对过长的函数忽略inline关键字,因此内联函数只适用于短函数的调用。
- 局部、全局和静态局部变量
局部变量:在函数内部定义的变量。
全局变量:在所用函数之外定义的变量,可以被作用域内的所用函数访问。
局部变量没有缺省值,全局变量的缺省值为0。在函数中定义一个与全局变量同名的局部变量,根据就近原则在函数的内部只有局部变量是可见的。
静态局部变量:保留局部变量的值,便于在下次调用时使用。在程序的整个生命周期中,静态局部变量会一直驻存在内存中。使用关键字static声明静态局部变量。注意:静态局部变量的初始化只在第一次调用时发生,调用后就一直存在内存中。
- 函数抽象与逐步求精:
函数抽象就是将函数的实现和函数的使用相分离,实现信息的隐藏(封装)。
将函数抽象的思想用于程序的开发,编写大程序时,可以使用分治的策略(逐步求精),将原问题分解成若干个小的问题,进而得到更小更易处理的问题。