通过K&R的C书,第2版了解C声明

pol*_*nut 5 c declaration semantics

我刚读完了第二版K&R的"The C Programming language"的语言参考(附录A),以获得一份新工作.

请注意,我已经制定了如何通过SO上的所有指导来阅读C声明(非常感谢;)).解释一直是对C语言中表达式和运算符的优先级的引用.
我可以从参考手册中推断出相同的优先级表,即所述书中的附录A,§A7,没问题.

但是,§A7处理表达式运算符的优先级,如本节开头所述 - 方括号postfix-expression [ expression ]在此处被视为下标运算符,星号*被视为间接运算符,括号( argument-expression-list)()与函数调用有关,请参阅§A7.3.
那么为什么这么多人会引用这个优先级表,当主题是C声明时,甚至会在SO上得到几个赞成?它声称定义的唯一优先级是某些表达式运算符.

如何解析声明是在§A8中编写的,尤其是§A8.6介绍了更复杂的声明的基础知识.
但是在整个附录A中,没有关于优先顺序,方括号,星号,类型名称等要解析的说法.
它在第216页说,括号可能会改变复杂声明符的绑定,但现在如何(虽然我有预感,请参阅下面的示例).

让我举一个"伪代码"的例子,我这里使用§A8.8(类型说明符的T代表,声明符的D代表).

阅读C声明:

Original declaration:
char (*(*f())[])()

/* Have to use A8.6.3, because of how the decl. looks: */
Now let T=char , D=(*(*f())[])()

D=D1(), where D1=(*(*f())[])
The type of f, according to A8.6.3 is then  
:L1 /* label 1 */
f is "type-modifiers of f in D1" function returning char /* note, in the book it says 'type-modifiers of f in T D1, but this wouldn't make any sense! */

  Now look at T D1 = char (*(*f())[])

    :ALT_A
    The type of f in D1 = (*(*f())[]) is the same as that of f in 
    D2=*(*f())[] 
    /* At least, this is how parentheses are supposed to be understood, according to the beginning of A8.6, 
    where it says: 
      In a declaration T D where D has the form 
          ( D1 )
    then the type of the identifier in the declaration D1 is the same as that of D. */
    /* note about that quote: the identifier in D has no type, did the authors mean to imply 'incomplete' types?
    So, using incomplete types:*/
    Looking at D2 = T1 D3[] ----> have to use A8.6.2,  where T1 = * , D3 = (*f()),
    so the type of f in T1 D3 is 
    f is "type-modifiers of f in D3" array of pointers ()

      look at f in D3 = (*f()), or equivalently, f in D4 = *f(). Have to use A8.6.3. ---> 
      f is a function returning a pointer to ()  

    going up a level: f is "type-modifiers of f in D3" array of pointers () 
    translates to: f is a function returning a pointer to an array of pointers ()

going up another level: f is "type-modifiers of f in D1" function returning char 
translates to: f is a function returning a pointer to an array of pointers to functions returning a char
Run Code Online (Sandbox Code Playgroud)

这是结果,cdecl也显示了.请注意,我没有使用任何优先级表,只是参考手册和直接与声明相关的部分.

那么这么多人如何以及为什么会提到运营商优先权呢?
在我看来,当人们询问C声明时,每次对运算符优先级的引用都是错误的答案,给出了一个神奇地证明可以给出正确结果的"解析算法".

其次,为什么K&R似乎对如此多的事情如此不精确(参见我的/**/ - 伪代码中的备注)?我本来期望更精确,我的意思是他们显然知道所有的细节,并且必须能够精确地思考.

抱歉格式混乱,顺便说一下..我今天大部分时间都在努力写下我如何手动解析这个问题,同时了解K&R对这个和那个公式的意义......

声源列表,其中声明与运算符优先级相关联:

http://users.ece.utexas.edu/~ryerraballi/CPrimer/CDeclPrimer.html ("所有人都要了解任何复杂的C声明,就是要知道这些声明是基于C运算符优先级图表的,同样的你用来评估C中的表达式的那个:")

http://binglongx.com/2009/01/25/how-to-read-a-cc-declaration/

(复杂)声明如何根据优先级和关联性进行解析? ("事实上,C的设计者足够明智地使声明使用与表达式相同的"优先规则".这是"声明遵循使用"规则.例如,在表达式"中,请参阅Brian的第一个答案."

C定义中的运算符优先级

专家C编程:Deep C Secrets,p.74,28在Google Books上的5星评价?

eca*_*mur 0

这是因为声明反映了使用。

在声明语法中,声明符被分为指针部分和直接声明符,其中应用了数组形成[]和函数形成构造,因此形成数组或函数类型比形成指针类型具有更高的优先级。()

并且,反映了这一点,在表达式的语法中,后缀运算符[]()比前缀一元运算符 具有更高的优先级*

这意味着当我们看到时int *f()我们知道这是一个返回指针的函数int,因为*f()给出了类型的值int;同样,我们知道这char (*g)()是一个指向返回函数的指针char,因为(*g)()必须给出类型为 的值char

这就是为什么附录 A 中会出现错误;预计没有人会阅读它,因为应用声明-反映-使用规则会给出正确的结果,并且更容易应用。