【问题标题】:12 Days Of Christmas C Program12天圣诞节C程序
【发布时间】:2013-08-26 14:09:58
【问题描述】:

所以我尝试自己编写 12 天的圣诞节代码。我还没有完成歌词,但我仍在努力弄清楚。但我不明白为什么我圣诞节的“第一天”会翻倍并搭配不同的礼物,而在第 12 天,没有礼物出现。我检查了我的开关盒,我猜它们似乎是对的。有没有可能我可以减少我的代码来打印出完整的歌词?

#include <stdio.h>
#include <conio.h>

int main() // Main Function
{
    int days, counter, num;
    //int counter = 1;  

    printf("\t\t***TWELVE DAYS OF CHRISTMAS***\n");
    printf("\t\t______________________________\n\n\n");

    for (counter=0; counter<=12; counter++)
    {   
        // counter++;
        switch(counter)
        {
            case 1: printf("\t\tA Partridge in a Pear Tree\n");break; // Day 12
            case 2: printf("\t\tTwo Turtle Doves\n"); break;
            case 3: printf("\t\tThree French Hens\n"); break;
            case 4: printf("\t\tFour Calling Birds \n"); break;
            case 5: printf("\t\tFive Golden Rings\n"); break;
            case 6: printf("\t\tSix Geese a Laying\n"); break;
            case 7: printf("\t\tSeven Swans a Swimming\n"); break;
            case 8: printf("\t\tEight Maids a Milking\n"); break;
            case 9: printf("\t\tNine Ladies Dancing\n"); break;
            case 10: printf("\t\tTen Lords a Leaping\n"); break;
            case 11: printf("\t\tEleven Pipers Piping\n"); break;
            case 12: printf("\t\tTwelve Drummers Drumming\n"); break; // Day 1 
        }
        printf("\n\tOn the ");

        switch(counter){
            case 1:
                printf("1st");
                break;  
            case 2: 
                printf("2nd");
                break;
            case 3: 
                printf("3rd");
                break;
            case 4: 
                printf("4th");
                break;
            case 5: 
                printf("5th");
                break;      
            case 6: 
                printf("6th");
                break;
            case 7: 
                printf("7th");
                break;
            case 8: 
                printf("8th");
                break;  
            case 9: 
                printf("9th");
                break;
            case 10:    
                printf("10th");
                break;  
            case 11:    
                printf("11th");
                break;  
            case 12:    
                printf("12th");
                break;                                                                                      
                default: 
                printf("1st", num);
                break;
            }
            printf(" day of Christmas my true love sent to me\n");

        }   

        getch();
        return 0;
    }

指令说,“你的函数只会在 main() 函数中被调用,不会返回任何东西” 那么这是否意味着我不会创建更多函数呢?或者我应该只将我的所有代码放在主函数中吗?还是创建单独的代码?

【问题讨论】:

  • 注意:您的 for 循环来自 0...12,但您有来自 1...12 的案例
  • 这意味着,而不是主函数中的逻辑。将其包装在另一个函数中(例如 PrintTwelveDaysOfChristmas()),该函数的返回类型为 void(无结果)。然后你可以从主函数调用那个函数。
  • 您在循环开始时将 counter 初始化为 0。但是在切换中,您希望它从 1 开始。另外,您打印出“梨树中的鹧鸪”部分before“在...的第 n 天”) :)跨度>
  • 如果你把你的第一个开关倒过来,去掉breaks,你会得到一些有趣的东西。
  • 这里有一个小技巧,可以让这更容易一些:你知道你想从 switch 语句中的一个索引开始,一直到“梨树中的一只鹧鸪”而不中断.您可以翻转您的 switch 语句并删除所有 break (即:从案例 12 开始并在案例 1 结束:)...然后您所要做的就是告诉您的程序“入口点”在哪里" 是,它会滑过所有剩余的日子。

标签: c++ c


【解决方案1】:

再次查看 switch 语句,记住中断并不是完全必要的。

switch (day) {
  case 2: printf("two turtle doves ");
  case 1: printf("and a partridge in a pear tree");
}

这将是“第 2 天”从“两只斑鸠”开始,经过到“和梨树上的一只鹧鸪”。

同时,“第一天”的开始是“梨树上的鹧鸪”。

【讨论】:

  • 我建议使用数组,并且使用 [0, 12) 而不是 [1, 12]。
  • @Veltas 我认为这会使代码更难理解,而且这是不必要的更改。
  • @KirkBackus 那么你会争辩说 switch 语句是一种迷你反模式。这是一个有效的论点。我自己尽量避免它们;但是,当需要它们时(这可能是真正需要它们的极少数情况),最好正确使用它们。
  • 其实对于懂C的人来说理解一样简单,看来学好C才是提问者的目的。这是一个不必要的改变,但它是更好的风格,不是吗?我原以为提问者宁愿学习体面的编程,也不愿以最简单的方式一起破解 12 天。
  • @EdwinBuck 我忘了加上我正在和谁说话,我其实很喜欢 switch 语句的方式。
【解决方案2】:

我实际上并不认为交换机是这里的最佳选择。我们有一个要显示的项目列表,我们可以轻松地将其放入数组和顺序中,并且每次都必须显示这些项目的不同列表。虽然这里的 switch 语法很好(正如问题的 cmets 中提到的,而不是在提问者的代码本身中使用的那样),但我认为简单的循环比不断要求程序执行 switch 跳转更合适。

这是我建议的解决方案:

#include <stdio.h>

const char
  *presents[] = {
    "\t\tA Partridge in a Pear Tree\n", "\t\tTwo Turtle Doves\n",
    "\t\tThree French Hens\n", "\t\tFour Calling Birds \n",
    "\t\tFive Golden Rings\n", "\t\tSix Geese a Laying\n",
    "\t\tSeven Swans a Swimming\n", "\t\tEight Maids a Milking\n",
    "\t\tNine Ladies Dancing\n", "\t\tTen Lords a Leaping\n",
    "\t\tEleven Pipers Piping\n", "\t\tTwelve Drummers Drumming\n"},
  *days[] = {
    "1st", "2nd", "3rd", "4th", "5th", "6th",
    "7th", "8th", "9th", "10th", "11th", "12th"};

void printTwelveDaysSong(void)
{
  int i, j;

  for (i = 0; i < 12; ++i) {
    printf("\n\tOn the %s day of Christmas my true love sent to me\n", days[i]);
    for (j = i; j > 0; --j) fputs(presents[j], stdout);
    if (i > 0) fputs("\t\tand\n", stdout);
    fputs(presents[0], stdout);
  }
}

/* Example main function */
int main(void)
{
  printTwelveDaysSong();
  return 0;
}

我将核心代码放在不同的函数中,因为这听起来像是需要的,所以我也展示了这一点,没什么特别的。

在代码中我只使用了 C 标准库函数进行输出,并且我没有尝试实现交互式程序,如果您愿意,可以自己添加。

【讨论】:

  • 这几乎是我在对字符串数组发表原始评论时所想到的。 +1 读心术!
【解决方案3】:

您的for 循环将counter 设置为零,但您的switch 语句处理大于零的情况。

【讨论】:

    【解决方案4】:

    好吧,首先你将计数器设置为零,第一个开关不打印任何内容,第二个打印“在 1 日...”。

    然后你将 counter 设置为 1...

    而且,在你说出今天是哪一天之前,你会很奇怪地把礼物打印出来。

    为了减少代码,你应该考虑到 1 到 12,只有 1st、2nd 和 3rd 不以 th 结尾,此外请记住你可能会在 switch 中遇到 case(不是特别好的样式,但适用于这种事)。

    【讨论】:

    • 我应该怎么做 "%dth" ? @汤姆坦纳
    • @JennicaPrincess: printf("%dth", counter); 应该可以工作,如果你让 counter 从 1 循环到 12。
    【解决方案5】:

    for 条件应该是:

    for (counter=1; counter<=12; counter++)
    

    【讨论】:

    • 我建议使用数组,并且使用 [0, 12) 而不是 [1, 12]。
    • 我试过了,但是“梨树上的帕特里奇”排在“第一天……”之前,这是为什么? @MatteoD
    • 我们的课程还没有解决数组问题。我们仍然在基础、循环和函数上。我想如果我会使用数组我会很难,因为我仍然不知道它。 @Veltes
    • @JennicaPrincess:因为这是你打印东西的顺序。你在“第 N 天……”之前打印礼物。就目前而言,counter 从 0 开始,第一行很可能是“圣诞节那天……”,不是吗? (实际上,没关系;我只是重新阅读代码并注意到默认情况。但这确实意味着您在 counter == 0 和 counter == 1 时都打印1st。)
    • @JennicaPrincess:好的,但我应该警告你,这是一个人们来学习的网站,而不是在硬件方面得到帮助(尽管你可以顺便获得硬件方面的帮助)。当你来到这里时,准备学习一两件事。
    【解决方案6】:

    你从counter=0开始你的for循环。这会导致第一个switch 不打印任何内容,而第二个switch 转到打印“1st”的default。这可能就是您的第一天打印两次的原因!

    将你的 for 循环改为 for (counter = 1; counter &lt;= 12; counter++)

    【讨论】:

    • 你必须做的不止这些。否则,第一次迭代将打印"\t\tA Partridge in a Pear Tree\n\tOn the 1st day of Christmas"
    • 是的,先打印现在似乎有点奇怪……switch 语句的顺序也必须交换! :)
    【解决方案7】:
    #include <stdio.h>
    #include <conio.h>
    
    int main() // Main Function
    {
    int days, counter, num;
    //int counter = 1;  
    
    printf("\t\t***TWELVE DAYS OF CHRISTMAS***\n");
    printf("\t\t______________________________\n\n\n");
    
    for (counter=1; counter<=13; counter++)
    {   
        printf("\n\tOn the ");
    
        switch(counter){
            case 1:
                printf("1st");
                break;  
            case 2: 
                printf("2nd");
                break;
            case 3: 
                printf("3rd");
                break;                                                             
            default: 
                printf(counter + "th");
                break;
            }
    
        printf(" day of Christmas my true love sent to me\n");
        for (int x= counter; x > 0; x--)
        {
            switch(x)
            {
                case 1: printf("\t\t");if (counter > 1 ) printf("And ");printf("A Partridge in a Pear Tree\n");break; // Day 12
                case 2: printf("\t\tTwo Turtle Doves\n"); break;
                case 3: printf("\t\tThree French Hens\n"); break;
                case 4: printf("\t\tFour Calling Birds \n"); break;
                case 5: printf("\t\tFive Golden Rings\n"); break;
                case 6: printf("\t\tSix Geese a Laying\n"); break;
                case 7: printf("\t\tSeven Swans a Swimming\n"); break;
                case 8: printf("\t\tEight Maids a Milking\n"); break;
                case 9: printf("\t\tNine Ladies Dancing\n"); break;
                case 10: printf("\t\tTen Lords a Leaping\n"); break;
                case 11: printf("\t\tEleven Pipers Piping\n"); break;
                case 12: printf("\t\tTwelve Drummers Drumming\n"); break; // Day 1 
            }
        }
    
    }           
        getch();
        return 0;
    }
    

    【讨论】:

    • 也许重写第二个开关,这样 for 循环就变得不必要了?即删除中断并将案例倒置。并不是说我认为 switch 语句在这里是合适的。
    【解决方案8】:

    我假设您的教授的目标是教您如何使用 switch 语句(可能要求您使用多个 switch 语句?)。显然,这个程序除了教学之外没有任何实际用途。因此,所有向您推荐各种“创造性”方法(例如使用数组和其他东西)的人都误解了您的情况。你犯了一些错误——那里有一些不必要的东西。但是您的思路是正确的,只需要复习几次(来自 cmets 的 SuvP 的一个特别好的通知)。

    【讨论】:

      【解决方案9】:
      #include <iostream>
      #include <string>
      
      using std::cout;
      
      const char *num_day[] = {"-", "First", "Second", "Third",
               "Fourth", "Fifth", "Sixth", "Seventh",
               "Eighth", "Ninth", "Tenth", "Eleventh", "Twelfth"};
      int main()
      {
      
          for (int day = 1; day <= 12; ++day) {
          cout << "On the " << num_day[day]
               << " day of Christmas, my true love gave to me:\n";
          switch (day) {
              case 12: cout << "Twelve Drummers Drumming\n";
              case 11: cout << "Eleven Pipers Piping\n";
              case 10: cout << "Ten Lords a-Leaping\n";
              case 9: cout << "Nine Ladies Dancing\n";
              case 8: cout << "Eight Maids a-Milking\n";
              case 7: cout << "Seven Swans a-Swimming\n";
              case 6: cout << "Six Geese a-Laying\n";
              case 5: cout << "Five Gold Rings\n";
              case 4: cout << "Four Calling Birds\n";
              case 3: cout << "Three French Hens\n";
              case 2: cout << "Two Turtle Doves, and\n";
              case 1: cout << "A Partridge in a Pear Tree\n\n";
          }
      }
      return 0;
      

      }

      【讨论】:

      • 由于缺少break = 失败,此代码不会给出正确的结果。
      猜你喜欢
      • 2012-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-27
      • 1970-01-01
      相关资源
      最近更新 更多