gpt4 book ai didi

c - 这是 C 中的未定义行为吗?如果不能逻辑地预测输出

转载 作者:太空狗 更新时间:2023-10-29 16:22:50 25 4
gpt4 key购买 nike

代码 1

#include <stdio.h>
int f(int *a, int b)
{
b = b - 1;
if(b == 0) return 1;
else {
*a = *a+1;

return *a + f(a, b);
}
}

int main() {
int X = 5;
printf("%d\n",f(&X, X));
}

考虑这个 C 代码。这里的问题是预测输出。从逻辑上讲,我得到 31 作为输出。 ( Output on machine )

当我将返回语句更改为

return f(a, b) + *a;

我逻辑上得到 37。(Output on machine)

我的一个 friend 说在计算返回语句时

return *a + f(a, b);

我们计算 a while going depth of the tree 的值,即 *a 首先计算然后 f(a, b) 被调用,而在

return f(a,b) + *a;

返回时解析,即先计算f(a, b),然后调用*a

通过这种方法,我尝试自己预测以下代码的输出:

代码 2

#include <stdio.h>
int foo(int n)
{
static int r;
if(n <= 1)
return 1;

r = n + r;
return r + foo(n - 2);
}

int main () {
printf("value : %d",foo(5));
}

对于 return(r+foo(n-2));

enter image description here

我得到 14 作为逻辑输出 ( Output on machine )

对于 return(foo(n-2)+r);

enter image description here

我得到 17 作为输出。 ( Output on machine )

但是,当我在我的系统上运行代码时,两种情况下我都得到 17。

我的问题:

  • 我 friend 给出的方法是否正确?
  • 如果是这样,为什么我在机器上运行时在代码 2 中得到相同的输出?
  • 如果不是,解释代码 1代码 2 的正确方法是什么?
  • 是否有任何未定义的行为,因为 C 不支持引用传递?由于它在 Code 1 中使用,因此可以使用指针来实现吗?

简而言之,我只是想知道在上述 4 种情况下预测输出的正确方法。

最佳答案

代码1

对于 代码 1,因为 return *a + f(a, b); 中项的求值顺序(以及 return f( a, b) + *a;) 未由标准指定并且函数修改了 a 指向的值,您的代码具有未指定的行为并且可能有各种答案。

正如您从评论中的愤怒中看出的那样,术语“未定义行为”、“未指定行为”等在 C 标准中具有技术含义,而该答案的早期版本在本应使用的地方误用了“未定义行为”使用了“未指定”。

问题的标题是“这是 C 中的未定义行为吗?”,答案是“否;这是未指定的行为,而不是未定义的行为”。

代码 2 — 修订版

对于固定的 Code 2,该函数也有未指定的行为:静态变量 r 的值被递归调用改变,因此求值顺序改变可能会改变结果。

代码 2 — 修订前

对于代码 2,如最初用 int f(static int n) { … } 所示,代码不(或至少不应该)编译.函数参数定义中唯一允许的存储类是 register,因此 static 的存在应该会给您带来编译错误。

ISO/IEC 9899:2011 §6.7.6.3 Function declarators (including prototypes) ¶2 The only storage-class specifier that shall occur in a parameter declaration is register.

在 macOS Sierra 10.12.2 上使用 GCC 6.3.0 编译,像这样(注意,没有额外的警告请求):

$ gcc -O ub17.c -o ub17
ub17.c:3:27: error: storage class specified for parameter ‘n’
int foo(static int n)
^

没有;如图所示,它根本无法编译 — 至少,对于使用现代版本的 GCC 的我来说是这样。

但是,假设它是固定的,该函数也有 undefined 未指定的行为:静态变量 r 的值被递归调用更改,因此更改为评估顺序可能会改变结果。

关于c - 这是 C 中的未定义行为吗?如果不能逻辑地预测输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41775973/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com