函数指针 & 指针函数 学习笔记

犹记大一时期,搞ACM的小哥告诉我,其实学C++很简单,搞清了指针的东西,C++就入门了。的确,指针在C++中发挥着重要的作用,这几天项目需要,使用C++,故重温指针相关知识,笔记如下:

1.函数指针

  函数指针本身是一个指针,其指向的是函数。

函数指针的格式如下,通用格式就不说了,直接上例子:

int (*f) (int ,int){}

在上面的例子中,*f 由于有括号的原因,因此成为一个指针f,这里使用的是C++的优先级来判断的。指针 f 指向一个函数,上例中函数接收两个int型的参数,函数名前面的int表示函数返回值。因此,可以解释为定义了一个指针f,它指向一个有两个int类型参数的返回int类型数据的函数。

相信仔细看过指针相关知识的都知道,对于一个数组来说,数组名就是指向数组第一个元素的常量指针,例如有int型数组A,那么访问A[0]也可以使用*A,那么访问A[3]也可以使用*(A+3)。同理,对于一个函数来说,函数名也是指向函数第一条指令的常量指针。对于函数来说,编译器要做的就是在程序编译以后,为每个函数分配一个首地址,即函数第一条指令的地址,所以可以使用指针保存这个首地址,那么就可以找到这个函数,而保存这个首地址的指针就是函数指针。对于数组A来说,如果将A看做是指针的话,那么A中存的地址就是数组A的第0个单元的地址即首地址;那么对函数来说也一样,对于一个函数如:int M(int a,int b){}  ,那么可以使用函数名M来访问函数的首地址,这样,对于函数指针也就简单多了,对于上述的例子来说:函数指针是f,普通函数M,可以这样赋值:

f = M;

实例如下:

#include <iostream>
using namespace std;

int getAdd(int a, int b)
{
	return a + b;
}

int getSub(int a, int b)
{
	return a - b;
}

int(*f) (int, int);  //定义函数指针

int main()
{
	f = getAdd;  //让函数指针f指向函数getAdd,即将getAdd的函数首地址赋给指针f
	int add = (*f)(1, 2);  //使用函数指针调用函数
	cout << "两者之和是:" << add << endl;

	f = getSub;
	int sub = (*f)(1, 2);
	cout << "两者之差是:" << sub << endl;

	return 0;

}

运行结果如下:

两者之和是:3
两者之差是:-1
请按任意键继续. . .

使用函数指针需要注意的是:在给函数指针赋值时,函数和函数指针的返回值,参数个数和参数类型应该是一致的,否则会报错,如上例中,函数指针f的参数是两个int型,返回值也是int型,那么我们赋给f的函数getAdd和getSub的参数也是两个int型,且返回值也是int型。另外注意赋值,只是使用的函数名,没有带参数。


2.指针函数

  指针函数本身是一个函数,其返回值是某个类型的指针,也就是说指针函数是一个返回地址值的函数。指针函数必须赋给指针变量。

指针函数格式如下,通用格式就不说了,直接上例子:

int  *f (int a, int b) {}        

在上面的例子中,f是指针函数的函数名,f前的 int * 表示其返回值是int 类型的指针,也就是返回一个地址,这个地址指向的内容的类型为int型。括号中的a和b是函数的参数。

实例如下:

#include <iostream>
using namespace std;

int *f(int a, int b);

int main()
{
	int *p1 = nullptr;
	cout << "p1中的地址是:" << p1 << endl;

	p1 = f(1, 2);  //调用指针函数
	cout << "p1中的地址是:" << p1 << endl;
	cout << "*p1=" << *p1 << endl;

	return 0;
}

int *f(int a, int b)
{
	int n = a + b;
	int *p = (int *)malloc(sizeof(int));  //使用指针时要进行内存的申请和分配,否则不能为指针赋值
	memset(p, 0, sizeof(int));
	*p = n;

	cout << "n=" << n << endl;
	cout << "*p=" << *p << endl;
	cout << "p中存的地址是:" << p << endl;

	return p;
}


上面的例子的运行结果如下:

p1中的地址是:00000000
n=3
*p=3
p中存的地址是:00B0AD30
p1中的地址是:00B0AD30
*p1=3
请按任意键继续. . .

 指针函数的函数 从上面的结果可以看到,p和p1的地址是相同的,那么可以看出指针函数返回的确实是地址。 



    以上就是函数指针和指针函数比较基础的知识,可能难理解,但真正看下来收货会很多。此外,推荐几篇比较好的博文,写的很详细:

http://www.cnblogs.com/uniqueliu/archive/2011/07/27/2118619.html

http://blog.csdn.net/ameyume/article/details/8220832


本人经验,仅供参考!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
sigprocmask()函数是一个用于设置和修改进程信号屏蔽字的系统调用。它可以在进程内部控制信号的传递。在Linux系统中,sigprocmask()函数的原型如下: ```c int sigprocmask(int how, const sigset_t *set, sigset_t *oldset); ``` 其中,参数how用于指定信号屏蔽的方式,可以取以下三个值: - SIG_BLOCK: 将信号集set中的信号添加到当前进程的信号屏蔽字中。 - SIG_UNBLOCK: 将信号集set中的信号从当前进程的信号屏蔽字中移除。 - SIG_SETMASK: 将当前进程的信号屏蔽字设置为信号集set。 参数set是一个指向信号集的指针,用于指定需要屏蔽的信号集。参数oldset是一个指向信号集的指针,用于保存调用之前的信号屏蔽字。 下面是一个简单的示例,展示了如何使用sigprocmask()函数屏蔽SIGINT信号: ```c #include <stdio.h> #include <signal.h> int main() { sigset_t set, oldset; sigemptyset(&set); sigaddset(&set, SIGINT); sigprocmask(SIG_BLOCK, &set, &oldset); printf("SIGINT signal is now blocked\n"); sleep(10); sigprocmask(SIG_SETMASK, &oldset, NULL); printf("SIGINT signal is now unblocked\n"); return 0; } ``` 在上面的示例中,首先创建了一个信号集set,并将其中的SIGINT信号添加到其中。然后使用sigprocmask()函数将这个信号集添加到当前进程的信号屏蔽字中,从而屏蔽了SIGINT信号。程序会打印一条消息,表示SIGINT信号已被屏蔽,然后等待10秒钟。在等待期间,如果按下Ctrl+C组合键发送SIGINT信号,程序不会响应该信号。10秒钟后,程序再次调用sigprocmask()函数,将之前保存的旧信号屏蔽字恢复,从而取消了对SIGINT信号的屏蔽。 需要注意的是,sigprocmask()函数对信号处理的影响是进程级别的,而不是线程级别的。因此,在多线程程序中,对信号屏蔽的处理需要特别小心,以避免出现意外的情况。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值