这个表达式将如何在C中计算?

这个表达式将如何在C中计算?,c,printf,C,Printf,我不知道这个表达式在C中是如何计算的? 我对printf中表达式的求值有点困惑? 如果printf中的表达式从右向左求值,则表达式的求值应该在遇到(c>10)后停止,但它将“1”打印到输出屏幕 这不是C语言的确切语法,而是向我提出的一个问题 integer a = 50, b = 25, c = 0; printf( a > 45 || b > 50 && c > 10 ); 这将是未定义的行为。printf的第一个参数必须是格式字符串。很可能它会崩溃。节省您

我不知道这个表达式在C中是如何计算的? 我对printf中表达式的求值有点困惑?
如果printf中的表达式从右向左求值,则表达式的求值应该在遇到(c>10)后停止,但它将“1”打印到输出屏幕

这不是C语言的确切语法,而是向我提出的一个问题

integer a = 50, b = 25, c = 0;
printf( a > 45 || b > 50 && c > 10 );

这将是未定义的行为。printf的第一个参数必须是格式字符串。很可能它会崩溃。节省您的是“integer”不是一个类型,所以它不会编译

这将是未定义的行为。printf的第一个参数必须是格式字符串。很可能它会崩溃。节省您的是“integer”不是一个类型,所以它不会编译

这个表达式

a > 45 || b > 50 && c > 10
( a > 45 ) || ( b > 50 && c > 10 )
( b > 50 && c > 10 )
a > 45
b > 50 && c > 10
相当于表达式

a > 45 || b > 50 && c > 10
( a > 45 ) || ( b > 50 && c > 10 )
( b > 50 && c > 10 )
a > 45
b > 50 && c > 10
因此,如果此子表达式
(a>45)
的计算结果为true,则第二个子表达式将不会计算,结果等于1(int类型)

否则这个子表达式

a > 45 || b > 50 && c > 10
( a > 45 ) || ( b > 50 && c > 10 )
( b > 50 && c > 10 )
a > 45
b > 50 && c > 10
相当于

( b > 50 ) && ( c > 10 )
如果
(b>50)
的计算结果为false,则整个结果为false(C中为0),第二个子表达式将不计算。否则,结果为的值 子表达式
c>10
。如果
c>10
,则结果为int类型的对象,值为1;如果不是
(c>10)
,则结果值为0

如果变量的值与问题中显示的值相同

int a = 50, b = 25, c = 0;
然后是第一个子表达式

a > 45 || b > 50 && c > 10
( a > 45 ) || ( b > 50 && c > 10 )
( b > 50 && c > 10 )
a > 45
b > 50 && c > 10
计算结果为true,结果为int类型的1。第二个子表达式

a > 45 || b > 50 && c > 10
( a > 45 ) || ( b > 50 && c > 10 )
( b > 50 && c > 10 )
a > 45
b > 50 && c > 10
甚至不会评估

考虑下面的演示程序

#include <stdio.h>

int f( int x )
{
    printf( "f is called for %d\n", x );
    return x;
}

int main( void ) 
{
    int a = 50, b = 25, c = 0;

    f( f( a ) > 45 || f( b ) > 50 && f( c ) > 10 ); 

    return 0;
}
如您所见,计算表达式
f(a)>45
就足以得到与该表达式相等的结果

a > 45 || b > 50 && c > 10
( a > 45 ) || ( b > 50 && c > 10 )
( b > 50 && c > 10 )
a > 45
b > 50 && c > 10
相当于表达式

a > 45 || b > 50 && c > 10
( a > 45 ) || ( b > 50 && c > 10 )
( b > 50 && c > 10 )
a > 45
b > 50 && c > 10
因此,如果此子表达式
(a>45)
的计算结果为true,则第二个子表达式将不会计算,结果等于1(int类型)

否则这个子表达式

a > 45 || b > 50 && c > 10
( a > 45 ) || ( b > 50 && c > 10 )
( b > 50 && c > 10 )
a > 45
b > 50 && c > 10
相当于

( b > 50 ) && ( c > 10 )
如果
(b>50)
的计算结果为false,则整个结果为false(C中为0),第二个子表达式将不计算。否则,结果为的值 子表达式
c>10
。如果
c>10
,则结果为int类型的对象,值为1;如果不是
(c>10)
,则结果值为0

如果变量的值与问题中显示的值相同

int a = 50, b = 25, c = 0;
然后是第一个子表达式

a > 45 || b > 50 && c > 10
( a > 45 ) || ( b > 50 && c > 10 )
( b > 50 && c > 10 )
a > 45
b > 50 && c > 10
计算结果为true,结果为int类型的1。第二个子表达式

a > 45 || b > 50 && c > 10
( a > 45 ) || ( b > 50 && c > 10 )
( b > 50 && c > 10 )
a > 45
b > 50 && c > 10
甚至不会评估

考虑下面的演示程序

#include <stdio.h>

int f( int x )
{
    printf( "f is called for %d\n", x );
    return x;
}

int main( void ) 
{
    int a = 50, b = 25, c = 0;

    f( f( a ) > 45 || f( b ) > 50 && f( c ) > 10 ); 

    return 0;
}

如您所见,计算表达式
f(a)>45
就足以得到等于
1
的结果。表达式出现的上下文会影响它是否被计算,但不会影响其计算方式。较大表达式的子表达式的求值顺序由控制

在表达式中的运算符中,
的优先级最高,然后是
&&
,然后是
|
。所有人都从左到右关联。因此,表达式的计算方式与这样编写的表达式完全相同:

(a > 45) || ((b > 50) && (c > 10))
此外,
&&
|
操作员执行短路评估。这似乎是你的一个困惑点。短路计算意味着,如果
&&
|
操作的结果由左侧操作数的值确定,则不计算该操作的右侧操作数。这不影响是否或如何计算其他运算,除非短路运算的结果用作操作数


但是,在这种情况下,由于
|
从左到右关联,
a>45
首先计算,产生
1
(true)。因为这决定了
|
操作的结果,所以不会计算其右侧操作数。相对运算符优先级产生的右操作数是整个表达式的剩余数,如上图所示,因此不会对其求值。但是,即使对其求值,整个表达式的结果仍然是
1
,因为不管右侧子表达式是什么,左侧操作数的求值结果都是
1
。这就是为什么不需要对
|
的右侧求值。

表达式出现的上下文影响是否求值,但不影响如何求值。较大表达式的子表达式的求值顺序由控制

在表达式中的运算符中,
的优先级最高,然后是
&&
,然后是
|
。所有人都从左到右关联。因此,表达式的计算方式与这样编写的表达式完全相同:

(a > 45) || ((b > 50) && (c > 10))
此外,
&&
|
操作员执行短路评估。这似乎是你的一个困惑点。短路计算意味着,如果
&&
|
操作的结果由左侧操作数的值确定,则不计算该操作的右侧操作数。这不影响是否或如何计算其他运算,除非短路运算的结果用作操作数

但是,在这种情况下,由于
|
从左到右关联,
a>45
首先计算,产生
1
(true)。因为这决定了
|
操作的结果,所以不会计算其右侧操作数。相对运算符优先级产生的右操作数是整个表达式的剩余数,如上图所示,因此所有操作数