C 返回语句中的求值

C 返回语句中的求值,c,function,pointers,return,printf,C,Function,Pointers,Return,Printf,在prog1.c中,在return语句中是否存在任何特定于实现的行为?如果不是,如何评估 我可能不知道某种未定义的行为或,未指定的行为。请解释一下。 谢谢 在prog1.c中,return语句中是否有任何特定于实现的行为?如果不是,如何评估 return语句没有任何错误,只是如果使用c对f的原始调用是否定的,则递归调用将是无止境的 函数的用途不清楚,但终止条件最好写为: //prog2.c #include <stdio.h> int f(int *x,int *y,int *z)

prog1.c
中,在
return
语句中是否存在任何特定于实现的行为?如果不是,如何评估

我可能不知道某种
未定义的行为
或,
未指定的行为
。请解释一下。 谢谢

在prog1.c中,return语句中是否有任何特定于实现的行为?如果不是,如何评估

return
语句没有任何错误,只是如果使用
c
f
的原始调用是否定的,则递归调用将是无止境的

函数的用途不清楚,但终止条件最好写为:

//prog2.c
#include <stdio.h>
int f(int *x,int *y,int *z) {
  *x = *x + 1;
  *y = *y + 1;
  *z = *z + 1;
  return 0;
}
int main() {
  int a=0,b=0,c=0;
  printf("%d %d %d\n",a,f(&a,&b,&c),b);;
  return 0;
}
// gcc output : 1 0 0
// clang-3.5 :  0 0 1

if(c如注释和几乎重复的问题()中所述,这两个程序的结果未完全由c标准定义-它们产生“未指定行为”,因为
返回第一个和
printf()语句中术语的评估顺序
第二个调用不是由语言指定的,是编译器一时兴起的。(请注意,它是“未指定的行为”,而不是形式上的“未定义的行为”-参见注释中的讨论。它也不是“实现定义的”行为;实现不需要记录它所做的事情。)

这意味着任何实现给出的结果在问题方面都是“特定于实现的”。不同的实现可能会合理地产生不同的答案

第一个方案是:

if(c <= 0) return 1;
#include <stdio.h>

int f(int *a,int *b,int c) {
  if(c == 0) return 1;
  else {
    *a = *a + 1;
    *b = *b - 1;
     c =  c - 1;
     return (*a + f(a,b,c) + *b);
  }
}

int main() {
  int a = 3,b = 3,c = 3;
  printf("%d\n",f(&a,&b,c));
  return 0;
}

问题是对调用
printf()的
a
f(&a,&b,&c)
b
进行求值的顺序
不是标准指定的,根据编译器选择的顺序,您会得到不同的结果。您表明GCC和Clang会产生不同的结果-根据标准,这两种结果都是可以接受的,其他很多结果也是可以接受的。

如果(c)目的是跟踪
递归
,并在假设
f()
c>0
终止的情况下查找输出。感谢您的回答和澄清。@artmSee和(如果您是10K用户)-现在已删除。这两个程序都依赖于表达式项的求值顺序,而该顺序不受C标准的约束。在第二个示例中,GCC和Clang的输出都是可以接受的;它们甚至可以相当容易地解释。但是,您不能依赖于得到任何一个结果,甚至不能依赖于得到其中一个结果wo结果(也可能有其他结果)。您得到了错误的答案,并且接受了错误的答案。@JonathanLeffler这里有未定义的行为,对吗?@pC_u;是的。这与您提出的问题和a非常相似。这是家庭作业还是什么?3个类似的问题背靠背!没有未定义的行为,函数调用前后都有一个序列点。这是不具体的确定行为。我建议你自己确定它不是未定义的,然后相应地更新答案。这是一个重要的问题,因为UB可以发射导弹等,而这个程序必须从a输出一个数字(可能很大)有限集possibilities@M.M;标准说:如果一个表达式的子表达式有多个允许的顺序,那么如果在任何顺序中出现这种未排序的副作用,则行为是未定义的。这使得语句
返回(*a+f(a,b,c)+*b)
未定义的行为。@M.M:我现在不做这件事-这里是睡觉时间。请参阅《标准》中关于“优秀”和“密切相关的问题”的引语。这些引语包括一些问题的术语“未定义的行为”。@haccks请参阅“未排序的副作用”在你的报价中。OP的代码中没有未排序的副作用,函数是按顺序排序的
#include <stdio.h>

int f(int *a,int *b,int c) {
  if(c == 0) return 1;
  else {
    *a = *a + 1;
    *b = *b - 1;
     c =  c - 1;
     return (*a + f(a,b,c) + *b);
  }
}

int main() {
  int a = 3,b = 3,c = 3;
  printf("%d\n",f(&a,&b,c));
  return 0;
}
#include <stdio.h>
int f(int *x,int *y,int *z) {
  *x = *x + 1;
  *y = *y + 1;
  *z = *z + 1;
  return 0;
}
int main() {
  int a=0,b=0,c=0;
  printf("%d %d %d\n",a,f(&a,&b,&c),b);;
  return 0;
}