首页 > 解决方案 > 如何确定逻辑表达式中函数调用的顺序

问题描述

我对函数调用的顺序感到困惑。我已经列出了我尝试过的命令,但仍然得到错误的答案。

!!!答案是“i 和 j 值未定义”。

根据运算符优先级:</h3>
  1. 如果编译器从左到右计算值
   int i = (1+0) || (ignored);  //1  
   int j = (1) || (ignored);   //1 
  1. 如果编译器首先计算'+'之后的值,则从左到右计算其他值
   int i = (0+0) || (1);  //1  
   int j = (2) || (ignored);   //1 

我仍然得到错误的结论。

所以我尝试不遵守运算符优先级

  1. 如果编译器首先从右到左计算值
   int i = (1+1) || (0);  //1
   int j = (ignored) || (2+2);  //1
  1. 如果编译器只首先计算'+'之前的值,则从右到左计算其他值
   int i = (0+1) || (0);  //1  
   int j = (ignored) || (1+2);    //1

我仍然得到错误的结论。

我再次猜测编译器可能不会忽略 || 之后的表达式 即使左边是真的

  1. 如果编译器从左到右计算值
   int i = (1+0) || (1);    //1
   int j = (2) || (2+3);    //1
  1. 如果编译器首先计算'+'之后的值,则从左到右计算其他值
   int i = (0+0) || (1);    //1
   int j = (2) || (3+3);    //1
  1. 如果编译器首先从右到左计算值
   int i = (1+1) || (0);  //1
   int j = (3) || (2+2);  //1
  1. 如果编译器只首先计算'+'之前的值,则从右到左计算其他值
   int i = (0+1) || (0);  //1
   int j = (3) || (1+2);  //1

我仍然得到错误的结论。

#include<stdio.h>
int x = 0;
int f(){
  if(x == 0) return x + 1;
  else return x - 1;
}
int g(){
  return x++;
}
int main(){
  int i = (f() + g()) || g();
  int j = g() || (f() + g());
}

不管顺序如何,除了 i=1 和 j 的值是 1 之外,我的
答案是 i 和 j 的值是未定义的。
我想知道哪种情况会导致另一个输出......
原谅我的愚蠢......

标签: c

解决方案


我们来分析一下i。请注意,仅当左侧参数为 0 时才计算||第二个参数。

i即使未指定获得此结果的方法,也始终为 1 。

这里没有未定义的行为。(正式地说,这是因为函数调用是一个有序的步骤。)

该语言没有指定在左侧评估中调用f()和调用的顺序。g()这留给实施。正式地,它甚至没有定义实现,因为不需要实现来记录行为。如果f()首先调用,则 的值f() + g()非零。如果g()首先被调用f() + g(),则为零,所以g()再次被调用,这也是非零的,因为x此时为 1。

j||由于仅评估的左侧,因此以 1 的形式退出。

一个更有趣的变体是

int f(){
  if(x == 0) return ++x;
  else return --x;
}

实际上不同的实现可能会为ior返回 0 或 1 j


推荐阅读