C++10 --- 函数指针、相关试题

一、函数指针

1、相关定义

函数指针 static

指针

就是一个地址

使用

基类型(当前这个指针变量说指向的变量的类型) * 指针变量名

指针变量(指向存放地址的变量):

单指针 双指针 指针数组 数组指针 指针函数 函数指针

单指针 – 可以和一个 变量、一维数组、二位数组、函数 联系
双指针 – 可以和一个 变量 、指针数组 联系
字符指针 –

2、右左法则

认指针的法则 – 右左法则 --往右看一个,在往左看一个,在看右边,只有往复,直到将其看完。
将得到的逐个往前补充;

示例:

int (*p)[4] — 整型数组指针 – 指向数组的指针
先找这句话的标识符 - p,
先往右看,有小括号,先个*结合,说明p是个指针;
在往右看,是[ ,是个数组,所以为数组指针;
在往左看,是int,为整型,所以是整型数组指针。

int *q[4] — 指针数组 – 存储指针的数组
先找标志符,这里为q,没有(),就先往右看,为[,所以是q是一个数组;
在往左看一个,为*,所以为指针数组;
在往右看,看完了,往左看,为int,所以是整型指针数组;

int (*p1[5]) — 指针数组
和q一样,

int *(*p2[3])(int) **— 指针函数指针数组 – **
先找标志符,这里为p2,
先往右看,为[ ,为数组,所以为数组;
在往左看,为*,为指针,所以为指针数组;
再往右看,为( ,是函数,所以为函数指针数组;
再往坐看,为 * ,是指针,所以为指针函数指针数组;
再往右看,没了,往左看,为int,是整型,所以为整型指针函数指针数组。

int *p3(int n) — 指针函数 – 返回值为指针的函数
先找标志符,这里为p3,
先右看,为(,是函数,所以为函数;
再往左看,为*,是指针,所以是指针函数;
再往右看,没了,往左看,为int,是整型,所以是整型指针函数。

int (*p4)(int ,int ) — 函数指针 – 指向函数的指针
先找标志符,这里为p4,
先往右看,为),是小括号,先看括号内,为*,是指针,所以是指针;
再往右看,为,是函数,所以为指针函数;
再往左看,为int,是整型,所以为整型指针函数。

3、函数指针的用法

1)基础应用:函数名 – 代表函数的入口地址

int Sum(int a,int b)
{
	return a + b;
}
void main()
{
	int (*p)(int ,int );//p是一个指针,指向一类函数,函数有两个int型参数,返回值为int
	p = Sum;
	cout << Sum(4,7) << endl;
	cout << p(3,4) << endl;
}

运行结果:

在这里插入图片描述

对于int (*p)(int ,int );的看理解:p是一个指针,指向一类函数,函数有两个int型参数,返回值为int

2)指针指向函数,由指针调用函数

代码示例:

int max(int a,int b)
{
	return a > b ? a : b;
}
int min(int a,int b)
{
	return a < b ? a : b;
}
void test(int x,int y,int (*p)(int,int))
{
	cout << "test :" << p(x,y) << endl;//max(2,9)
}
void main()
{
	//函数指针作为另外一个函数的参数
	test(2,9,max);//将max传给p,相当于p = max
}

运行结果:

在这里插入图片描述

3)函数指针作为另外一个函数的参数

代码示例:

int min(int a,int b)
{
	return a < b ? a : b;
}
//函数指针作为另外一个函数的返回值
/*
函数指针函数 -- fn是个函数名,函数里面有int n的一个参数,fn函数的返回值是个指针,这个指针指向一类函数 - int xx(int,int)
*/
int (*fn(int n))(int ,int )//函数指针函数
{
	cout << "fn n = " << n << endl;
	return min; //返回值是个指向函数的指针,在此可以返回函数名
}
void main()
{
	cout << "函数指针作为函数返回值 " << endl;
	cout << fn(100)(3,20) << endl; //先调用fn函数,将100传递给参数n,fn函数返回min,再掉用min(3,20)

	//等价于
	//int (*p)(int ,int );
	//p = fn(100); //p = min
	//cout << p(3,20) <<endl;
}

运行结果:
在这里插入图片描述

4)函数指针作为另外一个函数的返回值

函数指针数组

int Sum(int a,int b)
{
	return a + b;
}
int max(int a,int b)
{
	return a > b ? a : b;
}
int min(int a,int b)
{
	return a < b ? a : b;
}
int Sub(int a,int b)
{
	return a - b;
}
int Mul(int a,int b)
{
	return a*b;
}
int Div(int a,int b)
{
	return a*b;
}
int Mod(int a,int b)
{
	return a%b;
}
//将同一类型的函数放一起 类似于函数数组 -- 函数指针
int main()
{
	int (*p[])(int,int) = {Sum,max,min,Sub,Div,Mul,Mod}; //函数指针数组
	int x = 10,y = 20;
	int n = sizeof(p)/sizeof(p[0]);
	for(int i = 0;i < n; i++)
	{
		cout << p[i](x,y) << endl;
	}
}

5)扩展 – 函数转移表 *** 最重要

整体测试代码

#if 0
int Sum(int a,int b)
{
	return a + b;
}
#if 1
int max(int a,int b)
{
	return a > b ? a : b;
}
int min(int a,int b)
{
	return a < b ? a : b;
}
void test(int x,int y,int (*p)(int,int))
{
	cout << "test :" << p(x,y) << endl;//max(2,9)
}
#endif

//3、函数指针作为另外一个函数的返回值
#if 0
/*
函数指针函数 -- fn是个函数名,函数里面有int n的一个参数,fn函数的返回值是个指针,这个指针指向一类函数 - int xx(int,int)
*/
int (*fn(int n))(int ,int )//函数指针函数
{
	cout << "fn n = " << endl;
	return min; //返回值是个指向函数的指针,在此可以返回函数名
}
#endif
#if 0
int Sub(int a,int b)
{
	return a - b;
}
int Mul(int a,int b)
{
	return a*b;
}
int Div(int a,int b)
{
	return a*b;
}
int Mod(int a,int b)
{
	return a%b;
}
#endif
//将同一类型的函数放一起 类似于函数数组 -- 函数指针
#if 0
int main()
{
	int (*p[])(int,int) = {Sum,max,min,Sub,Div,Mul,Mod}; //函数指针数组
	int x = 10,y = 20;
	int a = sizeif(p)/sizeof(p[0]);
	for(int i = 0;i < n; i++)
	{
		cout << p[i](x,y) << endl;
	}
}
#endif

#if 1
void main()
{
	//2、函数指针作为另外一个函数的参数
	test(2,9,max);//将max传给p,相当于p = max

	//3
	//cout << "函数指针作为函数返回值 " << endl;
	//cout << fn(100)(3,20) << endl; //先调用fn函数,将100传递给参数n,fn函数返回min,再掉用min(3,20)

	//p = fn(100);
	//cout << p(3,20) <<endl;
}

#endif
#endif

二、相关笔试题

1、指针和字符串的相关笔试题

代码

void main()
{
	char a[] = "123";
	char b[] = "123";
	const char c[] = "123";
	const char d[] = "123";
	const char* p1 = "123";
	const char* p2 = "123";
	const char* const p3 = "123";
	const char* const p4 = "123";

	//char* p5 = "123";//对于高级编译器不能通过,会报错 ,只是指向,不能改变

	if(a == b)
		cout << "a == b" << endl;
	if(a == c)
		cout << "a == c" << endl;
	if(c == d)
		cout << "c == d" << endl;
	if(p1 == p2)
		cout << "p1 == p2" << endl;
	if(p3 == p4)
		cout << "p3 == p4" << endl;
	if(p1 == p3)
		cout << "p1 == p3" << endl;
}

理解:

对于代码char a[] = "123";来说,其实是定义了一个数组a,给a数组开辟了4个字节的空间,给四个字节里存放了1 2 3 \0。
b数组同理。
a、b数组名代表的是数组的首元素的首地址。
在这里插入图片描述
所以两者不相同。

对于const char* p1 = "123";来说,p是个指针型变量,并没有开辟空间,p指向了一个字符串常量区的字符串常量,p里面存储的是其所指向的字符串常量的首地址,并没有开辟空间。只是指向,不能修改。
在这里插入图片描述
所以两者相同。

运行结果:

在这里插入图片描述

2、函数指针相关笔试题

1+2++3+…+n 要求,不能用if,不能用循环,不能用公式,不能直接输出结果

int f0(int n)
{
	return 0;
}
int f1(int n)
{
	
	static int (*pf[2])(int) = { f0,f1 }; //pf[0] = f0  fp[1] = f1
	
	return pf[!!n](n - 1) + n;
}
void main()
{
	cout << f1(100) << endl;
}

运行结果:

在这里插入图片描述

理解:

static int (*pf[2])(int) = { f0,f1 }; //pf[0] = f0  fp[1] = f1

定义了一个静态的函数指针数组,只在第一次调用的时候开辟空间,后面不会再开辟。
pf它是个数组,里面存的是指针,指针指向的返回值为int,里面有一个int类型的这类函数;相当于 pf[0]指向f0,pf[1]指向f1

	return pf[!!n](n - 1) + n;

其中!!n,如果其中的值为99,先取反为0,再取反为1.
在这里插入图片描述
程序运行的大体流程:

n = 100
return pf[!!100](99)+100->return pf[1](99)+100--->f1(99)+100
n = 99
return pf[!!99](98)+99   ---- f1(98)+99

n = 98
return pf[!!98](97)+98  -----f1(97)+98
......
n = 0
return pf[!!0](-1)+0  -----pf[0](-1)+0-----f0(-1)+0---0

3、二运算符重载相关试题:

class Magic
{
	double x;
public:
	Magic(double d = 0.00):x(fabs(d)){}
	Magic_____{return Magic(sqrt(x*x + c.x*c.x));}
	_____<<(ostream & os,Mgic c){return os<<c.x;}
};

void main()
{
	Magic ma;
	cout<<ma<<","<<Magic(-8)<<","<<ma+Magic(-3)+Magic(-4);
}

operator+(Magic c)
friend ostream& operator
代码:

#include <math.h>
class Magic
{
	double x;
public:
	Magic(double d = 0.00):x(fabs(d)){}
	Magic operator+(Magic c)//Magic(-3) 是一个无名对象,所以参数未Magic c
	{
		return Magic(sqrt(x*x + c.x*c.x));
	}
	friend ostream& operator<<(ostream & os,Magic c);
};

ostream& operator<<(ostream &os,Magic c)
{
	return os << c.x;
}

void main()
{
	Magic ma;
	cout << ma << ","<< Magic(-8) << "," << ma + Magic(-3) + Magic(-4);
}

运行结果:
在这里插入图片描述

4、桶排

n个1~10的数据,例如1 3 2 5 4 7 6 8 9 10 4 3 1 2 4 5 6 8 7 1 2 3 9 8 6
计算1~10出现的次数 — 票据的缺失 – 思想一样

void main()
{
	int num[] = { 1,2,4,3,2,5,6,7,8,9,10,9,8,6,7,8,9,1,2,3,4,5,6,7 };
	int n = sizeof(num) / sizeof(num[0]);
	int count[11] = { 0 };
	int i;
	for (i = 0; i < n; i++)
	{
		count[num[i]]++;
		/*
		if(num[i] == 1)
			count[1]++;
		*/
	}
	for (i = 1; i <= 10; i++)
		cout << i << " : " << count[i] << endl;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在C语言中,内部类函数指针即为指向内部类成员函数指针,而C函数指针则是指向普通的C函数指针。在C语言中,实际上并没有内部类的概念,只能通过结构体内的函数指针来模拟实现内部类的成员函数的调用。 为了将内部类函数指针转换为C函数指针,我们需要手动维护一个指向内部类实例的指针,并将其作为第一个参数传递给内部类函数。这样,我们可以通过将内部类实例的指针与内部类函数指针一起传递给C函数,来模拟内部类函数的调用。 下面是一个简单的示例代码,演示了如何将内部类函数指针转换为C函数指针: ```c #include <stdio.h> // 内部类的定义 typedef struct { int x; int y; void (*add)(int, int, void*); } InnerClass; // 内部类的成员函数 void add(int a, int b, void* instance) { InnerClass* innerInstance = (InnerClass*) instance; innerInstance->x += a; innerInstance->y += b; } // C函数,接收C函数指针作为参数 void callCFunction(void (*cFuncPtr)(int, int, void*), void* instance) { cFuncPtr(10, 20, instance); } int main() { InnerClass innerInstance; innerInstance.x = 0; innerInstance.y = 0; innerInstance.add = add; printf("Before call: x = %d, y = %d\n", innerInstance.x, innerInstance.y); // 将内部类函数指针转换为C函数指针进行调用 callCFunction(innerInstance.add, &innerInstance); printf("After call: x = %d, y = %d\n", innerInstance.x, innerInstance.y); return 0; } ``` 在上述示例中,我们定义了一个名为`InnerClass`的内部类,其中包含了整型的成员变量`x`和`y`,以及一个函数指针`add`。`add`函数用于将传入的两个参数与内部类的成员变量相加。 然后,我们定义了一个名为`callCFunction`的C函数,其中接收一个C函数指针和一个内部类实例的指针作为参数。在该函数中,我们通过调用传入的C函数指针来调用内部类函数,将`10`和`20`作为参数传递给内部类函数。 在`main`函数中,我们创建了一个`InnerClass`的实例`innerInstance`,并将其成员变量`x`和`y`初始化为`0`。接着,我们调用了`callCFunction`函数,将内部类函数指针`innerInstance.add`和`&innerInstance`作为参数传递给它。 最后,我们在控制台上输出了内部类函数调用前后的`x`和`y`的值,可以看到内部类函数的调用对内部类实例的成员变量进行了修改。这就说明我们成功将内部类函数指针转换为C函数指针,并通过C函数的调用来模拟了对内部类函数的调用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值