C ++主表达式 - 它是否是主表达式?

时间:2013-06-23 09:49:57

标签: c++ standards expression

1)为什么他们被称为“主要”?按照评价的顺序,他们是第一个?

2)C ++ 03标准定义了第5章(注1)中的表达式:“表达式是a 指定计算的运算符和操作数序列。“

然后5.1“主要表达式”定义了主要表达式列表:

(1)primary-expression:

字面

(表达)

ID-表达

我的主要问题与第三点有关:

(表达)

因此,根据标准,带括号的每个表达式都是主表达式,首先计算它们。它看起来很合理,并且给出了C ++表达式(优先级)中括号行为的准确解释。

所以这就是例如

(变量+10)

是主要表达。

var =(变量+ 10)* 3

根据我的理论,它看起来很合乎逻辑,但我知道其他来源

(变量+10)

不是主要表达,但为什么?我不明白,但标准定义了

(表达式)

作为主要表达。

请帮助我,因为我不能。非常感谢,对不起我的英语不好。 您好。

2 个答案:

答案 0 :(得分:7)

C ++表达式可能很复杂,也就是说它们可以由嵌套表达式组成,通过使用运算符组合在一起,而这些嵌套表达式又可能很复杂。

如果将复杂表达式分解为更小的单位,那么在某些时候,你将留下原子,因为它们无法进一步分解。这些是主要表达;它们包括标识符,文字,关键字this和lambda表达式。

但是,确实存在一个C ++标准定义为主要的非原子构造:用圆括号括起来的表达式(也就是括号)。所以你给出的(variable + 10)示例是一个主表达式(子表达式variable(它是一个标识符)和10(它是一个文字)。

我相信标准将它们列为主要表达式,因为它们在评估顺序中扮演真正的原子表达式的角色:必须在支持表达式的值可以进入评估之前评估括号内的任何内容其他表达式:在(5+10)*a中,必须先评估5+10的值,然后才能进入*a的评估。 [请注意,这并不意味着在评估表达式5+10之前评估a。它只表示在计算乘法本身之前必须对5+10进行求值。]

因此,在这个意义上,括号中的子表达式就好像它们是原子的一样。

我想这就是为什么标准不对这个概念使用术语“原子表达式”。它们表现得好像是原子的,但至少包括在内的品种实际上并不是原子的。对我来说,“小学”似乎是一个很好的选择。

答案 1 :(得分:1)

术语 primary-expression 是语言语法的一个元素。它们本可以被称为 foobar-expression ,但这只是一个没有更深层含义的名称。

一个 primary-expression 不一定是原子的,首先被评估,顶层的,比其他表达式更重要的东西或类似的东西。而且所有表达式都是“构建块”,因为可以添加任何表达式以形成更大的表达式。

问题中已经给出了定义,因此在此不再赘述。

(variable + 10)是主要表达式,您的“其他来源”是错误的。这是 primary-expression 的另一个示例:

([]{
int n, t1 = 0, t2 = 1, nextTerm = 0;

cout << "Enter the number of terms: ";
cin >> n;

cout << "Fibonacci Series: ";

for (int i = 1; i <= n; ++i)
{
    // Prints the first two terms.
    if(i == 1)
    {
        cout << " " << t1;
        continue;
    }
    if(i == 2)
    {
        cout << t2 << " ";
        continue;
    }
    nextTerm = t1 + t2;
    t1 = t2;
    t2 = nextTerm;
    
    cout << nextTerm << " ";
}
return 0;  
}())

(这将调用lambda函数并在结果中加上括号;代码是从here借来的)。


此外,该问题还带有对评估的优先级和顺序的常见误解。该标准根本没有提到“优先级”。优先级表是一种以更易于阅读的方式呈现语言语法规则的方法。

它是指将操作数与运算符组合在一起的方式,而不是子表达式的执行顺序。在f() + ([]{int n, t1 = 0, t2 = 1, nextTerm = 0; cout << "Enter the number of terms: "; ....等情况下,可以在调用lambda之前调用f(),也可以不调用。 Lambda周围的括号不会使它首先被求值。