【问题标题】:Why can't I swap out the variable of the for loop with a random letter?为什么我不能用随机字母替换 for 循环的变量?
【发布时间】:2020-01-24 22:53:50
【问题描述】:

我正在写一个整数到罗马数字的转换器。这一次,妥妥的。

尝试解决打印900s、90s、9s的问题;我在while循环中编写了一个for循环(只持续一个循环,因为它的目的是防止打印CMCMCMCM而不是CM)。但是对于for循环的变量,我在while循环中使用了与“n”相同的“n”而没有注意到。

运行它,运行良好;然后注意到所谓的错误。将其换成“A”,将“A”插入到 int cd, cl,..... 列表中。 AAAaa,结果是完全偏离轨道的数字混乱。

我不明白代码如何使用重复使用的循环变量正常工作,但不能使用新的。

#include<stdio.h>
int main()
{
    int num, m, c, d, l, x, v, i, n, cm, cd;
    printf("Enter Number: ");
    scanf_s("%d", &num);
        m = num / 1000;
        d = (num % 1000) / 500;
        c = (num % 500) / 100;
        l = (num % 100) / 50;
        x = (num % 50) / 10;
        v = (num % 10) / 5;
        i = (num % 5);
        n = m + d + c + l + x + v + i;
        while (n > 0)
        {
            {
                for (m; m > 0; m--)
                {
                    printf("M");
                }
            }
            {
                for (n=1; n>0; n--)
                {
                    if (num%1000>=900)
                    {
                        printf("CM");
                        d = d - 1;
                        c = c - 4;
                        num = num - 900;
                    }
                }
            }
            {
                for (d; d > 0; d--)
                    printf("D");
            }
            {
                for (n = 1; n > 0; n--)
                {
                    if (num % 500 >= 400)
                    {
                        printf("CD");
                        c = c - 4;
                    }
                }

            }
            {
                for (c; c > 0; c--)
                    printf("C");
            }
            {
                for (l; l > 0; l--)
                    printf("L");
            }
            {
                for (x; x > 0; x--)
                    printf("X");
            }
            {
                for (v; v > 0; v--)
                    printf("V");
            }
            {
                for (i; i > 0; i--)
                    printf("I");
            }
            n--;
        }
        return 0;
}

请记住,900、400 等的 for 循环没有完成,因为我在编写 900 单循环后注意到了这一点。

【问题讨论】:

  • 为什么是循环周围的块?并且绝对可以将其简化为两个循环左右,以说明问题并方便读者。
  • 如果您将要转换的值作为参数而不是从标准输入中读取,界面会更简洁。
  • 那是num = strtol(argv[1], NULL, 0);

标签: c loops for-loop while-loop roman-numerals


【解决方案1】:

首先,您计算输出中每个不同字母的数量。然后你有一个while循环运行n减少到0,即循环体运行n次。在循环内部,您有一系列 for 循环,每个循环对应一个不同的字母。如果你省略了使用n 的 for 循环,你正在这样做:

  • 计算输出中每个字母的数量:mdc 等以及n,即字母总数(以加法表示)。
  • 重复n 次:
    • 打印Mm 次。
    • 打印Dd 次。

结果是,如果没有修改 n 的内部循环,您将多次打印结果。

以加法表示法(4 是IIII 等)打印罗马数字的正确算法是:

  • 计算mdc
  • 打印Mm 次。
  • 打印Dd 次。

如果没有修改 n 的 for 循环,您将重复正确的算法 n 次:

while (n > 0) {
    … /* code that doesn't modify n and prints the desired output */
    n--;
}

使用修改n 的for 循环,您在while 循环的主体内将n 设置为0,因此循环主体末尾的n--n 设置为-1,并且while 循环在第一次迭代后终止。

while (n > 0) {
    … /* some code */
    for (n = 1; n > 0; n--) {
        … /* more core */
    }
    /* On exit of this for loop, the value of n is 0. */
    … /* more code that doesn't modify n */
    n--;
}

解决方法很简单:删除 while 循环,因为您总是希望只执行一次它的主体。删除要打印的字母总数的计算:不需要。使用 n 的 for 循环也只执行一次它们的主体,因此它们也无用。这是结果(我已经使缩进统一并删除了无用的大括号,但除此之外我没有寻求改进程序):

#include<stdio.h>
int main()
{
    int num, m, c, d, l, x, v, i, cm, cd;
    printf("Enter Number: ");
    scanf("%d", &num);
    m = num / 1000;
    d = (num % 1000) / 500;
    c = (num % 500) / 100;
    l = (num % 100) / 50;
    x = (num % 50) / 10;
    v = (num % 10) / 5;
    i = (num % 5);
    for (m; m > 0; m--)
    {
        printf("M");
    }
    if (num%1000>=900)
    {
        printf("CM");
        d = d - 1;
        c = c - 4;
        num = num - 900;
    }
    for (d; d > 0; d--)
        printf("D");
    if (num % 500 >= 400)
    {
        printf("CD");
        c = c - 4;
    }
    for (c; c > 0; c--)
        printf("C");
    for (l; l > 0; l--)
        printf("L");
    for (x; x > 0; x--)
        printf("X");
    for (v; v > 0; v--)
        printf("V");
    for (i; i > 0; i--)
        printf("I");
    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-31
    • 2018-05-12
    • 1970-01-01
    • 2012-10-29
    • 2012-06-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多