function return 改为直接写在printf语句中

function return changed as directly written in printf statement

#include <stdio.h>
#include <math.h>

int main() {
    printf("%d\n", pow(3546, 0));   
    return 0;
}

以上代码打印值0

虽然下面的代码打印值 1

#include <stdio.h>
#include <math.h>

int main() {
    int a  = pow(3546, 0);
    printf("%d\n", a);
    return 0;
}

为什么会这样?尽管它们是等价的。

this answer 中所述,printf 使用格式说明符知道要从堆栈中弹出什么(%dsizeof(int),在我的文件中是 4 个字节系统)。

(编辑: 正如 rici 在评论中指出的那样,它不能保证是堆栈(在 x86 上它在 CPU 大部分时间注册。标准从不讨论实现,这就是这个问题的全部内容。)

一个有趣的小事实:在我的 Windows 10 框中,它是 0 和 1。在我的 Xubuntu VBox 中,它是 1 和 -2132712864。因此,printf 仅弹出 4 个字节,而您机器的字节顺序破坏了结果。来自 pow(3) manual:

#include <math.h>

double pow(double x, double y);
float powf(float x, float y);
long double powl(long double x, long double y);

因此,为了在这两种情况下都获得正确的结果,请使用 correct printf format specifier:

double a = pow(3546, 0);

并且:

printf("%lf\n", pow(3546, 0));

如果您想了解更多关于 可变参数函数 (像 printf 这样的函数,它采用可变数量的参数),请先阅读 API manual page.

#include <stdarg.h>

void va_start(va_list ap, last);
type va_arg(va_list ap, type);
void va_end(va_list ap);
void va_copy(va_list dest, va_list src);

pow returns 类型 double 的结果,并且 %d 不是用于格式化它的正确转换说明符。 C 标准未定义由此产生的行为。

要打印 double,您可以使用 %g%f,以及其他选项:

printf("%g\n", pow(3456, 0));
printf("%f\n", pow(3456, 0));

int a = pow(3546,0);中,double值自动转换为int用于初始化inta,然后打印int%d 是正确的。

没有对等。后一个函数在打印前明确地将数字转换为 int,而前一个函数通过尝试使用错误的格式说明符打印浮点数而导致 UB——你很幸运得到 0,你可能得到了一个任意数字。

请打开编译器上的所有警告,它应该会抱怨对错误的数据类型使用了错误的格式。