在《C陷阱与缺陷》第二章第一节中有这样一个声明:

(*(void(*)())0)();

看到这样的表达式估计让不少人都“不寒而栗”了吧,其实虽然看起来复杂,但是构造这类表达式其实只有一条简单的规则:按照使用的方式来声明。

首先先介绍一个著名的解析法则:右左法则:首先从圆括号起,然后向右看,然后向左看,每当遇到圆括号时,就调转阅读方向,当括号内的内容解析完毕,就跳出这个括号,重复这个过程直到表达式解析完毕。

其实我们发现,所谓复杂指针离不开指针函数,函数指针,指针数组,函数指针这四个概念并且括号,*比较多,其实只要我们仔细分析这些看起来复杂的表达式,其实他的逻辑也是很清晰的。

举个例子,使用右左法则解析复杂的表达式:

Int *(*(*pfun)(int *))[10];

用右左法则解析这个表达式,首先要找到未定义的标识符pfun,当往右看的时候遇到括号,于是调转方向,再朝相反的方向看,pfun遇到了*,说明pfun是一个指针,再往左看又遇到了括号,因此又要调转方向,遇到的是另外一个括号,因此说明指针所指向的是一个函数,函数的参数是一个整型指针。然后又向相反的方向看,又遇到了一个*,说明该函数的返回值又是一个指针,在往左看又遇到括号,所以再次调转方向,把内侧的括号里的内容看完,出了括号遇到的是数组,说明指针所指向的函数的返回值类型的指针指向的是数组,这有点向绕口令,但是还是有逻辑可循的。

但是右左法则确实有点麻烦,我们这样看上面这个表达式:首先fpun是一个指向函数的函数指针,该函数有一个整型指针类型的参数并且返回值也是一个指针,所返回的类型指向的是一个数组,并且这个数组有10个元素,每个元素是整型指针类型。

接下来我们在回过头来看文章最开始的那个表达式:

(*(void(*)())0)();

我们先看括号里面的内容,首先0被强制转换为一个返回值为void类型,没有参数的函数的函数指针,指针(void)(*)()0)指向了一个函数。

要想很好的解决这个问题,选择使用typedef是一个很好的方式。

C语言之复杂指针详解的更多相关文章

  1. 结构体指针,C语言结构体指针详解

    结构体指针,可细分为指向结构体变量的指针和指向结构体数组的指针. 指向结构体变量的指针 前面我们通过“结构体变量名.成员名”的方式引用结构体变量中的成员,除了这种方法之外还可以使用指针. 前面讲过,& ...

  2. 深入理解C语言 - 指针详解

    一.什么是指针 C语言里,变量存放在内存中,而内存其实就是一组有序字节组成的数组,每个字节有唯一的内存地址.CPU 通过内存寻址对存储在内存中的某个指定数据对象的地址进行定位.这里,数据对象是指存储在 ...

  3. Linux C 语言之 Hello World 详解

    目录 Linux C 语言之 Hello World 详解 第一个 C 语言程序 程序运行原理 编译,链接 运行时 链接库 编译器优化 Hello World 打印原理 stdout, stdin 和 ...

  4. Delphi指针详解

    Delphi指针详解2007-12-04 06:08:57|  分类: DLL学习 阅读91 评论0   字号:大中小 订阅 大家都认为,C语言之所以强大,以及其自由性,很大部分体现在其灵活的指针运用 ...

  5. [转]C++ 智能指针详解

    转自:http://blog.csdn.net/xt_xiaotian/article/details/5714477 C++ 智能指针详解 一.简介 由于 C++ 语言没有自动内存回收机制,程序员每 ...

  6. C++ 智能指针详解(转)

    C++ 智能指针详解   一.简介 由于 C++ 语言没有自动内存回收机制,程序员每次 new 出来的内存都要手动 delete.程序员忘记 delete,流程太复杂,最终导致没有 delete,异常 ...

  7. [转]C语言字节对齐问题详解

    C语言字节对齐问题详解 转载:https://www.cnblogs.com/clover-toeic/p/3853132.html 引言 考虑下面的结构体定义: typedef struct{ ch ...

  8. 【C++】智能指针详解(一):智能指针的引入

    智能指针是C++中一种利用RAII机制(后面解释),通过对象来管理指针的一种方式. 在C++中,动态开辟的内存需要我们自己去维护,在出函数作用域或程序异常退出之前,我们必须手动释放掉它,否则的话就会引 ...

  9. C语言解决约瑟夫问题详解的代码

    将开发过程中比较重要的一些内容做个收藏,下面的内容是关于C语言解决约瑟夫问题详解的内容,希望能对码农有帮助. #pragma once #include<vector> class PRO ...

随机推荐

  1. mysql存储过程和事件

    1.会员表member和车辆表car,更新每个会员下面的车辆数量have_car字段. DELIMITER $$ USE $$ DROP PROCEDURE IF EXISTS `sp_update_ ...

  2. 在线API文档

    http://www.ostools.net/apidocs A Ace akka2.0.2 Android Ant Apache CXF Apache HTTP服务器 ASM字节码操作 AutoCo ...

  3. POJ 3662

    Telephone Lines Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4591   Accepted: 1693 D ...

  4. Python并发与并行的新手指南

    点这里 在批评Python的讨论中,常常说起Python多线程是多么的难用.还有人对 global interpreter lock(也被亲切的称为“GIL”)指指点点,说它阻碍了Python的多线程 ...

  5. Peer certificate cannot be authenticated with known CA certificates.

    I was trying to post to a webservice and was getting the 60 error code: Peer certificate cannot be a ...

  6. hdu 4345 Permutation 记忆化搜索

    思路:实际上求的是和小于等于n的质数的种类数!!! 代码如下: #include<iostream> #include<stdio.h> #include<algorit ...

  7. CF 197 DIV2 Xenia and Bit Operations 线段树

    线段树!!1A 代码如下: #include<iostream> #include<cstdio> #define lson i<<1 #define rson i ...

  8. [转载] ACE 组播校验和出错问题解决

    源地址:http://yuanmuqiuyu2000.blog.sohu.com/140904942.html 使用ACE框架写了个组播简单的测试工具,但是测试过程中,总是发现udp校验和出错的信息. ...

  9. QTP10补丁汇总

    QTP10补丁汇总 QTP_00591.EXE QTP10 调试器视图问题的补丁 QTP_00591 - Prevent QuickTest Debug Viewer Problems when Pr ...

  10. 545E. Paths and Trees

    题目链接 题意:给定一个无向图和一个点u,找出若干条边组成一个子图,要求这个子图中u到其他个点的最短距离与在原图中的相等,并且要求子图所有边的权重之和最小,求出最小值并输出子图的边号. 思路:先求一遍 ...