首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >这个表达式将如何在C中求值?

这个表达式将如何在C中求值?
EN

Stack Overflow用户
提问于 2017-01-14 01:40:47
回答 4查看 900关注 0票数 0

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

这不是C的确切语法,而是有人问我的问题。

代码语言:javascript
运行
复制
integer a = 50, b = 25, c = 0;
printf( a > 45 || b > 50 && c > 10 );
EN

回答 4

Stack Overflow用户

发布于 2017-01-14 01:55:55

此表达式

代码语言:javascript
运行
复制
a > 45 || b > 50 && c > 10

等同于表达式

代码语言:javascript
运行
复制
( a > 45 ) || ( b > 50 && c > 10 )

因此,如果此子表达式( a > 45 )的计算结果为true,那么第二个子表达式将不会计算,并且结果等于1(类型为int)。

否则,此子表达式

代码语言:javascript
运行
复制
( b > 50 && c > 10 )

等同于

代码语言:javascript
运行
复制
( b > 50 ) && ( c > 10 )

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

如果变量具有您的问题中所示的值

代码语言:javascript
运行
复制
int a = 50, b = 25, c = 0;

然后是第一个子表达式

代码语言:javascript
运行
复制
a > 45

计算结果为true,结果为int类型的1。第二个子表达式

代码语言:javascript
运行
复制
b > 50 && c > 10

甚至不会进行评估。

考虑下面的演示程序

代码语言:javascript
运行
复制
#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;
}

它的输出是

代码语言:javascript
运行
复制
f is called for 50
f is called for 1

正如您所看到的,为了得到与1相等的结果,计算表达式f( a ) > 45就足够了。

票数 2
EN

Stack Overflow用户

发布于 2017-01-14 01:44:31

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

票数 1
EN

Stack Overflow用户

发布于 2017-01-14 03:46:47

||&&运算符都强制从左到右求值。在计算右操作数之前,将完全计算左操作数(并应用所有副作用)。

此外,两个运算符都是短路的-根据左操作数的值,可能根本不会计算右操作数。

代码语言:javascript
运行
复制
a || b

如果a为true,则无论b的值如何,整个表达式都为true,因此不计算b

类似地,对于

代码语言:javascript
运行
复制
a && b

如果a为false,则无论b的值如何,整个表达式都为false,因此不计算b

&&的优先级高于||,因此

代码语言:javascript
运行
复制
a || b && c 

将被解析为

代码语言:javascript
运行
复制
a || (b && c)

代码语言:javascript
运行
复制
a && b || c 

将被解析为

代码语言:javascript
运行
复制
(a && b) || c  

所以..。

代码语言:javascript
运行
复制
a > 45 || b > 50 && c > 10

被解析为

代码语言:javascript
运行
复制
a > 45 || (b > 50 && c > 10 )

因为a == 50,所以a > 45是真的。因为a > 45||运算符的左操作数,所以无论右操作数是什么,整个表达式都是真的,所以根本不计算b > 50 && c > 10

表达式的结果为1 (true)。

不幸的是,printf期望它的第一个参数指向一个字符串(格式字符串),而1很可能不是您的平台上的有效地址,因此此代码的结果很可能是一个段错误。最简单的解决方法是编写

代码语言:javascript
运行
复制
printf( "%d\n", a > 45 || b > 50 && c > 10 );
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41640413

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档