指针函数、函数指针(指针数组、数组指针)傻傻分不清?

初探:

  对于初学指针的小伙伴来说提起指针就已经够头疼的了,那如果在代码中遇到指针函数、函数指针、指针数组、数组指针....指针家族都一块来了,更是连看下去的勇气都没有了,不要急,c语言灵活的地方就在指针上面,指针是c语言的灵魂,这篇文先让你了解一下概念,分清这几种指针家族的本质,在实际过程中多用才能有更深的体会。

  首先实体是什么先要分清楚,在前两个字与后两个字的中间加上一个 ‘的’ 会好很多。

指针函数不就是有指针的函数,实体是函数,这个函数的返回值类型是指针

函数指针不就是拥有函数的指针,实体是指针,这个指针拥有函数,也就是这个指针指向函数

指针数组不就是有指针的数组,实体是数组,这个数组里面装着指针

数组指针不就是拥有数组的指针,实体是指针,这个指针指向数组

  这样一分析后,是不是就清晰很多?下面让我们做一下具体分析

指针函数:

  函数体内该怎么写还是怎么去写,只不过最后返回的是一个指针类型。这面这个例子是计算a+b的值,返回一个指针类型。下面这个代码有坑!

int *sum(int a, int b)
{
	int c;
	/*int *p;
	p = &c;*/
	c = a + b;
	return &c;
}
int main()
{
	int *p;
	int a, b;
	a = 3; b = 2;
	p = sum(a, b);
	//cout << endl;
	cout << a << " + " << b << " = " << *p << endl;
}

    我先面说这个代码有坑,但是运行后发现没有问题啊,输出很正常,但如果延时一下,把那个main函数中的注释去掉,就会出问题了,有的编译器会出现一行警告:warning C4172: 返回局部变量或临时变量的地址,原因何在呢?就是因为我们在函数中定义的c是一个临时变量,存放在栈区,这个子函数一结束就会被释放掉,没有延时的直接输出出现正确情况可能只是一种巧合,那一块区域还没被释放掉,但你过一会再去访问就会出错。避免这种错误出现的方法是,只需让c这个变量在子函数运行后不被释放掉就可以了,用静态变量static就可以。下面是正确的代码

int *sum(int a, int b)
{
	static int c;
	/*int *p;
	p = &c;*/
	c = a + b;
	return &c;
}

函数指针:

  一般形式: 返回值类型  (*指针名)(参数);  如果我们用函数指针不得不考虑函数重载的问题

重载

int sum(int a, int b)
{
	int c;
	/*int *p;
	p = &c;*/
	c = a + b;
	return c;
}
void sum()
{
	cout << "sum的重载" << endl;
}
int main()
{
	int (*p)(int,int);  //下面这两种格式也可以
	//int(*p)();        //有重载的情况不适合用这种形式    
	//int(*p)(int a, int b);
	int a, b,c;
	a = 3; b = 2;
	p = sum;
	c = p(a,b);  //下面这种格式也可以
	//c = (*p)(a, b);
	cout << a << " + " << b << " = " << c << endl;

	//重载
	void (*pf)();
	pf = sum;
	pf();
}

回调:

  把一个函数的指针作为参数传递到另一个函数的参数中

int sum(int a, int b)
{
	int c;
	/*int *p;
	p = &c;*/
	c = a + b;
	return c;
}
void function(int(*p)(int, int))
{
	int a, b, c;
	a = 3; b = 2;
	cout << "这是在function中调用其他函数" << endl;
	c = p(a, b);
	cout << a << " + " << b << " = " << c << endl;
}
int main()
{
	function(sum);
}

typedef:

  如果程序中有比较多的函数指针,那么没定义一个变量就要写一遍这个类型,不仅麻烦还容易出错,所以用typedef为他定义一个简短的名字就很有必要。

typedef int(*PFON)(int, int);
int sum(int a, int b)
{
	int c;
	/*int *p;
	p = &c;*/
	c = a + b;
	return c;
}
int main()
{
	int a, b,c;
	a = 3; b = 2;
	PFON pfon;
	pfon = sum;
	c = pfon(a, b);  
	cout << a << " + " << b << " = " << c << endl;
}

指针数组:

  首先,与要明确这几个符号的优先级问题:()= [] > * ,优先级相同从左到右,根据这个优先级关系推出 int * parray[4] 是一个指针数组

int *sum(int a, int b)
{
	static int c;
	/*int *p;
	p = &c;*/
	c = a + b;
	return &c;
}
int main()
{
	int * parray[3];
	int a=2, b=3;
	parray[0] = &a;
	parray[1] = &b;
	parray[2] = sum(*parray[0], *parray[1]);  //此函数返回的直接是指针类型
	cout << *parray[0] << " + " << *parray[1] << " = " << *parray[2] << endl;
}

数组指针:

  首先我们要知道指向数组的指针与指向数组首元素的指针是两码事!!!

int main()
{
	int array[3] = { 1, 2, 3 };
	int *p1 = array;   //指向数组的指针
	int (*p2)[3];
	p2 = &array;       //指向数组首地址的指针,需要二次解引用
	for (int i = 0; i < 3; i++)
	{
		cout << *(*p2+i) << " ";    //*p2相当于array    
	}
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

small_planet

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值