据我所知,不纯函数是那些在使用相同参数调用时并不总是返回相同值的函数(我必须遗漏一些东西,或者可能是错误的,如果我是,请纠正我)。
那么为什么被printf()
认为是不纯函数呢?
据我所知,不纯函数是那些在使用相同参数调用时并不总是返回相同值的函数(我必须遗漏一些东西,或者可能是错误的,如果我是,请纠正我)。
那么为什么被printf()
认为是不纯函数呢?
“纯”功能也没有副作用。
换句话说,无论你调用多少次,一个纯函数只会影响它的输出。
例如,foo
is impure,即使它返回零:
int x;
int foo() { x++; return 0; }
int bar() { return x; }
如果foo
是纯的,调用它不会影响bar()
.
printf
是不纯的,因为它的结果有“副作用”——具体来说,它会在屏幕上(或文件等)打印一些东西。
如果它是纯粹的,那么你可以调用它十亿次,并确保不会发生任何不好的事情。
但是如果你真的调用printf
了一百万次,对用户来说肯定会有所不同——它会填满他的屏幕(或磁盘空间,或其他任何东西)。很明显,它不是纯粹的。
此外:如果您的输出被重定向为您自己的输入(有点没用,但仍然如此),那么调用printf
会影响您从getchar
. :) 所以它也可以直接观察到。
成为纯函数有两个部分。首先,正如您所说,该函数必须始终为相同的输入参数返回相同的值。第二个不满足的标准printf
是函数不能有像 I/O 或对象突变这样的副作用。
简单地说,printf
是不纯的,因为它确实I/O
。I/O
根据定义是不纯的,因为存在I/O
设备的外部状态(状态可能因执行而异)。
很多答案都解释了printf
I/O 作为副作用,但printf
也可能有其他副作用。例如,说明符%n
允许printf
写入指定的地址(并且是一些安全漏洞的原因)。
纯函数在编程中的意义在于,如果它已经具有调用具有相同参数的函数的结果,则实现可以优化对纯函数的调用。显然,对于 printf 的调用无法做到这一点。
PS 即使按照您的定义, printf 也是不纯的,因为它可以在成功时返回一个值,而如果出现 I/O 错误(例如,输出设备上的空间不足)则返回不同的值。
printf()
是不纯的,因为它会导致输出到 I/O 设备作为副作用.....