【问题标题】:Why the last 'printf' function didn't execute?为什么最后一个'printf'函数没有执行?
【发布时间】:2021-04-02 07:58:38
【问题描述】:

我是 C 新手,我很困惑为什么最后一个“printf”函数没有执行。 printf("%d:%.2d %c.m.,到达%d:%.2d %c.m.\n")

结果是“最近的出发时间是晚上 9 点 45 分,晚上 11 点 58 分到达”为什么结果不是'最近的出发时间是晚上 9 点 45 分,晚上 11 点 58 分到达。 最近的出发时间是晚上 9 点 45 分,晚上 11 点 58 分到达'

现在我意识到它是因为循环中的'return 0',但我不知道为什么。

感谢您提供的任何帮助。

int i,
    user_time,
    hour,
    d_hour,
    d_minute,
    a_hour,
    a_minute,
    minute,
    dep[8] = {480, 583, 679, 767, 840, 945, 1140, 1305},
    arr[8] = {616, 712, 811, 900, 968, 1075, 1280, 1438};

printf("Enter a 24-hour time: ");
scanf("%d :%d", &hour, &minute);
user_time = hour * 60 + minute;

printf("Closest departure time is ");

for (i = 0; i < 7; i++) {
    if (user_time <= dep[i] + 
        (dep[i + 1] - dep[i]) / 2) {

        d_hour = dep[i] / 60 > 12 ? dep[i] / 60 - 12 : dep[i] / 60;
        d_minute = dep[i] % 60;
        a_hour = arr[i] / 60 > 12 ? arr[i] / 60 - 12 : arr[i] / 60;
        a_minute = arr[i] % 60;

        printf("%d:%.2d %c.m., arriving at %d:%.2d %c.m.\n", 
               d_hour, d_minute, dep[i] / 60 > 11 ? 'p' : 'a',
               a_hour, a_minute, arr[i] / 60 > 11 ? 'p' : 'a');
        return 0;
    }
}

d_hour = dep[7] / 60 > 12 ? dep[7] / 60 - 12 : dep[7] / 60;
d_minute = dep[7] % 60;
a_hour = arr[7] / 60 > 12 ? arr[7] / 60 - 12 : arr[7] / 60;
a_minute = arr[7] % 60;

printf("%d:%.2d %c.m., arriving at %d:%.2d %c.m.\n",
       d_hour, d_minute, dep[7] / 60 > 11 ? 'p' : 'a',
       a_hour, a_minute, arr[7] / 60 > 11 ? 'p' : 'a');

【问题讨论】:

  • 可能是因为你 return 在循环内?也许您应该只将break 排除在循环之外?
  • @Some 程序员老兄 谢谢。这是一本书的答案,我不明白它为什么有效。当循环中有'return 0'时,它的作用是什么?
  • 如果之前的条目都不适合用户的输入,您想打印时间表中的最后一个条目。当你找到一个合适的出发点时,比如在循环中的 8 点,那么你就不需要打印最后一个条目,所以你可以简单地通过从它返回来跳过函数的其余部分。
  • 澄清:我的意思是上面评论中的上午 8 点,而不是数组中的第 8 个条目。
  • @CiaPan 非常感谢,我明白你的意思。我现在了解该程序:)

标签: c return


【解决方案1】:

由于return 0;,函数从for循环内部退出,因此最后一个printf永远不会执行。

已添加

如果您不知道为什么内部的return 会跳过最后一个打印,则说明您缺乏对所使用语言的基本知识。

在 C 语言中,return 语句会导致执行它的函数立即终止。换句话说,它跳转到具有指定返回值的右大括号,即函数的结果。

如果您想终止循环但不退出函数,请使用break 而不是return。但请注意,break 仅打破“最近”循环——如果你在嵌套循环中使用它,如下所示:

for (i=0; i<10; i++)
{
    // do some stuff with i

    for (j=0; j<4; j++)
    {
        // do some stuff with j

        if (some_condition)
            break;              // <----- break here

        // do more stuff about j
    }

    // do more stuff about i
}
// the rest of the program

然后内部循环中的break 将执行刚刚超过该循环的结束,到do more stuff about i 点,而不是the rest of the program

已添加

如果您确实了解 return 的工作原理,但不了解 为什么使用它,那么您缺乏对程序逻辑的基本知识。

您根据输入寻找适合用户需求的出发时间。为此,您需要使用每个出发时间下一个出发时间。但是,在时间表中的最后一个之后没有下一个出发,因此您扫描表格直到最后一个项目。

如果之前的条目都不适合用户的输入,那么您想打印时间表中的最后一个条目。如果您在循环中找到适当的偏离,例如在i==3,那么您打印它并且您不需要打印最后一个条目。然后你可以简单地通过返回来跳过函数的其余部分。

【讨论】:

  • 感谢您的回答。在最后一个 printf 之后,主函数还有另一个“返回 0”。如果 dep[0] 到 dep[6] 不能满足条件,程序将执行'return 0'之后的部分。现在我意识到了,因为返回 0,但我不知道为什么。
  • @Charles 请查看扩展答案。
【解决方案2】:
**d_hour** = dep[7] / 60 > 12 ? dep[7] / 60 - 12 : **dep[7] / 60**;
printf("**%d**:%.2d %c.m., arriving at %d:%.2d %c.m.\n",
d_hour, d_minute, dep[7] / 60 > 11 ? 'p' : 'a',
_hour, a_minute, arr[7] / 60 > 11 ? 'p' : 'a');

您的 d_hour 将得到 dep[7] / 60 的结果,这将导致浮点数据类型。 但我可以看到 printf 期望 %d 是整数数据类型。 请使用数据转换或使用 '%f' 打印数据。

【讨论】:

  • 感谢您的回答,由于C的特性,它仍然是'int'类型。
  • 不,dep[7]60 这两个表达式都是int 类型,所以dep[7] / 60 的除法结果也是int