我想对C的常数表达有一个精确的理解。所以,我读了C99的相关规定。第一章" 6.6常量表达式"描述了常量表达式的语法,但我无法理解它。
第一章" 6.6常量表达式" C99:
常数表达式:
条件表达式
为什么C99使用条件表达式来解释常量表达式?毫无疑问,表达式2 + 3是一个常数表达式。这是条件表达式吗?
答案 0 :(得分:3)
要理解§6.6常量表达式,您需要理解语法的工作方式,并且需要阅读§6.5表达式。
在§6.5表达式中,第6.5.15节条件表达式说:
conditional-expression:
logical-OR-expression
logical-OR-expression ? expression : conditional-expression
这是标准指定优先级等的方式。想法是将赋值运算符和逗号表达式排除为“常量表达式”,但允许其余的大多数,受到§6.6中定义的约束(其中,除其他外,明确排除赋值和逗号运算符,可能是因为规则中的泛型表达式确实包含它们。)
答案 1 :(得分:3)
符号“constant-expression:conditional-expression”只是常量表达式语法的规范。语法描述可能是常量表达式的字符串。除了满足语法之外,常量表达式还必须满足第6.6节中列出的约束。
C标准使用“constant-expression:conditional-expression”这一事实可能令人困惑。但是,如果标准使用“constant-expression:expression”,它将完全相同,如下所示。也就是说,任何表达式都是一个常量表达式,前提是它不仅遵循表达式的语法,还遵循第6.6节中列出的约束。
条件表达式的一个示例是3 < 4 ? 5 : 6
。该表达式也是一个常量表达式,因为它满足第6.6节中的约束。另一方面,x < 4 ? 5 : 6
也是一个条件表达式,但不是一个常量表达式(假设x
是一个对象的名称,而不是一个被常量替换的宏,等等)。
第6.6节告诉您,如果条件表达式满足约束条件,则它可以是常量表达式。条款6.5.15表明条件表达式可以是logical-OR-expression
或logical-OR-expression ? expression : conditional-expression
。继续在链中工作,logical-OR-expression
可以是a logical-AND-expression
,也可以是使用逻辑OR运算符||
构建的表达式。虽然每个级别的名称类似于foo-expression
,但每个级别实际上是之前的表达式类型,或者是使用foo
构建的表达式。将它们命名为foo-expression-or-prior-type-of-expression
而不仅仅是foo-expression
,这只是一件麻烦事。
因此,语法从原色开始,这些原色是标识符,常量,字符串文字,我将在稍后讨论一个特殊的东西,语法将这些原色构建成更复杂的表达式,增加了使用每个运算符的可能性C允许。以这种方式分层语法定义了运算符优先级,因为在可能的情况下,必须在后面的表达式之前解析早期表达式。
主要内容中的特殊内容是带括号的表达式( expression )
。 expression
标记是6.5.17中定义的定义链的末尾。这会循环语法;任何表达式都可以放在括号中,这使得它成为一个新的primary
,然后可以将运算符应用到它。
第6.6条可以说constant-expression
是expression
,它与conditional-expression
的效果相同。这是因为6.6中的约束禁止赋值运算符和逗号运算符。因此,如果我们考虑expression
可能是什么,则第6.5.17条规定它可以是assignment-expression
或expression , assignment-expression
。但禁止逗号运算符的约束禁止后者。因此,常量表达式中的expression
必须是assignment-expression
。同样,assignment-expression
必须是conditional-expression
而不是unary-expression assignment-operator assignment-expression
。
答案 2 :(得分:2)
首先,C标准没有解释任何内容。它告诉我们如何定义C语言,但它没有说明原因。
语法部分使用特殊语言(EBNF的变体)编写,用于描述编译器应如何解释C源代码。 规范
constant-expression:
conditional-expression
本质上意味着常量表达式使用与conditional-expression
相同的语法。在有关条件运算符(6.5.15)的部分中,您将找到一个类似的语法部分,用于定义conditional-expression
的构建方式。
如果跟踪所有语法规则,您会发现constant-expression
可以使用除赋值运算符(=, *=, /=, +=, -=, <<=, >>= &=, ^=, |=
)和逗号运算符(,
)之外的任何运算符(除非它们)括在括号中。