C/C++基础----指针(4)

函数指针和指针函数

1.1 函数指针

  函数指针是一个指针,这个指针指向的是一个函数,在之后调用函数的时候,可以通过指针的方式来调用这个函数。为了使函数指针能够指向一个特定的函数,函数指针的声明需要于函数具有类似的结构。

#include <stdio.h>
//声明一个函数
void test(int x)
{
	printf("%d\n", x);
}

int main(int argc, char const *argv[])
{
	//声明一个函数指针
	void (*p)(int );
	//给函数指针赋值
	p = test;
	//通过指针来调用函数
	(*p)(2);	
	return 0;
}

  上面这段代码比较简单,首先声明了一个函数,该函数的作用就是将输入到该函数的参数进行打印。在main函数中,定义了一个函数指针。这里需要注意函数指针的定义方式,这个函数指针的方式有点像前面定义二维数组的指针。需要指定该函数的参数列表才能确定这个指针所指向的位置。对函数指针解引用的结果是该函数的地址。

1.2 函数指针的作用

  函数指针可以指向一个函数,若是有多个函数需要保存,可以使用一个函数指针数组来将多个同一类型的函数进行保存,有点类似于回调的作用。举个例子就像一个群,群里保存了各个人的联系方式,管理员可以通过这个群直接联系每个人,让被调用的人完成任务。

#include <stdio.h>

void test(int x)
{
	printf("%d\n", x);
}

void test_a(int x)
{
	printf("%d\n", x);
}

int main(int argc, char const *argv[])
{
	void (*p[2])(int );
	p[0] = test;
	p[1] = test_a;
	p[0](2);
	p[1](3);	
	return 0;
}

2.1 指针函数

  指针函数是一个函数,这个函数的返回值是一个指针。

int * test(int * p)
{
	return p;
}

  使用指针函数时,要注意可能会出现野指针的情况。下面这段代码就是一个野指针的实例。

#include<stdio.h>

int * test()
{
	int *r = NULL;
	int x = 10;
	printf("x is %d \n", x);
	r = &x;
	return r;
}

int main(int argc, char const *argv[])
{
	int * p;
	p = test();
	*p = 2;
	printf("*p is %d\n",*p);
	test();
	printf("*p is %d\n", *p);
	return 0;
}

在这里插入图片描述
  从输出结果可以来分析一下这段代码中存在的问题。在主函数中定义一个指针,最开始调用test()函数,函数返回了局部变量x的地址,p保存了这个地址,然后p通过解引用将这个地址中的内容更改为2。然后再次调用test(),可以发现p所指向的内存的数据发生了变化。而这时候我们并没有对指针p做任何操作。从这里可以看到指针p就是一个野指针。
  出现这种结果的情况是,函数内部的变量x是局部变量,函数调用完毕后自动释放掉了,但是依然返回了一个地址,返回的地址却被释放掉了,这时候main函数中的指针p所指向的内容就不归它所有了。
  将函数内部的x声明成静态,可以使返回的地址不被释放。

#include<stdio.h>

int * test()
{
	int *r = NULL;
	static int x = 10;
	printf("x is %d \n", x);
	r = &x;
	return r;
}

int main(int argc, char const *argv[])
{
	int * p;
	p = test();
	*p = 2;
	printf("*p is %d\n",*p);
	test();
	printf("*p is %d\n", *p);
	return 0;
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值