C++函数学习笔记
1.函数参数传递问题
1.1传值参数
主要两种:1.初始值拷贝到变量,改变变量不会影响初始值;2.指针形参(指针引用),传递对象地址,可以通过指针来该改变所指对象的值。
1.2传引用参数
#include<iostream>
using namespace std;
void change1(int& a); void change2(int a); void change3(int* p);
int main()
{
int a = 5, b = 15;
change1(a);
cout << a << endl;
change2(a);
cout << a << endl;
change3(&a);
cout << a << endl;
return 0;
}
void change1(int& a)
{
a = 15;
}
void change2(int a)
{
a = 25;
}
void change3(int* p)
{
(*p)++;
}
结果:15 15 16
1.3参数类型补充:
1.3.1传递 const 形参和实参;
//对于const:
void fcn(const int i); void fcn(int *const i); void fcn(int const*i);
//传递的i可以不是常量,但fcn在调用i时,不好再修改i的值,这里涉及到初始化规则
//对于顶层const,fcn函数在调用时,都无法修改这个值。
int main()
{
//const
const int c=8;
//c = b;//左值不允许被修改
int b = 2 * c;//const可以初始化常量
fcn(b);
//int *const pb = &b;//可以获取常量指针
fcn(&b);//常量指针所指对象是可以改变的
cout<< b<<endl;
fcn(&b);
}
void fcn(const int i)
{
//i = 3;左值不允许修改
cout << i << endl;
}
void fcn(int *const i)
{
*i += 5;
//int as =2 ;
//i = &as;//常量指针本身不能被修改,
cout << i << endl;
}
void fcn(int const*i)
{
//*i = 4;左值不允许修改,
cout << i << endl;
int as =2 ;
i = &as;//指针本身可以修改,但其指向的常量不能修改
cout << i << endl;
}
结果:
00CFFB7C
21
00CFFB7C
00CFFA94
附:形参初始化规则与变量初始化规则相似:对于const对象,可以使用非常量来初始化常量,反之则不行(会报错)
1.3.1传递数组形参;
数组特性:不允许拷贝与赋值
因此,在函数引用时,不能直接传递数组的值,可以通过传递地址来实现数组传递;
//数组
char ss[5] = { 'h','e','l','l','o' };
printfs(ss);
void printfs(char *a)
{
for (int i = 0; i < 5; ++i)
{
printf("%c",*(a+i));
}
}
也可以使用数组引用形参
void printfs(char(&a)[5])//此处[5]限制了引用数组的大小
{
for (int i = 0; i < 5; ++i)
{
printf("%c", *(a + i));
}
}
对于多维数组传递,其实就是数组中的数组,直接上代码
int pp[3][3] = {
{1,2,3},{4,5,6},{7,8,9}
};
printfs(pp);
/函数
void printfs(int(*p)[3])
{
for (int j = 0; j < 3; ++j)
{
cout<< endl;
for (int i = 0; i < 3; ++i)
{
cout << " " << *(*(p + j) + i);//注意这个p是指向 这个二维数组的第一个数组的首地址的 指针。
}
}
}
结果:
1 2 3
4 5 6
7 8 9
2.函数重载问题
函数重载的定义(copy的c++primer):同一作用域内的几个函数名字相同但形参列表不同。
重载函数特点:函数名字相同,但传递的形参数量、类型有不同。(在第一部分参数传递的代码示例中,都是重载函数),注意返回值不同不能作为重载依据!
重载与作用域问题:
因为在C++中,函数调用时,先查找函数名字,再进行类型检查,所以当编译器查找一个函数时,在局部作用域就找到同名的函数声明,就会忽略外层的同名函数体,这会导致程序可能出现错误;
int numberget(int a);
int main()
{
int num = 10;
int numberget(double);//在内部声明后,该局部作用域就会忽略外部
nb(num);
int get = numberget(a);
cout << get;
return 0;
}
int numberget(int a)
{
return 10*a;
}
int nb(int a)
{
int get=numberget(a);
cout << get;
return 0;
}
int numberget(double a)
{
return a / 10;
}
结果:100
1
根据结果看到。在main中调用,只能用double(这里调用时,参数会自动转换)(结果:1),而nb()函数调用的是外部的定义函数(结果:100)
对于该问题,避免的最好方式:重载函数声明尽量不要放在局部作用域
3.函数指针问题
先来弄明白函数指针和指针函数的区别:
指针函数:返回值是指针类型的函数(本质上是函数)
int* rp(int a,int b);
函数指针:指向函数的一个指针变量(这个可以联想到常量指针,指向常量的一个指针)
int (*rp)(int a,int b);
函数指针的使用:
int dfs(vector<int>a,int size)
int(*copy) = &dfs;//指针获取dfs函数的地址,和下面那个没区别
int(*copy) = dfs;//指针指向dfs,&在为可选项
//使用
int ans=(*copy)(a,b);
int ans1=dfs(a,b);//这两者是等价的
函数指针的重载
int fcn(int a);
int fcn(double a);
int fcn(char a);
int (*copy)(int)=fcn;//调用有重载函数时,必须指定好函数指针类型
void (*copy1)(char a)=fcn//返回值不同,会报错
函数指针作为形参使用
void bfs(int depth,vector<int>index,int find(int a,int b));//这里的函数在被作为形参调用后,会转换为函数指针。
void bfs(int depth,vector<int>index,int (*find)(int a,int b));//与上面效果相同
须指定好函数指针类型
void (*copy1)(char a)=fcn//返回值不同,会报错
函数指针作为形参使用
```C++
void bfs(int depth,vector<int>index,int find(int a,int b));//这里的函数在被作为形参调用后,会转换为函数指针。
void bfs(int depth,vector<int>index,int (*find)(int a,int b));//与上面效果相同