该代码的输出为125

#include<stdio.h>

int func(int a)
{
    static int num = 2;
    if(a==0) return 1;
    num++; 
    return num*func(--a);
}

int main()
{
    printf("%d", func(3));
}

而这段代码的输出为60

#include<stdio.h>

int func(int a)
{
    static int num = 2;
    if(a==0) return 1;
    return (++num)*func(--a);
}

int main()
{
    printf("%d", func(3));
}

在第一段代码中,我在return语句之前增加了num,在第二段代码中,我在return语句中预先增加了num.

推荐答案

在第二个程序的这一行:

return (++num)*func(--a);

num的值作为副作用而增加and,对func的函数调用也会修改num.

此表达式的单个操作数的求值为unsequenced,这意味着可以先求值num,也可以先调用func.

func的调用确实引入了一个序列点.因此,如果首先计算++num,则在实际调用func之前,应用递增num的副作用.另一方面,如果首先计算对func的调用,则在函数调用内部修改num,然后读取和更新num将看到更新的值.然而,不能保证其中一个会先发生.

所以这里没有未定义的行为,但是由于子表达式的未排序计算,结果是unspecified.

第一个程序有一个类似的问题,尽管在同一条语句中没有增加num:

return num*func(--a);

与之前一样,如果先计算num,则会看到当前值.如果先计算函数调用,则将读取更新后的值num.

要从程序中获得确定性行为,需要将静态变量的当前值复制到非静态变量,并使用该值乘以函数结果.

int func(int a)
{
    static int num = 2;
    if(a==0) return 1;
    int num_tmp = ++num;
    return num_tmp*func(--a);
}

C++相关问答推荐

如何在C中从函数返回指向数组的指针?

为什么GCC C23中的关键字FALSE不是整数常量表达式?

fwrite无法写入满(非常大)缓冲区

具有交换链获取和命令缓冲区提交的同步-危险-读后写错误

Make Node函数.S有什么问题吗?

在C语言中,是否可以使枚举数向后计数?

用C++实现余弦函数

无法在OpenGL上绘制三角形

S和查尔有什么不同[1]?

当内存来自Malloc时,将char*转换为另一个指针类型是否违反了严格的别名规则?

我可以创建适用于不同endian的 colored颜色 struct 吗?

Realloc():中止的下一个大小无效(核心转储)

生成一个半RNG,结果用C表示(无随机/随机)

浮点正零何时不全为零?

C程序printf在getchar while循环后不工作

令人困惑的返回和 scanf 问题相关

在列表中查找素数

在 C 中传递参数时出现整数溢出

clion.我无法理解 Clion 中发生的 scanf 错误

在 printf() 格式说明符中使用字段宽度变量