【问题标题】:How do I make conditions in printf statements?如何在 printf 语句中创建条件?
【发布时间】:2018-08-23 18:17:48
【问题描述】:

我有作业,我必须创建一个 C 程序,将 5 个数字从小到大排序。我知道如何使用函数和if 语句(使用>=<=)轻松编程。

但是,问题是我只能使用printfscanf,所以我必须计算printf 内的所有>=<=。而且我不允许使用三元运算符。

我已经尝试了很长时间。所以我试着只对 3 个数字进行排序,我什至无法通过排序最小的数字。它只是继续打印1

// This printf is just trying to figure out the smallest number from 3 numbers provided but it keeps printing 1.
printf("The ascending order of the numbers are: %d ",
    (
     (num1 <= num2 && num1 <= num3) || // Checking if num1 is the smallest
     (num2 <= num1 && num2 <= num3) || // Checking if num2 is the smallest
     (num3 <= num2 && num3 <= num1)    // Checking if num3 is the smallest
    ));

我想出的一个可能的解决方案是添加((num1 + num2 + num3) -1),因为如果其中一个语句为真(例如,如果num2 是最小的,它将打印1,因为1 表示真)。如果为假,则打印0。所以我可以在技术上添加正确的陈述然后-1。所以如果num2的说法是真的,我可以做+ num2 - 1

【问题讨论】:

  • 打印 1 因为表达式为真。是否允许使用三元运算符a ? b : c
  • @Katie 也没有三元组?要么是我误会了,要么你误会了,要么你的教授在耍你的狠心。
  • @user3386109 它部分工作(如你所说)。但是,如果使用该程序的人输入相同的数字,它就会中断。例如,如果用户输入 5 5 5 那么它会中断。或者如果用户输入 5 5 10
  • 这个作业的价值只是学术性的,我想,通过让你“跳出框框思考”(我不会在任何合理的时间内提出解决方案)。实际上,这是一项愚蠢、愚蠢、无用的任务,而且可能是有害的。大概这是 CompSci 101 或类似的东西;有多少对编码感兴趣的学生会被这样的任务吓跑?学生们会认为在printf 做这么多工作很正常吗?完成此任务后,永远不要再次编写这样的代码。这些愚蠢的要求(不允许使用这个,
  • @yano 说了什么。无论这个练习教什么,它都不是 C 编程。

标签: c if-statement printf conditional


【解决方案1】:

通过 1:至少三个不同的值

请注意,如果条件评估为 false,则结果为 0;如果为真,1。所以你可以使用一个技巧(只要乘法和加法也不是被禁止的)——对于三个不同的值,如问题所示:

printf("The smallest number is: %d ",
       (num1 * (num1 <= num2 && num1 <= num3) +
        num2 * (num2 <= num1 && num2 <= num3) +
        num3 * (num3 <= num1 && num3 <= num2)));

如果两个值相同,又是较小的值,那就麻烦了。

通过 2:至少五个不同的值

如果您需要处理 5 个值,则(如评论中所述)繁琐多于困难。

printf("The smallest number is: %d ",
       (num1 * (num1 <= num2 && num1 <= num3 && num1 <= num4 && num1 <= num5) +
        num2 * (num2 <= num1 && num2 <= num3 && num2 <= num4 && num2 <= num5) +
        num3 * (num3 <= num1 && num3 <= num2 && num3 <= num4 && num3 <= num5) +
        num4 * (num4 <= num1 && num4 <= num2 && num4 <= num3 && num4 <= num5) +
        num5 * (num5 <= num1 && num5 <= num2 && num5 <= num3 && num5 <= num4)));

这只是为了找到最小值;为其他每个案例工作很快就会变得荒谬。确实,整个练习相当愚蠢,但它在某些课程中也相当典型。

通过 3:至少三个值不一定不同

经过一番思考,我想你可以用这个来处理 2 或 3 个相同的数字(这基本上是 user3386109comment 中所说的)。

#include <stdio.h>

static void print_smallest(int num1, int num2, int num3)
{
    printf("The smallest number of (%d, %d, %d) is %d\n",
           num1, num2, num3,
           (num1 * (num1 <= num2 && num1 <= num3) +
            num2 * (num2 <  num1 && num2 <= num3) +
            num3 * (num3 <  num1 && num3 <  num2)));
}

int main(void)
{
    for (int i = 1; i < 4; i++)
    {
        for (int j = 1; j < 4; j++)
        {
            for (int k = 1; k < 4; k++)
                print_smallest(i, j, k);
        }
    }
    return 0;
}

输出:

The smallest number of (1, 1, 1) is 1
The smallest number of (1, 1, 2) is 1
The smallest number of (1, 1, 3) is 1
The smallest number of (1, 2, 1) is 1
The smallest number of (1, 2, 2) is 1
The smallest number of (1, 2, 3) is 1
The smallest number of (1, 3, 1) is 1
The smallest number of (1, 3, 2) is 1
The smallest number of (1, 3, 3) is 1
The smallest number of (2, 1, 1) is 1
The smallest number of (2, 1, 2) is 1
The smallest number of (2, 1, 3) is 1
The smallest number of (2, 2, 1) is 1
The smallest number of (2, 2, 2) is 2
The smallest number of (2, 2, 3) is 2
The smallest number of (2, 3, 1) is 1
The smallest number of (2, 3, 2) is 2
The smallest number of (2, 3, 3) is 2
The smallest number of (3, 1, 1) is 1
The smallest number of (3, 1, 2) is 1
The smallest number of (3, 1, 3) is 1
The smallest number of (3, 2, 1) is 1
The smallest number of (3, 2, 2) is 2
The smallest number of (3, 2, 3) is 2
The smallest number of (3, 3, 1) is 1
The smallest number of (3, 3, 2) is 2
The smallest number of (3, 3, 3) is 3

第 4 步:三个值的排序顺序不一定不同

计算最大值而不是最小值很简单;只需使用&gt; 代替&lt;。 计算中位数变得更加困难。我怀疑有比这更好的方法,但至少这是可行的。注意减去的项——省略它,当三个值相同时,中值加倍。

#include <stdio.h>

static void print_smallest(int num1, int num2, int num3)
{
    printf("The sorted order of (%2d, %2d, %2d) is (%2d, %2d, %2d)\n",
           num1, num2, num3,

           (num1 * (num1 <= num2 && num1 <= num3) +     /* Min1 */
            num2 * (num2 <  num1 && num2 <= num3) +     /* Min2 */
            num3 * (num3 <  num1 && num3 <  num2)),     /* Min3 */

           (num1 * (num1 >= num2 && num1 <= num3) +     /* Med1 */
            num2 * (num2 >  num1 && num2 <= num3) +     /* Med2 */
            num3 * (num3 >  num1 && num3 <  num2) -     /* Med3 */
            num1 * (num1 == num2 && num1 == num3) +     /* Med4 */
            num1 * (num1 <= num2 && num1 >= num3) +     /* Med5 */
            num2 * (num2 <  num1 && num2 >= num3) +     /* Med6 */
            num3 * (num3 <  num1 && num3 >  num2)),     /* Med7 */

           (num1 * (num1 >= num2 && num1 >= num3) +     /* Max1 */
            num2 * (num2 >  num1 && num2 >= num3) +     /* Max2 */
            num3 * (num3 >  num1 && num3 >  num2))      /* Max3 */
          );
}

int main(void)
{
    int lo = -7;        // +1, -2
    int hi = +6;        // +4, +4
    int jp = +6;        // +1, +2
    for (int i = lo; i < hi; i += jp)
    {
        for (int j = lo; j < hi; j += jp)
        {
            for (int k = lo; k < hi; k += jp)
                print_smallest(i, j, k);
        }
    }
    return 0;
}

输出:

The sorted order of (-7, -7, -7) is (-7, -7, -7)
The sorted order of (-7, -7, -1) is (-7, -7, -1)
The sorted order of (-7, -7,  5) is (-7, -7,  5)
The sorted order of (-7, -1, -7) is (-7, -7, -1)
The sorted order of (-7, -1, -1) is (-7, -1, -1)
The sorted order of (-7, -1,  5) is (-7, -1,  5)
The sorted order of (-7,  5, -7) is (-7, -7,  5)
The sorted order of (-7,  5, -1) is (-7, -1,  5)
The sorted order of (-7,  5,  5) is (-7,  5,  5)
The sorted order of (-1, -7, -7) is (-7, -7, -1)
The sorted order of (-1, -7, -1) is (-7, -1, -1)
The sorted order of (-1, -7,  5) is (-7, -1,  5)
The sorted order of (-1, -1, -7) is (-7, -1, -1)
The sorted order of (-1, -1, -1) is (-1, -1, -1)
The sorted order of (-1, -1,  5) is (-1, -1,  5)
The sorted order of (-1,  5, -7) is (-7, -1,  5)
The sorted order of (-1,  5, -1) is (-1, -1,  5)
The sorted order of (-1,  5,  5) is (-1,  5,  5)
The sorted order of ( 5, -7, -7) is (-7, -7,  5)
The sorted order of ( 5, -7, -1) is (-7, -1,  5)
The sorted order of ( 5, -7,  5) is (-7,  5,  5)
The sorted order of ( 5, -1, -7) is (-7, -1,  5)
The sorted order of ( 5, -1, -1) is (-1, -1,  5)
The sorted order of ( 5, -1,  5) is (-1,  5,  5)
The sorted order of ( 5,  5, -7) is (-7,  5,  5)
The sorted order of ( 5,  5, -1) is (-1,  5,  5)
The sorted order of ( 5,  5,  5) is ( 5,  5,  5)

通过 5:三个值的排序顺序,没有循环或函数

和以前一样,第 4 步中的代码对三个数字的所有组合在它们的相对位置上进行了彻底的测试。如果您需要读取三个数字然后对其进行排序(并且您不允许使用除main()scanf()printf() 之外的循环或函数,就这样吧——您可以移植printf()在您读取三个值后立即在您的main() 中声明:

#include <stdio.h>

int main(void)
{
    int num1, num2, num3;

    if (scanf("%d%d%d", &num1, &num2, &num3) != 3)
    {
        fprintf(stderr, "failed to read 3 integers\n");
        return 1;
    }

    printf("The sorted order of (%2d, %2d, %2d) is (%2d, %2d, %2d)\n",
           num1, num2, num3,

           (num1 * (num1 <= num2 && num1 <= num3) +     /* Min1 */
            num2 * (num2 <  num1 && num2 <= num3) +     /* Min2 */
            num3 * (num3 <  num1 && num3 <  num2)),     /* Min3 */

           (num1 * (num1 >= num2 && num1 <= num3) +     /* Med1 */
            num2 * (num2 >  num1 && num2 <= num3) +     /* Med2 */
            num3 * (num3 >  num1 && num3 <  num2) -     /* Med3 */
            num1 * (num1 == num2 && num1 == num3) +     /* Med4 */
            num1 * (num1 <= num2 && num1 >= num3) +     /* Med5 */
            num2 * (num2 <  num1 && num2 >= num3) +     /* Med6 */
            num3 * (num3 <  num1 && num3 >  num2)),     /* Med7 */

           (num1 * (num1 >= num2 && num1 >= num3) +     /* Max1 */
            num2 * (num2 >  num1 && num2 >= num3) +     /* Max2 */
            num3 * (num3 >  num1 && num3 >  num2))      /* Max3 */
          );

    return 0;
}

使用随机数生成器(程序名称sort3-53)进行测试会产生:

$ for i in $(range 0 9); do random -n 3 10 99 | sort3-53; done
The sorted order of (66, 62, 70) is (62, 66, 70)
The sorted order of (43, 99, 23) is (23, 43, 99)
The sorted order of (20, 46, 66) is (20, 46, 66)
The sorted order of (87, 82, 19) is (19, 82, 87)
The sorted order of (63, 29, 62) is (29, 62, 63)
The sorted order of (40, 66, 15) is (15, 40, 66)
The sorted order of (17, 13, 58) is (13, 17, 58)
The sorted order of (84, 50, 11) is (11, 50, 84)
The sorted order of (60, 86, 54) is (54, 60, 86)
The sorted order of (37, 33, 96) is (33, 37, 96)
$

您可能可以使用seq,而我使用range。我不确定是否有类似于我使用(和编写)的random 的标准 PRNG 程序。所示调用会生成 3 个介于 10 和 99 之间的随机数。

应该怎么做?

这里的整个过程很荒谬——但这是因为对可以使用的技术的条件。如果需要对三个或更多数字进行排序,请将它们放入数组中,对数组进行排序,然后打印数组。否则,您应该交换值以找到排序顺序;它将大大减少所需的比较次数,并且不会有乘法。

【讨论】:

  • 是的,现在我想看看打印五个数字中第二大的代码:)
  • @user3386109:这会比困难更乏味。这个练习很荒谬——但这并不像你想的那么不寻常。
  • 同意,如果这确实是预期的答案,那么这个练习就是荒谬的。
  • 我尝试这个练习的唯一方法是编写代码来生成代码。我不明白这是一个初学者问题,甚至是这个练习的重点。
  • 我仍然不解的是:预期的答案是什么? Jonathan Leffler 是 SO 上最有经验的 C 程序员之一,他可以才勉强开始解决这个问题。普通 C 编程课上的学生是不可能做到的。所以要么在翻译中丢失了一些东西,要么设置这个作业的老师是一个真正的恶意虐待狂。
【解决方案2】:

这是一个简单的解决方案,可以轻松适应任意数量的值:

#include <stdio.h>

int main() {
    int n[5], o[5], s[5];

    while (scanf("%d%d%d%d%d", &n[0], &n[1], &n[2], &n[3], &n[4]) == 5) {
        o[0] = (n[0] >  n[1]) + (n[0] >  n[2]) + (n[0] >  n[3]) + (n[0] >  n[4]);
        o[1] = (n[1] >= n[0]) + (n[1] >  n[2]) + (n[1] >  n[3]) + (n[1] >  n[4]);
        o[2] = (n[2] >= n[0]) + (n[2] >= n[1]) + (n[2] >  n[3]) + (n[2] >  n[4]);
        o[3] = (n[3] >= n[0]) + (n[3] >= n[1]) + (n[3] >= n[2]) + (n[3] >  n[4]);
        o[4] = (n[4] >= n[0]) + (n[4] >= n[1]) + (n[4] >= n[2]) + (n[4] >= n[3]);
        s[o[0]] = n[0];
        s[o[1]] = n[1];
        s[o[2]] = n[2];
        s[o[3]] = n[3];
        s[o[4]] = n[4];
        printf("%d %d %d %d %d\n", s[0], s[1], s[2], s[3], s[4]);
    }
    return 0;
}

注意while仅用于重复输入/排序/输出阶段。如果不允许 ifwhile 语句,您可以摆脱它,但是我不知道如何测试成功的 scanf() 转换,但可以通过初始化避免未定义的行为:

#include <stdio.h>

int main() {
    int n0, n1, n2, n3, n4, s[5];

    n0 = n1 = n2 = n3 = n4 = 0;
    scanf("%d%d%d%d%d", &n0, &n1, &n2, &n3, &n4);
    s[(n0 >  n1) + (n0 >  n2) + (n0 >  n3) + (n0 >  n4)] = n0;
    s[(n1 >= n0) + (n1 >  n2) + (n1 >  n3) + (n1 >  n4)] = n1;
    s[(n2 >= n0) + (n2 >= n1) + (n2 >  n3) + (n2 >  n4)] = n2;
    s[(n3 >= n0) + (n3 >= n1) + (n3 >= n2) + (n3 >  n4)] = n3;
    s[(n4 >= n0) + (n4 >= n1) + (n4 >= n2) + (n4 >= n3)] = n4;
    printf("%d %d %d %d %d\n", s[0], s[1], s[2], s[3], s[4]);
    return 0;
}

【讨论】:

    【解决方案3】:

    如果允许您使用int,我认为您会这样做(否则您如何存储用户输入)为什么不使用具有正确排序的预计算表?

    #include <stdio.h>
    
    int map[2][2] = {
        {1, 0},
        {0, 1}
    };
    
    int main() {
        int n[2] = {7, 5};
    
        int tmp  = n[0] >= n[1];
    
        printf("1.) %d\n", n[map[tmp][0]]);
        printf("2.) %d\n", n[map[tmp][1]]);
    }
    

    更新:这似乎适用于三个数字:

    #include <stdio.h>
    
    int map[2][2][2][3] = {
        {
            {
                {2, 1, 0},
                {1, 2, 0}
            },
            {
                {2, 0, 1},
                {0, 1, 0}
            }
        },
        {
            {
                {0, 0, 0},
                {1, 0, 2}
            },
            {
                {0, 2, 1},
                {0, 1, 2}
            }
        }
    };
    
    int main() {
        int n[3] = {30, 59, 100};
    
        int tmp1 = n[0] > n[2];
        int tmp2 = n[0] > n[1];
        int tmp3 = n[1] > n[2];
    
        printf("1.) %d\n", n[map[tmp1][tmp2][tmp3][0]]);
        printf("2.) %d\n", n[map[tmp1][tmp2][tmp3][1]]);
        printf("3.) %d\n", n[map[tmp1][tmp2][tmp3][2]]);
    }
    

    【讨论】:

      猜你喜欢
      • 2014-02-15
      • 2011-12-05
      • 2017-01-01
      • 2022-01-18
      • 1970-01-01
      • 2012-06-23
      • 2012-03-09
      • 2023-02-07
      • 1970-01-01
      相关资源
      最近更新 更多