评估报表

时间:2017-01-21 05:35:51

标签: c function pointers return printf

//prog1.c    
#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;
    }

我使用gccclang-3.5执行了该计划,并找到了输出= 16

我认为可能存在一些特定于实现的行为,如下面的代码

//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

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

我可能不知道某种undefined behaviourunspecified behaviour。请解释。 感谢

2 个答案:

答案 0 :(得分:2)

正如评论和近似重复的问题(Is this undefined behaviour in C? If not, predict the output logically.)所述,这两个程序的结果并未完全由C标准定义 - 它们产生'未指明的行为',因为这些术语的评估顺序在第一个return语句中,第二个printf()调用不是由语言指定的,而是编译器的一时兴起。 (请注意,它是'未指定的行为',而不是正式'未定义的行为' - 请参阅注释中的讨论。它也不是'实现定义'行为;不需要实现来记录它的作用。)

这意味着任何实现给出的结果都是问题条款中的“特定于实现”。不同的实现可能合法地产生不同的答案。

第一个项目是:

#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;
}

有问题的部分是return (*a + f(a,b,c) + *b);,因为可以在递归函数调用之前或之后评估*af()修改ab的值因此,评估的顺序很重要。不同的编译器可以合法地产生不同的结果。相同的编译器可以在不同的时间,或在不同的优化标志下或根据其选择产生不同的结果。 *a*b都可以在调用之前或者在调用之后进行评估,或者可以在之前和之后评估其中任何一个 - 并且只列出4个合理的替代方案。

第二个程序是:

#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;
}

问题是标准未指定af(&a, &b, &c)b评估printf()调用的顺序,您会得到不同的结果取决于编译器选择的顺序。你证明了GCC和Clang产生了不同的结果 - 根据标准,这些结果都是可以接受的,其他很多都是可以接受的。

答案 1 :(得分:0)

  

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

return声明没有任何问题,只是如果您对f c的原始电话是否定的,那么递归通话将会无穷无尽。

您的函数f的目的尚不清楚 - 但终止条件应更好地写为:

if(c <= 0) return 1;
相关问题