You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言printf嵌套scanf的参数求值顺序与输出差异探究

两段C语言printf代码输出差异原因分析及参数求值机制确认

测试代码

code1

#include <stdio.h>
int main() {
    int z = 9;
    printf("%d\n", printf("%d%d", scanf("%d", &z), z));
    return 0;
}

code2

#include <stdio.h>
int main() {
    int z = 9;
    printf("%d\n", printf("%d%d", z, scanf("%d", &z)));
    return 0;
}

测试结果

输入code1输出code2输出
1192112
a092902

输出差异原因及求值机制说明

先明确两个核心前提:

  1. scanf的返回值:成功读取输入项的数量,输入合法整数时返回1,输入非整数(如a)时返回0,且此时目标变量z的初始值不会被修改。
  2. C语言标准未指定函数参数的求值顺序,你观察到的从右向左求值是当前所用编译器(如GCC)的具体实现逻辑,不同编译器可能采用左向右或其他顺序,但你的测试结果完全符合右向左求值的行为。

输入为1时的逻辑拆解

  • code1:
    内层printf的两个参数按右向左求值:

    1. 先计算右侧的z:此时z是初始值9,得到数值9。
    2. 再计算左侧的scanf:读取输入1,将z修改为1,返回值1。
      内层printf输出1+9即19,而printf的返回值是输出的字符数(此处为2),外层printf输出这个2,最终得到192。
  • code2:
    内层printf的两个参数按右向左求值:

    1. 先计算右侧的scanf:读取输入1,将z修改为1,返回值1。
    2. 再计算左侧的z:此时z已被修改为1,得到数值1。
      内层printf输出1+1即11,外层printf输出返回值2,最终得到112。

输入为a时的逻辑拆解

  • code1:
    内层printf的两个参数按右向左求值:

    1. 先计算右侧的z:取初始值9,得到数值9。
    2. 再计算左侧的scanf:读取a失败,返回0,z保持初始值9不变。
      内层printf输出0+9即09,外层printf输出返回值2,最终得到092。
  • code2:
    内层printf的两个参数按右向左求值:

    1. 先计算右侧的scanf:读取a失败,返回0,z保持初始值9不变。
    2. 再计算左侧的z:取当前值9,得到数值9。
      内层printf输出9+0即90,外层printf输出返回值2,最终得到902。

关于参数求值顺序的确认

C语言标准(C99及后续版本)明确将函数参数的求值顺序列为未指定行为——编译器可自由选择求值顺序,从右向左只是GCC等主流编译器的常用实现方式。代码不能依赖这种顺序,否则在其他编译器上可能产生完全不同的结果,属于需要避免的非可移植写法。

内容的提问来源于stack exchange,提问作者anon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 22:47:19