函数在c++编程是很重要的,我们下面就开始学习函数模块有关的内容。
函数定义包含:返回值、函数名、参数列表和函数体几个部分。如:
#include<iostream> using namespace std ; int simpleFun() ; //函数声明 int main(){ simpleFun() ; //函数调用 return 0 ; } //函数定义 int simpleFun() { cout << "This is a simple function !!!" << endl ; }
函数使用:包含函数定义、函数声明、函数调用几个过程。 函数声明中形参名可以省略,如:int function1(int ,int ) ;
函数分为:有返回值函数和无返回值函数,如:
void fun (int x ,int y) //没有返回值 { cout << "x : " << x << " y : " >> y << endl ; return ; } int sum_int (int x , int y ) //返回int类型值 { int sum = x + y ; return sum ; }
上面的函数都是值传递参数,就是调用函数时,创建临时变量x , y ,将传递给函数参数的值复制给x , y ,在函数中不能修改参数的值,修改的只是形参变量的值,函数调用完,形参就不存在了。
注意:要在函数中修改实参的值,可以使用指针或引用,当返回值不能使局部变量的指针或引用,因为当函数调用后,临时变量就不存在了。
void change(int) ; int main(){ int x = 4 ; change(x) ; cout << "main x :" << x << endl ; // x = 4 return 0 ; } void change(int x ) { x += 3 ; cout << "change x : " << x << endl ; // x = 7 }
数组不能作为参数传递给函数,使用时是把数组作为指针来传递的。如:
int sum_arr(int[] , int ) ; int sum_arr2(int * , int ) ; int main(){ int arr[] = {1, 2, 3, 4, 5} ; int len = sizeof arr / sizeof (int) ; sum_arr(arr , len) ; sum_arr2(arr , len ) ; } int sum_arr(int arr[] , int len) { int sum = 0 ; for(int i =0 ; i < len ; i++) { sum += arr[i] ; } return sum ; } int sum_arr2(int *p_i , int len) { int sum = 0 ; for(int i = 0 ; i < len ; i++ ) { sum += p_i[i] ; } return sum ; }
sum_arr和sum_arr2这两个函数作用相同,因为传递时都是传递的数组名,我们知道,数组名是指向数组第一个元素的地址,就是个指针。这时,我们就可以在函数中修改数组的元素值。我们要不想用户修改数组值,可以使用const关键字限制,如:int fun(const int arr[] , int len) ;这时我们就不能再函数中修改arr的值了。
用const限制参数时,并不是说参数只能传入常量值,变量值也能够传入,只不过在函数中作为常量来使用,不能够在函数中修改该值。如:
int testConst(const int ) ; int main(){ int x = 4 ; const int y = 9 ; testConst(x) ; //传入int testConst(y) ; //传入const int return 0 ; } int testConst(const int x ){ // x += 3 ; //error 这里不能修改x的值 read-only return x ; }
const和指针:有两种不同的方式将const用于指针。一种是让指针指向一个常量对象,既不能通过指针修改所指向对象的值;另一种是将指针声明为常量,既不能修改指针所指向的位置。
1:声明一个指向常量的指针pt:
int a = 34 ;
const int *pt = &a ; // 声明pt是指向const int ,既不能通过*pt来修改a的值 即*pt为const int
上面并不是说pt所指向的是常量值,可以通过a来修改值 但不能通过*pt来修改a的值,可以修改pt指向的位置 如:
int b = 45 ;
pt = &b ;
我们可以将const int 变量的地址赋给const int*指针,但不能将const int变量的地址赋给int*指针,因为若赋给int*指针,则可以通过指针来修改变量的值,就违反const的本意。如:
const double I = 3.1415926 ;
const double *Pi = &I ; //可以
double *p_i = &I ; //error
则在定义函数时,若我们在函数中不需要通过指针修改变量的值,则将形参定义为const ,这样我们既可以传递普通变量,也可以传递const常量。
2:声明指针常量pt:
int a = 4 ;
int * const pt = &a ;
我们可以通过*pt来修改a的值,但不能修改pt指向的地址,如:
int b = 5 ;
pt = &b ; //error
3:声明指向常量的指针常量pt :
double a =3.4 ;
const double * const pt = &a ; //我们既不能通过*pt修改a的值,也不能修改pt指向的地址。
函数指针:与数据相比,函数也有地址,就是存储机器语言代码的开始地址,我们可以将函数地址作为参数传递给另一个函数,则这样我们可以在另一个函数调用函数,在运行时,根据传入的不同函数地址来调用不同的函数。
1:获取函数的地址,函数名就是函数的地址,如果think()是一个函数,则think就是函数地址,要将函数作为参数传递,就必须使用函数名,我们要区别传递的是函数地址还是返回值。如:
process(think); //传递的是函数地址
thought(think()) ; //传递的是函数返回值
2:声明函数指针:声明指向函数的指针时,我们必须指定指向的函数类型。如:
int max(int x ,int y) ; //函数
int (*p_max)(int , int ) ; //p_max 就是函数指针 它指向返回值是int ,参数是两个int类型的函数。如:
#include<iostream> using namespace std ; int sum(int , int ) ; //函数声明 int max(int , int ) ; //函数声明 int process(int (*p_m)(int , int ) , int x , int y) ; //函数声明 int main(){ int (*p_m) (int , int ) ; //函数指针 p_m = sum ; process(p_m) ; //当p_m指向sum函数 调用sum函数 p_m = max ; process(p_m) ; //当p_m指向max函数, 调用max函数 return 0 ; } int sum(int x , int y) { cout << "sum method !!!" << endl ; return x + y ; } int max(int x ,int y ) { cout << "max method !!!" << endl ; return x > y ? x : y ; } int process(int (*p_m)(int , int ) , int x ,int y) { return p_m(x , y) ; }