什么样的运算符是(),[]?一元还是二元? [英] What kind of operator is ( ), [ ] ? unary or binary ?

查看:80
本文介绍了什么样的运算符是(),[]?一元还是二元?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们可以在调用函数时考虑()一元运算符,在exps eq。

f(),(1 + 2)。但是当我们调用函数f(10)时,它是一个二元的

运算符。即使我们正在使用f(10,20),运算符那么

一个操作数将在那里用于()?


和一元运算符一样!,+, - ,〜,......据说从右到左有

关联性,这意味着我们可以写,(但不允许



1. 2!

2.!2

作为解释,我们可以说。在第一种情况下!没有

左操作数它将采用右操作数并将与

相关联。在第二种情况下,它将与左边相关

本身。


但是不允许使用案例1.然后从右到左说什么是关于

关联的必要性它总是与正确的关联



如果有错,任何人都可以解释什么关联性究竟意味着什么?

解决方案

Anoob写道:


我们可以在调用时考虑()一元运算符吗?一个函数,在exps eq。
f(),(1 + 2)。但是当我们调用函数f(10)时,它是一个二元
运算符。即使我们正在使用f(10,20),运算符那么
一个操作数将用于()?




逗号不是参数列表中的逗号运算符。这种标点符号的重复使用是美女之一。 C.


-

查克F(cb********@yahoo.com)(cb ****** **@worldnet.att.net)

可用于咨询/临时嵌入式和系统。

< http://cbfalconer.home.att.net>使用worldnet地址!


In< 41 *************** @ yahoo.com> CBFalconer< cb ******** @ yahoo.com>写道:

Anoob写道:


在调用函数时我们可以考虑()一元运算符,在exps eq。
f (),(1 + 2)。但是当我们调用函数f(10)时,它是一个二元
运算符。即使我们正在使用f(10,20),运算符那么
一个操作数将用于()?



逗号不是逗号运算符参数列表。这种标点符号的重复使用是美女之一。 of C.




您也可以在Fortran中找到它们。 A(2,3)是函数调用还是

数组元素?


Dan

-

Dan Pop

DESY Zeuthen,RZ集团

电子邮件: Da * ****@ifh.de

目前在欧盟找工作


文章< 28 * ***********************@posting.google.com>

Anoob< be ****** @ yahoo .COM>写道:

我们可以在调用函数时考虑()一元运算符...


编号或者更确切地说,你可以考虑任何你喜欢的东西

你喜不喜欢,但这不会成功。 :-)函数调用中使用的括号

仅仅是语法,而不是运算符,在
中编译器编写者使用的术语[%]与其他

编译器编写者沟​​通。

-----

[%]行话,在这种情况下,意味着技术领域中使用的专业英语子集

。例如,在法律中,

而是有一个特殊的行话化意义。医学上充满了b
行话,其中一些已被电视节目推广:大多数人

知道stat例如,现在意味着现在。在这里,我要用

来使用优先级字样。和结合性,它们都是计算机科学(CS)术语,也是解析和结合。和语法,其中

是采用英语 - 语法行话的CS术语。

-----

和一元运算符一样!,+, - ,〜,...据说从右到左有结合性...


一元运算符不需要关联性。有些人可能会说

他们拥有它,但这通常是其他东西的简写。


C'的正式规格(一,C89或C99) )*既不*

优先*也不*关联性。它使用了一个完全因子的语法

,其中模糊的解析是不可能的。然而,这是* * b $ b与* do *允许模糊解析的其他语法同构,在

中,歧义通过优先级和关联性来解决。


考虑表达式:


a - b * c + d


在C中,这个意味着 ;同样的事情:


(a - (b * c))+ d


与以下内容完全不同:


a - (b *(c + d))


但我们怎么认为* b * c绑定最多

紧,然后a-(结果)和(结果)+ d绑定应该

发生?


C标准(C89和C99两者)确保我们通过费力的努力拿出

正确的绑定。语法包括这些

位:


multiplicative-expr:

cast-expr

乘法-expr * cast-expr

multiplicative-expr / cast-expr

multiplicative-expr%cast-expr


加法 - expr:

multiplicative-expr

additive-expr + multiplicative-expr

additive-expr - multiplicative-expr

...


表达式:

assignment-expr

表达式,赋值-expr


(并且让我在没有支持的情况下声称a,b,c和

d中的每一个最终都被cast-expr允许,并且该赋值 - expr

最终包含additive-expr。


要将整个表达式解析为表达式,我们必须找到

某种方式可以获得这个语法允许的
a - b * c + d


。也就是说,整个事情必须是一个表达式,它可以是一个赋值表达式,而一个

赋值表达式可以是一个additive-expr。


而a是(通过长链)有效的cast-expr,a - b

是*不是*有效的cast-expr,所以它不是乘法 - expr

要么。这意味着a-b表示a-b。 *不能*是左手边

(LHS)的乘法expr。但请注意,a表示a。 * can *是乘法expr的

*整数*,plus-expr可以

完全由乘法expr组成。类似地,additive-expr

可以包含右侧的乘法expr(RHS)

的序列additive-expr - multiplicative- EXPR" (因为

LHS乘法 - expr被允许作为加法 - expr,即使

,也不允许将additive-expr作为乘法expr)。


现在,b * c当然是一个有效的乘法 - expr,如果我们匹配

" a - b * c"违反规则:


additive-expr:

additive-expr - multiplicative-expr


和make第一个a additive-expr和b * c乘法 - expr,

它都可以工作,所以整个事情本身就是一个加法 - expr。这个

允许我们将它全部收集到一个绑定组中,调用

表示additive-expr;现在我们可以使用它作为LHS:


additive-expr:

additive-expr + multiplicative-expr


其中d是乘法 - 表达式。


如果你已经设法完成所有这些,你应该看到我们

已经把它作为我们的最终解析树 ;:


+

/ \

- d

/ \

a *

/ \

bc


解析是关于获得正确的解析树和C89并且

C99标准都使用完全因子语法来确保

你可以*只*获得*一个*解析树以获得任何有效表达式。然而

是这些语法的两个问题:


- 与运营商优先相比,人们使用它们很痛苦

语法;并且

- 它们在自动解析器生成器(例如

yacc和bison)中的效率低于运算符优先级语法。


在运算符优先语法中,我们只描述

和表达式的语法。给* all *可能的运算符,例如:


expr:

变量名

expr + expr

expr - expr

expr * expr

expr / expr


但这意味着我们有模棱两可的解析 ;:a + b * c(有或没有

末尾的 - d)可以是(a + b)-as-an-expr * c-as-an-expr ,或者

a-as-an-expr +(b * c)-as-an-expr。所以我们引入一个新概念

称为优先级,并说*和/具有优先权超过+

和 - ,意味着你应该比一个+(结果)更紧密地绑定b * c到

确保你得到正确的解析树。


Precedence修复了绑定添加之前的绑定乘法问题,

但是没告诉你如何解决像e-f-g那样的表达式:是(b-b)那个(e-f)-g,还是e-(f-g)?你绑定左边的 - 第一个

或右边的 - ?它们具有相同的运算符优先级,所以这个

没有帮助。所以现在我们引入另一个概念,结合性,

并说 - 是左关联的,所以我们首先绑定左边的 - >

,给予(ef)-g。


再次,这更容易*人*(并且在某种程度上,在
yacc和bison中也更好),但它只是一种确保我们

获得正确解析树的方法。计算机*可以*使用完全因子的

语法,而C标准则可以。


*所有这* *只是*用于构建一个解析树。它没有,

我重复没有,控制实际的运行时评估顺序。要

,请参阅评估顺序。是一个单独的问题,考虑一个C

源代码行说:


sum = f()+ g();

其中函数f()和g()都向stdout打印一行,显示他们已经运行了




int f(void ){puts(" f()called);;返回17; }

int g(void){puts(" g()called");返回25; } $ / $

当你运行一个使用f()+ g()的程序时,其中一个将首先调用

,然后调用另一个 - 并且没有人说首先会发生哪一个
,这取决于编译器 - 但是没有

优先级,并且没有关联性来弄清楚如何解析

a simple" x + y"加成。由于我们有运行时订单

评估,如果没有优先级,它们必须是*独立的东西。

...任何人都可以解释关联性的确切含义吗?




这是执行摘要版本:


- C标准不使用运算符优先级语法,但

*你*可以,如果你喜欢。


- 如果你*使用运算符优先级语法,你需要

来记住哪些运算符优先而其他人,和
使用它来解决解析模糊。使用优先权后,

如果(并且只有)还有更多含糊之处,你需要

才能记住关联性。其余含糊不清的
运算符,用它来解决它们。


- 优先级和关联性不控制运行时顺序

评估。它们只影响编译时解析树。

解析树通常会有某种部分顺序。在运行时代码上运行
,但要获得*保证*运行时序列,你需要使用C'的序列点。

-

In-Real-Life:风河系统Chris Torek

美国犹他州盐湖城(40°39.22''N,111°50.29 ''W)+1 801 277 2603

电子邮件:忘了它 http://web.torek.net/torek/index.html

由于垃圾邮件发送者,阅读电子邮件就像在垃圾中搜索食物一样。


Can we consider () unary operator when calling a function, in exps eq.
f(), ( 1 + 2). But when we call function f( 10 ) it is a binary
operator. Even if we pass f( 10, 20) as we are using , operator there
one operand will be there for ()?

And Unary operators like !, +, -, ~, ... are said to be having
associativity right to left which means that we can write, (but not
allowed)
1. 2!
2. !2
As an explanation can we say. in the first case as ! is not having a
left operand it will take right operand and will be associated with
that. where as in the second case it will be assosiated with left
itself.

But the case 1. is not allowed. Then what is the neccessity for saying
the associativiy from right to left it is always associated with right
?
if wrong can anyone explain what exactly does associativity means?

解决方案

Anoob wrote:


Can we consider () unary operator when calling a function, in exps eq.
f(), ( 1 + 2). But when we call function f( 10 ) it is a binary
operator. Even if we pass f( 10, 20) as we are using , operator there
one operand will be there for ()?



The comma is NOT a comma operator in parameter lists. This sort of
reuse of punctuation is one of the "beauties" of C.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!


In <41***************@yahoo.com> CBFalconer <cb********@yahoo.com> writes:

Anoob wrote:


Can we consider () unary operator when calling a function, in exps eq.
f(), ( 1 + 2). But when we call function f( 10 ) it is a binary
operator. Even if we pass f( 10, 20) as we are using , operator there
one operand will be there for ()?



The comma is NOT a comma operator in parameter lists. This sort of
reuse of punctuation is one of the "beauties" of C.



You can find them in Fortran, too. Is A(2, 3) a function call or an
array element?

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Currently looking for a job in the European Union


In article <28************************@posting.google.com>
Anoob <be******@yahoo.com> wrote:

Can we consider () unary operator when calling a function ...
No. Or rather, you can consider anything you like to be anything
else you like, but that will not make it so. :-) The parentheses
used in function calls are merely "syntax", not "operators", in
the jargon[%] used by compiler-writers to communicate with other
compiler-writers.
-----
[%] "Jargon", in this case, means a specialized subset of English
as used in a technical field. In law, for instance, the word
"whereas" has a special jargon-ized meaning. Medicine is full of
jargon, some of which has been popularized by TV shows: most people
know that "stat" means "right now", for instance. Here, I am going
to use the words "precedence" and "associativity", which are both
computer-science (CS) jargon, and also "parse" and "grammar", which
are CS jargon adopted from English-grammar jargon.
-----
And Unary operators like !, +, -, ~, ... are said to be having
associativity right to left ...
Unary operators do not need associativity. Some people may say
they have it, but this is usually shorthand for something else.

C''s formal specification (either one, C89 or C99) has *neither*
precedence *nor* associativity. It uses a fully factored grammar
in which ambiguous parses are impossible. This is, however,
isomorphic to other grammars that *do* allow ambiguous parses, in
which the ambiguity is resolved by "precedence and associativity".

Consider the expression:

a - b * c + d

In C, this "means" the same thing as:

(a - (b * c)) + d

which is quite different from:

a - (b * (c + d))

But how are we supposed to *know* that the b*c binds the most
tightly, and then the a-(result) and (result)+d bindings should
happen?

The C standards (C89 and C99 both) make sure we come up with the
correct bindings by laborious effort. The grammar includes these
bits:

multiplicative-expr:
cast-expr
multiplicative-expr * cast-expr
multiplicative-expr / cast-expr
multiplicative-expr % cast-expr

additive-expr:
multiplicative-expr
additive-expr + multiplicative-expr
additive-expr - multiplicative-expr

...

expression:
assignment-expr
expression , assignment-expr

(and let me just claim without support that each of a, b, c, and
d are eventually allowed by "cast-expr", and that assignment-expr
eventually includes additive-expr).

To parse the entire expression as an "expression", we have to find
some way for

a - b * c + d

to be allowed by this grammar. That is, the whole thing has to
be an "expression", which can be an "assignment-expr", and an
assignment-expr can be an additive-expr.

While "a" is (through a long chain) a valid "cast-expr", "a - b"
is *not* a valid cast-expr, so it is not a multiplicative-expr
either. This means that "a - b" *cannot* be the left hand side
(LHS) of a multiplicative-expr. But note that "a" *can* be the
*entirety* of a multiplicative-expr, and an additive-expr can
consist entirely of a multiplicative-expr. Similarly, an additive-expr
can consist of a multiplicative-expr on the right-hand-side (RHS)
of the sequence "additive-expr - multiplicative-expr" (because the
LHS multiplicative-expr is allowed as an additive-expr, even though
an additive-expr is not allowed as a multiplicative-expr).

Now, b*c is of course a valid multiplicative-expr, and if we match
"a - b*c" up against the rule:

additive-expr:
additive-expr - multiplicative-expr

and make the first "a" the additive-expr and b*c the multiplicative-expr,
it all works, so this whole thing is itself an additive-expr. This
allows us to collect it all up into one bound-up group, calling
that an "additive-expr"; and now we can use that as the LHS of:

additive-expr:
additive-expr + multiplicative-expr

where "d" is the multiplicative-expr.

If you have managed to follow all that, you should see that we
have gotten this as our final "parse tree":

+
/ \
- d
/ \
a *
/ \
b c

Parsing is all about getting the right parse tree, and the C89 and
C99 standards both use a fully-factored grammar to make sure that
you can *only* get *one* parse tree for any valid expression. There
are two problems with such grammars, though:

- they are painful for people to use, compared to operator-precedence
grammars; and
- they are less efficient in automated parser-generators (like
yacc and bison) than operator-precedence grammars.

In an operator-precedence grammar, we just describe the syntax for
an "expression" giving *all* the possible operators, e.g.:

expr:
variable-name
expr + expr
expr - expr
expr * expr
expr / expr

But this means we have "ambiguous parses": a + b * c (with or without
the "- d" on the end) can be (a + b)-as-an-expr * c-as-an-expr, or
a-as-an-expr + (b * c)-as-an-expr. So we throw in a new concept
called "precedence", and say that * and / "have precedence" over +
and -, meaning you should bind b*c more tightly than a+(result), to
make sure you get the right parse tree.

Precedence fixes the "bind multiply before binding add" problem,
but does not tell you how to resolve expressions like e-f-g: is
that (e-f)-g, or is that e-(f-g)? Do you bind the left "-" first
or the right "-"? They have the same operator-precedence, so this
does not help. So now we throw in yet another concept, "associativity",
and say that "-" is left-associative so that we bind the left "-"
first, giving (e-f)-g.

Again, this is easier for *people* (and to some extent, nicer in
yacc and bison as well), but it is just a way to make sure that we
get the right parse tree. A computer *can* use a fully-factored
grammar instead, and the C standards do.

*All* of this is *just* used to build a parse tree. It does not,
I repeat DOES NOT, control actual run-time order of evaluation. To
see that "order of evaluation" is a separate issue, consider a C
source line that says:

sum = f() + g();

where functions f() and g() both print a line to stdout showing that
they have run:

int f(void) { puts("f() called"); return 17; }
int g(void) { puts("g() called"); return 25; }

When you run a program that uses f()+g(), one of the two will get
called first, then the other -- and nobody says which one will
happen first, and this is up to the compiler -- but there is no
precedence and no associativity needed to figure out how to parse
a simple "x + y" addition. Since we have "runtime order of
evaluation" with no "precedence", they *must* be separate things.
... can anyone explain what exactly does associativity means?



Here is the executive-summary version:

- The C standards do not use an operator-precedence grammar, but
*you* can, if you prefer.

- If you *do* use an operator-precedence grammar, you will need
to remember which operators "have precedence" over the others, and
use that to resolve parse ambiguities. After using precedence,
if (and ONLY if) there are still more ambiguities, you will need
to remember the "associativity" of the remaining ambiguous
operators, and use that to resolve them.

- Precedence and associativity DO NOT control run-time order of
evaluation. They only affect the compile-time parse tree. The
parse tree will usually have some sort of "partial order" effect
on runtime code, but to get *guaranteed* runtime sequencing, you
have to use C''s "sequence points".
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22''N, 111°50.29''W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.


这篇关于什么样的运算符是(),[]?一元还是二元?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆