一、指针变量作为函数的参数
如果想在函数内部修改外部变量的值,需要将外部变量的地址传递给函数。
1.1、单向传递:值传递
函数内部不能修改外部变量的值。
#include <iostream>
using namespace std;
void set(int num2)// 相当于 int num2=num;
{
num2=10;
}
int main()
{
int num=1;
set(num);
cout<<"num = "<<num<<endl;
return 0;
}
输出:
num = 1
1.2、单向传递:传地址
函数内部可以修改外部变量的值。
#include <iostream>
using namespace std;
void set(int *p)// 相当于 int *p=#
{
*p=10;
}
int main()
{
int num=1;
set(num);
cout<<"num = "<<num<<endl;
return 0;
}
输出:
num = 10
二、数组作为函数的参数传递
函数内部想操作外部数组元素,将数组名传递给函数。
• 一维数组作为函数的参数,会被编译器优化为指针变量。
• 二维数组作为函数的形参会被优化成一维数组指针。
(1)一维数组作为函数的参数传递:
#include <iostream>
using namespace std;
void foreach(int p[5])//优化成void foreach(int *arr)
{
cout<<"sizeof(p) = "<<sizeof(p)<<endl;
//遍历
for(int i=0;i<5;i++)
{
cout<<p[i]<<" ";
}
cout<<endl;
}
int main()
{
int num[5]={1,2,3,4,5};
cout<<"sizeof(num) = "<<sizeof(num)<<endl;
foreach(num);
return 0;
}
输出:
sizeof(num) = 20
sizeof(p) = 4
1 2 3 4 5
(2)二维数组作为函数的参数传递:
#include <iostream>
using namespace std;
// void foreach(int (*p)[4],int row,int col)和下面的等价
void foreach(int p[3][4],int row,int col)
{
cout<<"sizeof(p) = "<<sizeof(p)<<endl;
//遍历
for(int i=0;i<col;i++)
{
for(int j=0;j<col;j++)
cout<<p[i][j]<<" ";
cout<<endl;
}
cout<<endl;
}
int main()
{
int num[3][4]={
{1,2,3,4},
{5,6,7,8},
{9,10,11,12}
};
cout<<"sizeof(num) = "<<sizeof(num)<<endl;
foreach(num,sizeof(num)/sizeof(num[0]),sizeof(num[0])/sizeof(num[0][0]));
return 0;
}
输出:
sizeof(num) = 48
sizeof(p) = 4
1 2 3 4
5 6 7 8
9 10 11 12
三、函数的返回值类型是指针类型
将函数内部的合法地址通过返回值返回给函数外部使用。
注意:函数不要返回普通局部变量的地址,返回普通局部变量的地址会出现段错误,使用一个已经释放的内存空间的行为是未定义的。但是,可以返回静态变量的地址,因为静态变量的生命周期是整个进程,所以是一个合法的地址。
#include <iostream>
using namespace std;
int* test()
{
// int data=1;
// return &data;
static data=2;
return &data;
}
int main()
{
int *p=test();
cout<<"test return "<<*p<<endl;// 输出2
return 0;
}
四、函数指针
4.1、函数指针的定义
函数名代表函数的入口地址。函数指针本质上是一个指针变量,只是该变量保存的是函数的入口地址。
#include <iostream>
using namespace std;
int add(int x, int y)
{
return x+y;
}
int main()
{
// 函数指针
int (*p)(int,int)=NULL;
cout<<"sizeof(p) = "<<sizeof(p)<<endl;// 输出4
// 函数指针与函数入口建立关系
p=add;
// 通过函数指针调用函数
cout<<p(1,2)<<endl;//输出3
return 0;
}
4.2、函数指针变量的注意事项
1 函数指针变量不要加1操作,没有意义。
2 不要对函数指针变量取*,没有意义,编译器会自动优化。
3 函数指针变量判断大小也没有意义。
4 函数指针变量可以赋值,比如:p1=p2。
5 函数指针变量可以判断相等,比如:p1==p2。
4.3、函数指针变量使用typedef定义别名
#include <iostream>
using namespace std;
int add(int x, int y)
{
return x+y;
}
typedef int (*FUNC_NAME)(int,int);
int main()
{
// 函数指针
FUNC_NAME p =NULL;
cout<<"sizeof(p) = "<<sizeof(p)<<endl;// 输出4
// 函数指针与函数入口建立关系
p=add;
// 通过函数指针调用函数
cout<<p(1,2)<<endl;//输出3
return 0;
}
4.4、函数指针作为函数的参数
目的:让算法功能多样化,更加强大。
#include <iostream>
using namespace std;
int add(int x, int y)
{
return x+y;
}
int sub(int x, int y)
{
return x-y;
}
int mul(int x, int y)
{
return x*y;
}
int div(int x, int y)
{
return x/y;
}
int myCalc(int x,int y,int (*func)(int,int))
{
return func(x,y);
}
int main()
{
cout<<myCalc(20,30,add)<<endl;
cout<<myCalc(20,30,sub)<<endl;
cout<<myCalc(20,30,mul)<<endl;
cout<<myCalc(20,30,div)<<endl;
return 0;
}
五、总结
C++中指针和函数有着紧密的联系,指针可以用来存储函数的地址,通过指针调用函数或者将函数作为参数传递给其他函数。