1、整型指针

typedef int* PINT;

typedef int *PINT;

2、结构体

typedef struct {
  double data;
}DATA,  *PDATA;  //DATA是结构体类型别名,PDATA是结构体指针类型的别名

3、函数指针

#include<iostream>
using namespace std; void say()
{
cout << "hello world" << endl;
} int main()
{
void (*p)() = &say; //声明函数指针局部变量并初始化
(*p)();//或p();
return ;
}

函数名类似数组名。
  int a[100];定义了数组变量a,a是int [100]类型,是个数组类型。但int *p = a;竟可以把变量a直接赋给int*型变量p,但两者类型是不一样的。这是因为其中包含隐式的转换,a转换为了指向数组地址的指针常量,即int* const类型 。不含隐式转换的写法应该这样:int *p = &a[0];

  而函数void say();声明了函数say,say是void (void)类型,是个函数类型。上例的函数指针p可以 p=&say或p=say赋值。p=say时,say隐式转换为了指向函数地址的函数指针常量,即void say(* const)()类型。调用时也可进行反向转换,所以p();或(*p)();都可以调用函数!

可用typedf声明函数指针类型

typedef void (*)() S; //error,格式不正确
typedef void (*S)(); //ok!

举例:

#include<iostream>
using namespace std; void say1()
{
cout << "say1" << endl;
} void say2()
{
cout << "say2" << endl;
} int main()
{
typedef void (*SAY)(); //声明局部类型
SAY s;
s = say1;
s(); //或 (*s)();
(s = say2)(); //直接调用
return ;
}

这里是在main函数里声明的局部类型。当然,也可放在全局或类作用域中

C++11:也可以用std::function 。类模版 std::function是一种通用、多态的函数封装。std::function的实例可以对任何可以调用的目标进行存储、复制、和调用操作,这些目标包括函数、lambda表达式、绑定表达式、以及其它函数对象等。需#include <functional>

//接上例
#include <functional>
int main()
{
std::function<void ()> sf;
sf = &say1;
sf();
sf = &say2;//也可以sf = say2
sf();
return ;
}

4、函数指针数组

  先说一下,[]的优先级很高的,和()  .  ->这3个同处于最高优先级

void ((*p)[])();//编译出错:'p' 数组元素类型不能是函数
void (*p[])() = {say1, say2}; //ok;
p[]();
(*p[])();

上面,p是一个数组,含两个元素,元素类型是函数指针void (*)()  。

//不建议
typedef void (*S[])();
cout << sizeof(S) << endl;//
S a = {say1, say2}; //建议,更易懂
typedef void (*S)();
S a[] = {say1, say2};

4、返回值、形参含函数指针

int (*S)(int i, void (*p)()); //声明一个函数指针S,指向一函数。该函数返回值类型为int,有两个参数:int变量i和函数指针p。

int* (*r)() (*S[2])(void (*p1)(), int& (*p2[3])(int*, int*));//声明一数组,然而会编译错误,这种写法是不对的。

上面太复杂,编译器无法正常处理,你甚至可以编写更复杂的声明。用typedef可简化声明:

typedef int* (*RTN)();// 是一个函数指针
typedef void (*P1)();//参数1:也是函数指针
typedef int& (*P2)(int*, int*); // 参数2 typedef RTN (*S)(P1, P2[]);
S a[];//声明

若想定义一个函数指针pFoo,该指针所指向的函数也返回一个函数指针(类型是int (*)() )。

那么你不应该这么写 int (*)() (*pFoo)();

也不应该这么写 int (*pFoo)()(); ,不能按值直接返回函数int (void)

而应该这么写

int (*(*pFoo)())();

不同于 Linux中的signal函数原型就是: void (*signal(int, void(*)(int)))(int); ,signal是一个函数,而pFoo是一个指针。。注意两者括号包含区别~

5、成员函数指针

class Base
{
public:
  int m_a;
  void foo(){}
  static void sfoo(){} //注意:static修饰的是函数,不是返回值
}

int (Base::*pa) = &Base::m_a;
void (Base::*f1)() = &Base::foo; //注意,*在::后面
void (*f2)() = &Base::sfoo(); //注意static成员的指针不需指定作用域,可以向普通函数那样调用
std::function<>

#include <iostream>
using namespace std; class AA
{
public:
int m_a = ;
void f1()
{
cout << "AA::f1()" << endl;
}
void f2()
{
cout << "AA::f2()" << endl;
}
}; void main(void)
{
AA aa; int (AA::*pa) = &AA::m_a;
cout << aa.*pa << endl;// void (AA::*f)() = NULL;
f = &AA::f1;
(aa.*f)();//AA::f1()
f = &AA::f2;
(aa.*f)();//AA::f2()
}

std::function需用到std::bind  ---VS2013一直编译出错, sigh~

#include <functional>
class T
{
public:
void foo(int a){cout << "a: " << a << endl;}
}; int main()
{
T t; //方法1
std::function<void (int)> sf = std::bind(&T::foo, &t, 5);
sf();
//方法2:
std::function<void (const &, int)> sf2 = std::bind(&T::foo);
sf2(t, );
return ;
}

用typedef化繁为简,声明时可大大简化代码,且更易读!

typedef 函数指针 数组 std::function的更多相关文章

  1. C 中typedef 函数指针的使用

    类型定义的语法可以归结为一句话:只要在变量定义前面加上typedef,就成了类型定义.这儿的原本应该是变量的东西,就成为了类型. int integer;     //整型变量int *pointer ...

  2. C中typedef 函数指针的使用

    类型定义的语法可以归结为一句话:只要在变量定义前面加上typedef,就成了类型定义.这儿的原本应该是变量的东西,就成为了类型. int integer;     //整型变量int *pointer ...

  3. C++基础——函数指针 函数指针数组

    ==================================声明================================== 本文版权归作者所有. 本文原创,转载必须在正文中显要地注明 ...

  4. C/C++ 不带参数的回调函数 与 带参数的回调函数 函数指针数组 例子

    先来不带参数的回调函数例子 #include <iostream> #include <windows.h> void printFunc() { std::cout<& ...

  5. C++ code:函数指针数组

    函数指针作为一种数据类型,当然可以作为数组的元素类型.例如,要实现用菜单来驱动函数调用的程序框架,则用函数指针数组来实现就比较容易维护. #include<iostream> using ...

  6. 转:函数指针数组的妙用(I)

    转自:http://blog.sina.com.cn/s/blog_4c78b35f010008hi.html 笔者在开发某软件过程中遇到这样一个问题,前级模块传给我二进制数据,输入参数为 char* ...

  7. C/C++用状态转移表联合函数指针数组实现状态机FSM

    状态机在project中使用很的频繁,有例如以下常见的三种实现方法: 1. switch-case 实现.适合简单的状态机. 2. 二维状态表state-event实现.逻辑清晰.可是矩阵通常比較稀疏 ...

  8. (转)c++ typedef 函数指针详细说明

    转自:http://blog.csdn.net/future200x/article/details/5350134 一个函数在编译时被分配一个入口地址,将这个入口地址称为函数的指针,可以用一个指针变 ...

  9. c语言的函数指针和函数指针数组的简单demo

    今天,简单记录一下,函数指针和函数指针数组的使用,废话不多说,直接贴上代码,里面有详细的注释,方便以后查阅. #include <cstdio> #include <Windows. ...

随机推荐

  1. macOS sierra 10.12 Cocoapods 私有库

    使用Cocoapods创建私有podspec 见文章:http://www.cocoachina.com/ios/20150228/11206.html 或http://blog.wtlucky.co ...

  2. Unix内核中打开文件的表示

    Unix内核中已经打开文件,通过三种数据结构表示: 每个进程的进程表中的记录项,包含打开的文件的文件描述符表,与之关联的是: 文件描述符标识 指向一个文件表项的指针 内核为所有打开文件维持一张文件表, ...

  3. ExpandoObject动态类生成属性转json

    using System; using System.Collections; using System.Collections.Generic; using System.Collections.O ...

  4. oracle or语句的坑

    SELECT SUM(tjo.pay_amount) FROM tb_jf_order tjo,tb_jf_gateway_trade_log tjg WHERE tjo.order_id = tjg ...

  5. css响应式布局RWD

    响应式布局结合了三大理念: 1)用于布局的弹性网络(百分比定义宽度) 2)用于图片和视频的弹性媒体 3)媒体查询 在布局中,需要注意的点有: 1)尽量用min-width/max-width,max- ...

  6. 电脑文件出现“windows-文件发生意外问题-可修复(严禁修改)-错误代码0X00000BF8”错误,怎么办

    电脑文件出现"windows-文件发生意外问题-可修复(严禁修改)-错误代码0X00000BF8"错误,怎么办 下载一个"纵情文件修复器"修复一下就可以了 下载 ...

  7. 使用nginx-http-concat添加nginx资源请求合并功能

    web项目中有时候一个页面会加载多个js或css资源请求,导致页面加载耗时较长,这时优化的方向可以采用资源合并,可以在客户端事先合并,也可以在服务端进行资源合并,服务端合并的方式使用起来更灵活. ng ...

  8. C#、不说再见

    公司技术转型,.NET To Java,以后逐渐踏入Java阵营. 再见了 Java嫌弃的老同学,再见了 来不及说出的谢谢 再见了 不会再有的.NET,再见了 我留给你毕业册的最后一页 我相信 我们还 ...

  9. Unity5 项目设置 .gitignore 解决 Missing Prefab 问题

    同步Unity工程时候,两边总是出现Missing Prefab问题. 按照网上的教程设置是无效的.  后来Google了一下 才发现 新版Unity和旧版的设置方式是不同的. 1.在 Edit-&g ...

  10. paper122:多尺度与多分辨率的关系

    本文转自:http://blog.csdn.net/chgm_456d/article/details/8100513 我一直对于 多尺度与多分辨率没有一个准确的概念.后来看了一些文章,其中xiaow ...