【问题标题】:Increment a value up to a specific value, and then decrement back down to the initial starting point?将一个值增加到特定值,然后再减小到初始起点?
【发布时间】:2018-06-21 11:56:21
【问题描述】:

为标题道歉,但我找不到已经提出的类似问题。正如暗示的那样,我的问题是如何实现一个计数器,它从初始值开始并向上递增直到达到特定点,然后递减回原始值。请允许我提供一个例子来更好地展示我的意思

#include <stdio.h>

int main(void) {
  int i = 0;
  for(i = 0; i <= 10; i++) {
      printf("i = %d\n", i);
      if(i == 5) {
          int j = i;
          for(j = i; j >= 0; j--) {
              printf("j = %d\n", j);
          }
      }
  }
  return 0;
}

运行时,程序将为i 打印值0-5,然后为j 打印5-0,然后为i 打印6-10。而不是这个,我只想让程序为i打印0-5,然后为i打印5-0(如果需要另一个变量,则为j)。

【问题讨论】:

  • 为什么要嵌套循环?为什么不只是for(i=0;i&lt;=5;i++){ [print] } 然后for(i=5;i&gt;=0;i--){ [print] }
  • 这个例子只是为了展示我想说的话。实际上,这个想法并没有利用for循环并将值增加80,直到达到添加80会导致值超过阈值的点,在这种情况下,值将开始减少80并重复该过程
  • 您是否尝试让您的第一个循环迭代到i &lt; 6
  • @nice_remark 该评论中的文字应该是问题所在。问题中不需要当前代码,只是作为您想要的示例..

标签: c loops counter


【解决方案1】:

您可以在建议的 cmets 中使用两个单独的循环,例如 Rafalon。

如果您想要一个循环,您可以执行以下操作(使用 OP 评论中的信息对其进行修改):

int ctr_dir = 80;
int upper_value = 500;
for(int i = 0; i >= 0; i += ctr_dir)
{
  printf("%d", i);
  if (i > upper_value)
    ctr_dir = -80;
}

【讨论】:

  • 一个循环到底有什么好处?它的可读性较差,速度也慢得多。
  • @Lundin 考虑到 OP 的评论,您有灵活性。您可以使用可以由其他线程修改的阈值,或者轻松更改您添加/减去的数量(或再次从另一个线程修改它以切换方向)。虽然速度要慢得多。
  • 谁说过多线程或变量限制?那将完全是另一个问题。编写具有可变条件的循环通常是一个坏主意。这种情况最好使用while循环。
【解决方案2】:

你让这变得不必要的复杂。

for(int i=0; i<6; i++) // print 0 to 5
{
  printf("%d\n", i); 
}

for(int i=0; i<6; i++) // print 5 to 0
{
  printf("%d\n", 5-i);
}

【讨论】:

  • 我的实际问题比这更复杂。我只是把这段代码写下来以展示问题所在
  • 也许你可以多解释一下你真正的问题。
  • @nice_remark 是的,我在发布之前看到了该评论。我仍然不明白为什么你不应该使用两个简单的循环。 while(something) { for(....) {} for(....) {} }.
【解决方案3】:

虽然我不完全理解您编写代码的方式背后的原因,但其中缺少的成分是 if 语句中的 break 将退出循环而不是继续并打印出来6 到 10。

  for(i = 0; i <= 10; i++) {
      printf("i = %d\n", i);
      if(i == 5) {
          int j = i;
          for(j = i; j >= 0; j--) {
              printf("j = %d\n", j);
          }
          break; // Exit the loop
      }
  }

【讨论】:

    【解决方案4】:

    我认为简单最好,但是你说“我的问题更复杂”(我不知道还有多少!?),我写了一个更“复杂”的版本......

    你可以这样做,

    但是这段代码的问题是过冲。即如果步长大于 1,则可以传递最大值。 :)

    #include <stdio.h>
    
    void WaveGenerator(int start, int step, int max, int times)
    {
        int value = start;
        times *= 2;
    
        printf("%d", value);
        while(times)
        {
            value += step;
            if ((value <= start) || (value >= max))
            {
                step *= -1;
                times--;
            }
            printf("%d", value);
        }
    }
    
    int main()
    {
        int i;
    
        WaveGenerator(1, 1, 5, 2);
    
    
        return 0;
    }
    

    【讨论】:

      【解决方案5】:

      这里有许多不同的解决方案,包括我已经作为评论发布的解决方案。

      让我在这里再添加一个,类似于@izlin,但又有所不同:

      int i=0;
      int j=0;
      int max=10;
      
      for(i=0;i<=max;i++)
      {
          printf("%d\n", j);
      
          if(i<max/2)
              j++;
          else
              j--;
      }
      // max=10 > 0 1 2 3 4 5 4 3 2 1 0
      // max=11 > 0 1 2 3 4 5 4 3 2 1 0 -1
      

      请注意,根据max 的奇偶性,这将下降到0-1


      可以这样调整:

      int i=0;
      int j=0;
      int max=10;
      
      for(i=0;i<=max;i++)
      {
          Console.WriteLine(j);
      
          if(i<max/2)
              j++;
          else if(i>(max-1)/2)
              j--;
      }
      // max=10 > 0 1 2 3 4 5 4 3 2 1 0
      // max=11 > 0 1 2 3 4 5 5 4 3 2 1 0
      

      因此,如果max 是奇数,它将写入顶部数字两次,如果是偶数,则写入一次,但始终以0 开头和结尾。


      不过,正如我在评论中建议的那样,我仍然会使用 2 个循环:

      int i=0;
      int max=5;
      
      for(i=0;i<=max;i++)
      {
          printf("%d\n", i);
      }
      // 0 1 2 3 4 5
      for(i=max;i>=0;i--)
      {
          printf("%d\n", i);
      }
      // 5 4 3 2 1 0
      

      【讨论】:

        【解决方案6】:

        由于无论向上还是向下,您要执行的工作都是相同的,因此您不想使用单独的循环,因为您会重复自己。

        您可以通过使用指示您是否已达到上限的标志在单个循环中执行此操作。如果未设置标志,则增加,如果是,则减少。

        int increment = 5, limit = 50;
        int i = 0, go_back = 0;
        
        while (i>=0) {
            printf("%d\n", i);
        
            if (i >= limit) {
                go_back = 1;
            }
            if (go_back) {
                i -= increment;
            } else {
                i += increment;
            }
        }
        

        【讨论】:

        • 或者您可以将内容包装在一个函数中并在两个循环中调用该函数
        猜你喜欢
        • 2016-08-17
        • 2022-07-05
        • 1970-01-01
        • 2020-08-17
        • 1970-01-01
        • 2021-04-07
        • 1970-01-01
        • 1970-01-01
        • 2016-01-23
        相关资源
        最近更新 更多