• [译】顺时针分析规则 —— 一种针对复杂变量声明的分析的方法(尤其是指针类型)


    在C/C++中,指针的类型分析有时是异常复杂的,昨日偶得一篇佳文,特译之与大家共享!

    正文:

    顺时针规则  

                                                                                                                                                   by David Anderson

    现在,有一种称之为“顺时针规则”的方法能让C程序员分析任何让人头疼的C语句声明。

    简言之,此法有如下3步:

    1. 从一个未知的元素开始,按顺时针方向移动,当遇到一个元素时,用对应的英语句子代替之:

      [X] or []

         => Array X size of... or Array undefined size of...

      (type1, type2)

        => function passing type1 and type2 returning...

      *

        => pointer(s) to...

      2. 按顺时针方向保持移动直到所有的符号被覆盖为止;

      3. 总是先在括号里面解决任何元素(注:原文用的是resovle anything,我也不知如何翻译更为恰当)

    例子#1. 简单的声明

    +-------+
                         | +-+   |
                         | ^ |   |
                    char *str[10];
                     ^   ^   |   |
                     |   +---+   |
                     +-----------+
    我们要问的问题是:str是什么东东?
      ``str is an...
    • 我们从 str 开始按顺时针方向移动,我们遇到的第一个字符是 [ ,这意味着有一个数组,所以……

          ``str is an array 10 of...

    • 继续按顺时针方向移动,下个遇到的东东是`*`,这意味着有一个指针,所以……

          ``str is an array 10 of pointers to...

    • 继续按顺时针方向移动直到了这一行的末尾(即`;`),继续移动直到我们看到`char`类型,所以……

          ``str is an array 10 of pointers to char''

    • 现在,我们已经“访问”了所有的符合,因此我们的分析也就完成了。

    例子#2。函数指针的声明

                   +--------------------+
                         | +---+              |
                         | |+-+|              |
                         | |^ ||              |
                    char *(*fp)( int, float *);
                     ^   ^ ^  ||              |
                     |   | +--+|              |
                     |   +-----+              |
                     +------------------------+
    我们要问的问题是:fp是什么东东?
      ``fp is a...
    • 按顺时针方向移动,我们遇到的第一个字符是`)`,因此我们在括号内部按顺时针方向移动,然后遇到的下一个符合是`*`,所以……

          ``fp is a pointer to...

    • 我们现在已经在括号外部,继续按顺时针方向移动,我们遇到了`(`,所以有一个函数,因此……

          ``fp is a pointer to a function passing an int and a pointer to float returning...

    • 继续按其移动,下个字符是`*`,即是指针,所以……

          ``fp is a pointer to a function passing an int and a pointer to float returning a pointer to...

    • 继续按其移动,下个字符是`;`,但是我们还没有“访问”完所有的符号,所以继续按顺时针方向移动直到我们遇到了类型`char`,所以……

          ``fp is a pointer to a function passing an int and a pointer to float returning a pointer to a char''

     

    例子#3.终极版

                     +-----------------------------+
                          |                  +---+      |
                          |  +---+           |+-+|      |
                          |  ^   |           |^ ||      |
                    void (*signal(int, void (*fp)(int)))(int);
                     ^    ^      |      ^    ^  ||      |
                     |    +------+      |    +--+|      |
                     |                  +--------+      |
                     +----------------------------------+
    我们要问的问题是:signal是什么东东?
    注意到signal是在括号里面,所以我们先从这里(即signal)开始!
    • 按顺时针方向移动,遇到的第一个字符是`(`,所以……

          ``signal is a function passing an int and a...

    • 嘿嘿,对于fp,我们可以使用同样的规则,所以……fp是什么东东?fp在括号里面,所以我们继续直到遇到字符`*`,所以……

          fp is a pointer to...

    • 继续移动,然后遇到`(`,所以……

          ``fp is a pointer to a function passing int returning...''

    • 然后我们离开函数的括号即可看到`void`,所以……

          ``fp is a pointer to a function passing int returning nothing (void)''

    • 我们已经完成了fp的分析,所以把它和signal的分析连接起来,有……

          ``signal is a function passing an int and a pointer to a function passing an int returning nothing (void) returning...

    • 我们仍然在括号里面,所以下个字符是`*`,即……

          ``signal is a function passing an int and a pointer to a function passing an int returning nothing (void) returning a pointer to...

    • 现在我们已经完成了这个括号里面的部分,所以继续移动,然后我们遇到了另外一个`(`,所以……

          ``signal is a function passing an int and a pointer to a function passing an int returning nothing (void) returning a pointer to a function passing an int returning...

    • 最后,继续移动直到遇到左边的关键字`void`,所以对signal最后的定义即为:

          ``signal is a function passing an int and a pointer to a function passing an int returning nothing (void) returning a pointer to a function passing an int returning nothing (void)''

    同样的规则亦适用于 constan 和 volatile类型的声明,例如:    

        const char *chptr;
    • 现在,chptr是什么东东?

          ``chptr is a pointer to a char constant''

    那下面这个:

        char * const chptr;
    • 现在,chptr是什么东东?

          ``chptr is a constant pointer to char''

    最后,

        volatile char * const chptr;
    • 现在,chptr是什么东东?

          `chptr is a constant pointer to a char volatile.''

    K&R II 第122页的例子练习这个规则!

    注:

    1. 因为个人水平,译文有所粗糙,敬请谅解!
    2. 原文链接
    
    
  • 相关阅读:
    最大流之dinic
    HDU 2485
    最小费用最大流
    HDU 1533
    HDU 1402
    HDU 1498
    HDU 1281
    Codeforces 283E Cow Tennis Tournament 线段树 (看题解)
    Codeforces 983E NN country 思维 (看题解)
    Codeforces 494D Birthday 树形dp (看题解)
  • 原文地址:https://www.cnblogs.com/youngkingwang/p/2985003.html
Copyright © 2020-2023  润新知