精华内容
下载资源
问答
  • printf输出表达式的时候,运算顺序是从右到左进行运算。

    printf输出表达式的时候,运算顺序是从右到左进行运算。

    展开全文
  • 操作符(运算符)的优先级和结合性并不决定表达式的求值顺序,只是用于进行语法分析,决定语法树的生成。3 + 4 * 5,可以解析成(3 + 4) * 5 或者 3 + (4 * 5),因为乘法优先级高于加法,所以会选择第二种解析方法。3...

     

    操作符(运算符)的优先级和结合性并不决定表达式的求值顺序,只是用于进行语法分析,决定语法树的生成。

    3 + 4 * 5,可以解析成(3 + 4) * 5 或者 3 + (4 * 5),因为乘法优先级高于加法,所以会选择第二种解析方法。
    3 + 4 + 5,可以解析成(3 + 4) + 5 或者 3 + (4 + 5),因为加法是自左向右结合,所以会选择第一种解析方法。

    解析成3 + (4 * 5)后,对这个表达式求值,“+”操作符有两个操作数,左操作数为 3,右操作数为 4 * 5,那么是先对左操作数 3 求值呢,还是先对右操作数 4 * 5 求值呢?答案是未指定的,由编译器决定。

    标准并没有指定“+”操作符的求值顺序,标准只指定了“,”、“&&”、“||”、“?:”这四种操作符的求值顺序是自左向右,其余的操作符的求值顺序都是未指定的。

    因此 3 + (4 * 5),并非先算4 * 5,然后算 3 ,而是由编译器自己决定,求值顺序是未指定的。同理:
    int i = f() + g(); // 并非一定先执行f(),后执行g(),而是由编译器决定

    所以 ++i + ++i + ++i; 会被解析成 ((++i) + (++i)) + (++i);

    这个表达式是一个典型的未定义行为,因为 ++i 有两个作用,第一:对i加1;第二:返回一个值(或者应该说返回一个引用)。这里的对i加1属于副作用(side effect),而副作用什么时候生效呢?标准只规定了在跨越一个序列点的时候,序列点之前的副作用必须全部完成,此外就没有硬性要求了。
     前置++
    {
       this -> m_value += 1 ;
       return   *   this ;
     }
     后置++
    {
       Int old  =   * this ;
       ++ ( * this );
       return  old;
    }

    序列点是一个时间点(在整个表达式全部计算完毕之后或在||、&&、? : 或逗号运算符处, 或在函数调用之前), 此刻尘埃落定, 所有的副作用都已确保结束。
    C中为什么要搞这么一个复杂的序列点机制,让许多看起来很简单的代码变成未定义呢?为什么不详细的定义求值顺序呢?因为C是极端追求效率的语言,它诞生的年代计算机硬件都慢的可怜且贵的离谱,没有规定求值顺序就是要给编译器更大的余地去做优化。

    而((++i) + (++i)) + (++i); 这个表达式的序列点就是语句的结束之处,也就是";"所在之处,在此之前副作用何时生效(也就是何时给i加1)完全由编译器决定,编译器可以任意选择,比如:

    a, 先计算左边的子表达式((++i) + (++i)):
      先对左边的i加1(此时i == 6),再对右边的i加1(i == 7),然后再对左边的表达式求值,得到7,对右边的表达式求值,得到7,对子表达式求值,得到 7 + 7 = 14;
    b,再计算右边的子表达式 (++i)
      因为此时i == 7,所以++i == 8,子表达式值为8.
    c, 计算整个表达式的值:14 + 8 = 22;

    编译器还可以选择先对所有的3个i都加1(完成副作用),然后再分别求值,得到8 + 8 + 8 = 24.

    当然也可以挨个加1、求值,得到6 + 7 + 8 = 21.

    只要满足在((++i) + (++i)) + (++i);结束之后,i == 8(副作用完成)就行了,具体过程标准并没有指定,由编译器自己决定。

    至于说这种行为属于未定义,是因为c标准中有这么一条:

    在上一个和下一个序列点之间, 一个对象所保存的值至多只能被表达式的计算修改一次。而且前一个值只能用于决定将要保存的值。

    而这里的i显然在一条语句中被修改了多次。
    对于 x=5,y=(++x)+(++x)+(++x),y=?
    这是和编译器有关的具体如下,仅供参考:(只列举bc和vc的情况,其他的自己找规律)1、对于赋值计算,如: i = 5; k = (++i) + (i++) + (++i) + (++i);

      (1) BC下:  

      总体原则: 先计算所有的前置++或--,再计算表达式的值,最后计算后置++或--。

      a. 先计算所有i的前置++或--,得出i的值为8;

      b. 再计算k = 8 + 8 + 8 + 8 = 32;

      c. 最后计算i的后置++或--,得i的值为9。

      (2) VC下:

      总体原则:先计算前两项的前置++或--,再从第三项开始从左到右一项一项的计算,最后计算所

      有的后置++或--。

      a. 先计算前两项i的前置++或--,i为6,前两项之和为:6 + 6 = 12;

      b. 再计算第三项++i,i的值为7,前三项之和为:6 + 6 + 7 = 19;

      c. 再计算第四项++i,i的值为8,前四项之和为:k = 6 + 6 + 7 + 8 = 27;

      d. 最后计算i的后置++或--,得i的值为9。

      2、对于直接输出表达式的值的计算,如: i = 5; printf("%d",(++i)+(i++)+(++i)+(++i));

      (1) BC下:

      总体原则:从左到右一项一项的计算,后置++或--在中间计算过程中计算。

      a. 计算++i,得值为6,i的值为6;

      b. 计算i++,得值为6,i的值为7;

      c. 计算++i,得值为8,i的值为8;

      d. 计算++i,得值为9,i的值为9;

      所以表达式的值为:6 + 6 + 8 + 9 = 29。

      (2) VC下:

      计算方法同赋值计算,表达式的值为:27。
    另附vc++6.0:
    int x=3,y=5,z;
    // z = x*(y++)+y; // z = 20
    // z = x+(++x)*y; // z = 24
    // z = x+3+(++x)*y; // z = 27
    // z = x+x+(++x)*y; // z = 26
    // z = (++x)+x*y; // z = 24
    // z = x*(y++)+(++x)*y; // z = 30
    // z = (++x)+(++x)+(++x); // z = 16
    // z = (x++)+(x++)+(x++); // z = 9
    总结:有副作用的表达式与编译器相关,应尽量少用。如面笔试题出现此类问题,可大胆填上:不是我不会,是题没答案;
    参考:

    细说C/C++中的表达式运算顺序与求值顺序

     

    展开全文
  • c语言表达式运算顺序

    千次阅读 2017-07-18 20:54:16
    C语言中表达式运算顺序由优先级和结合性决定。 1.先按运算符优先级运算。2.如果相邻若干个运算符优先级相同,则按结合方向来运算。 比如:1+2-3*4的运算为:有优先级先做*运算,3*4得到12;表达式为1+2-12,...

    C语言中表达式的运算顺序由优先级和结合性决定

    1.先按运算符优先级运算。2.如果相邻若干个运算符优先级相同,则按结合方向来运算。

    比如:1+2-3*4的运算为:有优先级先做*运算,3*4得到12;表达式为1+2-12,算数运算符为从左到右的结合方向,即先做+运算,再做-运算。

    下面是c语言运算符的优先级和结合性:

    优先级

    运算符

    名称或含义

    使用形式

    结合方向

    说明

    1

    []

    数组下标

    数组名[常量表达式]

    左到右

    --

    ()

    圆括号

    (表达式)/函数名(形参表)

    --

    .

    成员选择(对象)

    对象.成员名

    --

    ->

    成员选择(指针)

    对象指针->成员名

    --

     

    2

    -

    负号运算符

    -表达式

    右到左

    单目运算符

    ~

    按位取反运算符

    ~表达式

    ++

    自增运算符

    ++变量名/变量名++

    --

    自减运算符

    --变量名/变量名--

    *

    取值运算符

    *指针变量

    &

    取地址运算符

    &变量名

    !

    逻辑非运算符

    !表达式

    (类型)

    强制类型转换

    (数据类型)表达式

    --

    sizeof

    长度运算符

    sizeof(表达式)

    --

     

    3

    /

    表达式/表达式

    左到右

    双目运算符

    *

    表达式*表达式

    %

    余数(取模)

    整型表达式%整型表达式

    4

    +

    表达式+表达式

    左到右

    双目运算符

    -

    表达式-表达式

    5

    << 

    左移

    变量<<表达式

    左到右

    双目运算符

    >> 

    右移

    变量>>表达式

     

    6

    大于

    表达式>表达式

    左到右

    双目运算符

    >=

    大于等于

    表达式>=表达式

    小于

    表达式<表达式

    <=

    小于等于

    表达式<=表达式

    7

    ==

    等于

    表达式==表达式

    左到右

    双目运算符

    =

    不等于

    表达式!= 表达式

     

    8

    &

    按位与

    表达式&表达式

    左到右

    双目运算符

    9

    ^

    按位异或

    表达式^表达式

    左到右

    双目运算符

    10

    |

    按位或

    表达式|表达式

    左到右

    双目运算符

    11

    &&

    逻辑与

    表达式&&表达式

    左到右

    双目运算符

    12

    ||

    逻辑或

    表达式||表达式

    左到右

    双目运算符

     

    13

    ?:

    条件运算符

    表达式1?

    表达式2: 表达式3

    右到左

    三目运算符

     

    14

    =

    赋值运算符

    变量=表达式

    右到左

    --

    /=

    除后赋值

    变量/=表达式

    --

    *=

    乘后赋值

    变量*=表达式

    --

    %=

    取模后赋值

    变量%=表达式

    --

    +=

    加后赋值

    变量+=表达式

    --

    -=

    减后赋值

    变量-=表达式

    --

    <<=

    左移后赋值

    变量<<=表达式

    --

    >>=

    右移后赋值

    变量>>=表达式

    --

    &=

    按位与后赋值

    变量&=表达式

    --

    ^=

    按位异或后赋值

    变量^=表达式

    --

    |=

    按位或后赋值

    变量|=表达式

    --

     

    15

    逗号运算符

    表达式,表达式,…

    左到右

    --


    展开全文
  • c语言中表达式运算顺序

    万次阅读 多人点赞 2016-10-25 20:31:36
    c语言中表达式运算顺序由优先级和结合性决定。 1.先按运算符优先级运算。2.如果相邻若干个运算符优先级相同,则按结合方向来运算。 比如:1+2-3*4的运算为:有优先级先做*运算,3*4得到12;表达式为1+2-12,算数...

    c语言中表达式的运算顺序由优先级和结合性决定

    1.先按运算符优先级运算。2.如果相邻若干个运算符优先级相同,则按结合方向来运算。

    比如:1+2-3*4的运算为:有优先级先做*运算,3*4得到12;表达式为1+2-12,算数运算符为从左到右的结合方向,即先做+运算,再做-运算。

    下面是c语言运算符的优先级和结合性:

    优先级

    运算符

    名称或含义

    使用形式

    结合方向

    说明

    1

    []

    数组下标

    数组名[常量表达式]

    左到右

    --

    ()

    圆括号

    (表达式)/函数名(形参表)

    --

    .

    成员选择(对象)

    对象.成员名

    --

    ->

    成员选择(指针)

    对象指针->成员名

    --

     

    2

    -

    负号运算符

    -表达式

    右到左

    单目运算符

    ~

    按位取反运算符

    ~表达式

    ++

    自增运算符

    ++变量名/变量名++

    --

    自减运算符

    --变量名/变量名--

    *

    取值运算符

    *指针变量

    &

    取地址运算符

    &变量名

    !

    逻辑非运算符

    !表达式

    (类型)

    强制类型转换

    (数据类型)表达式

    --

    sizeof

    长度运算符

    sizeof(表达式)

    --

     

    3

    /

    表达式/表达式

    左到右

    双目运算符

    *

    表达式*表达式

    %

    余数(取模)

    整型表达式%整型表达式

    4

    +

    表达式+表达式

    左到右

    双目运算符

    -

    表达式-表达式

    5

    << 

    左移

    变量<<表达式

    左到右

    双目运算符

    >> 

    右移

    变量>>表达式

     

    6

    大于

    表达式>表达式

    左到右

    双目运算符

    >=

    大于等于

    表达式>=表达式

    小于

    表达式<表达式

    <=

    小于等于

    表达式<=表达式

    7

    ==

    等于

    表达式==表达式

    左到右

    双目运算符

    =

    不等于

    表达式!= 表达式

     

    8

    &

    按位与

    表达式&表达式

    左到右

    双目运算符

    9

    ^

    按位异或

    表达式^表达式

    左到右

    双目运算符

    10

    |

    按位或

    表达式|表达式

    左到右

    双目运算符

    11

    &&

    逻辑与

    表达式&&表达式

    左到右

    双目运算符

    12

    ||

    逻辑或

    表达式||表达式

    左到右

    双目运算符

     

    13

    ?:

    条件运算符

    表达式1?

    表达式2: 表达式3

    右到左

    三目运算符

     

    14

    =

    赋值运算符

    变量=表达式

    右到左

    --

    /=

    除后赋值

    变量/=表达式

    --

    *=

    乘后赋值

    变量*=表达式

    --

    %=

    取模后赋值

    变量%=表达式

    --

    +=

    加后赋值

    变量+=表达式

    --

    -=

    减后赋值

    变量-=表达式

    --

    <<=

    左移后赋值

    变量<<=表达式

    --

    >>=

    右移后赋值

    变量>>=表达式

    --

    &=

    按位与后赋值

    变量&=表达式

    --

    ^=

    按位异或后赋值

    变量^=表达式

    --

    |=

    按位或后赋值

    变量|=表达式

    --

     

    15

    逗号运算符

    表达式,表达式,…

    左到右

    --


    展开全文
  • python中表达式运算顺序

    千次阅读 2018-04-20 17:25:04
    True or False and False 的结果是 True,原因应该是and的优先级高于or,因为False and False or True的结果也是True,说明实际的运算顺序是 True or (False and False)和(False and False) or True 24&lt;=...
  • 后缀表达式是计算机容易运算表达式,运算符在运算数后面,从左到右进行运算,无需考虑优先级,运算呈线性结构. 先举个简单的转换例子 2+9/3-5 (前缀)-> 2 9 3 / + 5 - (后缀) 先进行乘除再进行加减 运算规律,.....
  • 表达式运算

    2015-12-29 11:51:13
    通常我们所看到的算术表达式,运算符总是在两个操作数中间(除),如(A+B)*C,这样的表达式叫做中缀表达式。这种表达式不同的运算符优先级不同,而且通常含有括号,计算机很难理解这种表达式。在编译系统中,要把人...
  • //只有关键的运算部分有代码,只要实例化,栈是根据教科书上的写的,如果要用STL可以修改下就可以用,这个是中序表达式运算,由于按照老师要求,可能写的有点繁琐.#include #include"SeqStack.h" //教科书上的顺序数组栈...
  • 表达式: 就是有一个或多个操作数或0个以上运算符组成的序列就叫做表达式表达式里面可以包含文本值,方法调用,运算符,操作数甚至是一些简单名称。 语句: 执行流或控制流。是以分号结尾的单行代码,即用来实现...
  • 条件表达式运算规则

    2020-12-05 19:42:27
    运算规则:首先计算表达式1的值, 若表达式1的值为真(非零) 则只计算表达式2,并将其结果作为整个表达式的值; 否则,只计算表达式3,并将其结果作为整个表达式的值。 #include<iostream> using namespace std;...
  • 栈的应用 - 表达式运算

    千次阅读 2018-11-05 10:42:35
    中缀表达式:通常将运算符写在运算量之间,例如a+b,这种表示法称为中缀表示法。 后缀表达式:后缀表示法又称逆波兰表示法,它是波兰逻辑学家卢卡西维奇发明的一种表示表达式的方法。这种表示法把运算量写在前面,...
  • JavaScript的表达式运算有哪些?JavaScript的位运算是怎么样的?等值比较是怎么判断的?运算符优先级具体是怎样的?本文将为您一一道来。
  • C++运算表达式求值顺序

    千次阅读 2019-03-12 21:35:50
    优先级虽然规定了运算对象的组合方式,但是没有说明运算对象按照什么顺序求值。例如: int i=f1()*f2();//我们不知道先求f1还是先求f2,倘若f1和f2指向并修改了同一对象,则会引发错误。 例如:int i=0;cout&...
  • #include void main() { int a=1, b=2, c=3; cout(a); cout(a>b ? b-- : ++a); cout(c+=a>b ? ++a : ++b);...给出这一段代码,第一行和第二行输出为1和2我能理解,但是为什么第三行输出为6?...
  • c语言表达式计算顺序

    2020-03-28 11:18:57
    C 语言中,任何表达式的子表达式求值顺序是未指定的,编译器可能以任意顺序对这个表达式求值,而且同一表达式再度求值时可能会采用另一种顺序。 C 中有运算符从左到右 / 从右到左结合性,但没有从左到右 / 从右到左...
  • C语言关系运算符及其运算顺序

    千次阅读 2019-09-18 00:07:17
    C语言关系运算符及其运算顺序 | < | 小于 | | <= | 小于或者等于 | | > | 大于 | | >= | 大于或者等于 | | == | 等于 | | != | 不等于 | 前四种关系运算符优先级别相同(< ...
  • c++ 表达式执行顺序

    千次阅读 2016-05-12 23:38:39
    在c++中,任何表达式(函数参数,子表达式)中的运算元的计算顺序都是不固定的。对于相同的表达式,编译器可能生成不同计算顺序的指令。 同时,在c++中,没有像从左到右,或从右到左的计算规则(刚接触c++的人,...
  • 关系表达式

    千次阅读 2016-11-05 21:56:46
    关系表达式关系表达式总是返回一个布尔值。 相等和不等运算符相等运算符(== 和 === )用于比较两个值是否相等。允许任何类型的操作数。 对象的比较是引用的比较,而不是值的比较。一个对象只和其本身是相等的,和...
  • 中缀表达式转换为后缀表达式、后缀表达式的计算
  • 关于表达式 运算溢出等问题

    千次阅读 2007-05-07 11:16:00
    ALU的构造决定了它只能进行二元运算。那么一个复杂的表达式如何处理?只好按优先级和结合性一点一点地做。这就产生了“中间结果”,暂存在哪里?只有内存。内存里会有一些无名的、占一定空间的、短命的变量存在,...
  • 可以计算数学表达式的小软件。包括几十种数学函数。直接输入无需考虑运算顺序
  • 堆栈的应用:四则表达式运算

    千次阅读 2014-04-29 16:08:34
    哈哈,斯则表示的运算,非常经典的一个题目。哈哈,大家可以参考下,不过代码可能还包含错误,不过主线应该没有错误...
  • javascript变量计算顺序 javascript总是严格的按照从左到右计算表达式。 如表达式w=x+y*z;, 先计算子表达式w,然后计算x,y和z, 然后y和z的值相乘,再加上x的值。 如果表达式var a = 1;b=(a++)+a;, 1. 计算b, 2. ...
  • 对于基本的算术表达式,以字符序列的形式从终端进行输入,要求语法正确的,不含变量,按照算术运算优先级顺序,实现基本算术表达式运算过程。 (1) 输入:输入一个算术表达式,以#结束 (2) 输出:输出数据栈...
  • } 03:计算(a+b)*c的值 总时间限制: 1000ms 内存限制: 65536kB 描述 给定3个整数a、b、c,计算表达式(a+b)/c的值,/是整除运算。 输入 输入仅一行,包括三个整数a、b、c, 数与数之间以一个空格分开。(-10,000...
  • 1.3编程基础之算术表达式顺序执行 的全部题解,有需要的同学请自行学习。有任何错漏或者疑问,请留言。谢谢~~~ 1、题目分析 2、代码截图 1.3编程基础之算术表达式顺序执行 编号 题目 相对难度1-5 ...
  • @Test public void fun2(){ Studuent s=null;...三元表达式执行的顺序:先比较左边获得布尔值,根据布尔值选择执行语句。如上s.getAge()会等待布尔值为false时才执行,不会出现空指针报错; @Test ...
  • if中逻辑运算符表达式运行顺序

    千次阅读 2014-08-10 23:25:37
    在编程中注意一些小细节往往会给我们编程带来很大的效率提升,同时也能避免一些低级错误,如果在if的逻辑运算符中各个表达式的执行顺序。   在if运算符表达式中,&&和||有“短路”现象。  在if(a==b && c =...
  • 因此,整个逻辑表达式靠后的部分有可能不会被运算。——《Java编程思想》 这一点特性对bool逻辑判断时很有用,看以下代码: public static boolean func1() { System.out.println(&quot;1&quot;); r....
  • C中参数压栈及表达式计算顺序

    千次阅读 2012-08-11 12:09:34
    但参数中有表达式时,计算顺序则是按“尽可能快”的原则来安排的。 #include int main() { int i = 1; printf("%d,%d,%d\n",i++,i++,i++); //3,2,1 i=4 printf("%d,%d,%d\n",i++,i++,i); /

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 158,862
精华内容 63,544
关键字:

关系表达式的运算顺序