C++基础入门教程(八):函数指针
最近事情比较多,其实并不忙,就是事情比较影响思绪,所以都没心思写文章了。
今天主要说说函数的一些基本情况吧,同时也解释一下新手最容易迷糊的——什么时候要用指针参数?
一、函数原型和函数定义
大家都知道,C++定义函数之前,还需要声明函数原型,对于习惯Java等其他高级语言的朋友来说,真心觉得这很烦人。
如下代码:
// 声明函数原型
void startGame(int param);
// 函数定义
void startGame(int param)
{
// 各种逻辑
}
函数原型主要是给编译器用的,在编译的时候会通过函数原型来检查函数返回值、参数数量、参数类型等。
总而言之,方便编译器,编译器爽了,我们才能更爽。
但实际中,函数原型也方便我们快速理解某个类的功能。
这些很简单,就不多唠叨了。
二、const限定符与指针
之前也有简单介绍过const,比如 const int num = 10; 那么num就是常量,不可再次进行赋值操作了。
如果把const用在指针上呢?
int num = 10;
const int *p = #
// 编译会报错
*p = 100;
如上代码,编译的时候就会报错,因为指针p指向一个const int类型,这是一个常量。
所以*p的值是一个常量,不能被修改。
再来理一理,不然等会会混乱的:
1.p是一个指针
2.p指向一个内存地址,这个地址里存放的是一个const int类型的值
3.*p代表是p指向的内存地址里存放的那个值
4.所以,*p就是一个const int类型的值
5.综上所述,*p不能再次被赋值。
这里要区分p和*p,这是两个概念,一个是指针,一个是指针指向的值。
p是可以被再次赋值的,但是*p是不能被赋值的。
三、函数的指针参数
先来看看下面的代码:
void notChangeNum(int num);
void changeNum(int* num);
int _tmain(int argc, _TCHAR* argv[])
{
int num = 10;
// 这个函数不会改变num的值
notChangeNum(num);
cout << num << endl;
// 这个函数会改变num的值
int* p = #
changeNum(p);
cout << num << endl;
return 0;
}
void notChangeNum(int num)
{
// 参数不是指针
num = 999;
}
void changeNum(int* num)
{
// 参数是指针
*num = 999;
}
这里有两个函数,一个是普通参数(值传递),一个是指针参数(地址传递)。
第一个notChangeNum函数是不会改变num的值的,因为num传递给函数时,是拷贝了一份新的值,原来的num是不受影响的。
当离开notChangeNum函数后,函数的num参数会被释放。
第二个changeNum函数的参数是指针,我们都知道,指针是指向某个内存地址的,所以,函数的参数指向的内存地址就是num的内存地址。
直接修改内存地址上的值,会影响原来的num,所以,离开changeNum函数后,num的值也会被改变,最终值是999.
这就是指针参数的作用,某些情况下,我们希望函数里对参数的修改能够真正产生影响。
四、为什么要使用指针参数
为什么要用指针作为参数呢?因为指针可以直接指向内存地址,可以直接在函数里修改值,并且离开函数后仍然生效。
说是这么说,但,肯定还有人会迷糊,为什么呢?为什么要这样呢?
比如,我们的函数参数是某个类:
void play(Sprite* sp) {
}