野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 14138|回复: 5

正确解析C语言中的复杂声明

[复制链接]
发表于 2013-5-13 18:41:08 | 显示全部楼层 |阅读模式

在CU的C/C++版上看到一些比较复杂的函数声明:

  1. void (*(*p) (void *(*) (char *, long , long ))) (char *, long , long);

  2. void (*tpsetunsol (void (_TMDLLENTRY *)(*disp) (char *data, long len, long flags))) (char *data, long len, long flags);

  3. void double (*(*(*fp)())[10])()
复制代码
如何来读懂这些函数声明呢?

首先我们对它们进行一些“格式化”:
  1. void (*(*p)(
  2.              void *(*) (char *, long , long )
  3.            )
  4.      )(char *, long , long);
复制代码
  1. void (*tpsetunsol(
  2.                   void (_TMDLLENTRY *)(*disp)(char *data, long len, long flags)
  3.                  )
  4.      )(char *data, long len, long flags);
复制代码
  1. double (*
  2.            (*
  3.                (*fp)()
  4.            )[10]
  5.        )();
复制代码
然后掌握以下几点:
1. 括号()有两种作用:一是函数调用运算符,二是改变(默认的/原来的)结合顺序。
2. 记住括号作为函数调用运算符时,它的优先级要比 * 高。
3. 一个函数的声明,除了他的函数名和参数之外,剩余的就是它的返回值(类型)了。

4. 数组的成员访问运算符 [ ] 的优先级要比 * 高。


这种东西,一旦你掌握了方法,其实太简单不过了:


1) p是一个函数指针,p指向的函数的参数也是一个函数指针void *(*) (char *, long , long ),p指向的函数的返回值也是一个函数指针void (*)(char *, long , long);

2) tpsetunsol是一个函数,它的返回值为:void (*)(char, long, long),是一个函数指针。然后tpsetunsol函数的参数为:void (_TMDLLENTRY *)(*disp) (char *data, long len, long flags),参数的类型也是一个函数指针。
所以:tpsetunsol是一个参数和返回都是函数指针的函数。



3) fp是一个函数指针,fp指向的函数的返回值是一个数组指针(指向数组的指针),而数组指针指向的数组是“指针数组”(保存指针的数组),指针数组的大小为10,数组中的成员的类型是一个返回值为double的函数指针(指向函数的指针)。


另外:我们可以利用typedef来简化这样比较复杂的声明。类似于signal函数:
  1. #include <signal.h>
  2. typedef void (*sighandler_t)(int);
  3. sighandler_t signal(int signum, sighandler_t handler);
复制代码


简化如下:
  1. typedef void* (*FP1)(char *, long , long)
  2. typedef void (*FP2)(char *, long , long)

  3. FP2 (*p)(FP1 );
复制代码
  1. typedef void (*disp_f)(char * data,long len,long flags)

  2. disp_f tpsetunsol(disp_f _TDMLLENTRY * disp);
复制代码
  1. typedef double (*FP_DOUBLE)();
  2. typedef PF_DOUBLE (*P_ARRAY)[10];
  3. P_ARRAY (*fp)();
复制代码

函数指针:指向函数的指针。比如 int (*pf)(int, int);
指针函数:返回指针的函数。比如 int *fp(int, int);      也可这样写 int* fp(int, int);
数组指针:执行数组的指针。比如 int (*p_array)[10];
指针数组:保存指针的数组。比如 int *arrray_p[10];   也可这样写 int* array_p[10];


最后
char (*(*x[3])())[5];
char *(*(*f(char *(*para)(char *)))[2])();  
请试着解析它。



原文地址:
http://blog.chinaunix.net/space.php?uid=25909722&do=blog&id=3022956
回复

使用道具 举报

发表于 2013-5-15 22:18:39 | 显示全部楼层
学习中!!!
回复 支持 反对

使用道具 举报

发表于 2014-4-26 16:01:25 | 显示全部楼层
晕死个人 比雷公还雷人哦~
回复 支持 反对

使用道具 举报

发表于 2015-1-8 15:35:37 | 显示全部楼层
有点难懂,。。。。
回复

使用道具 举报

发表于 2022-8-5 13:19:33 | 显示全部楼层
涉及到指针了  指的晕头转向的
回复 支持 反对

使用道具 举报

发表于 2022-9-2 11:44:56 | 显示全部楼层
学习了!指针真复杂,可以玩得自己都晕头。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-3-28 18:31 , Processed in 0.035130 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表