C 哪个环路更好?

C 哪个环路更好?,c,C,我是C语言的初学者;想知道下面哪种代码更适合打印1和给定数字之间的奇数整数 //预编码:n>0 无效打印\u奇数\u整数(整数n){ int i; 对于(i=1;i=0 无效打印\u奇数\u整数(整数n){ int i; 对于(i=1;i而言,它们在功能上是相同的,因此,除非您真的需要最高性能,否则这并不重要 但是,如果您跳过if语句,则解决方案会非常有效。您跳过了一半的数字,并且不需要使用模检查条件。绝对是第一个。 原因: -更少的代码行 -如果有其他方法处理这种情况,则主要避免使用分支语

我是C语言的初学者;想知道下面哪种代码更适合打印1和给定数字之间的奇数整数

//预编码:n>0
无效打印\u奇数\u整数(整数n){
int i;
对于(i=1;i=0
无效打印\u奇数\u整数(整数n){
int i;

对于(i=1;i而言,它们在功能上是相同的,因此,除非您真的需要最高性能,否则这并不重要


但是,如果您跳过
if
语句,则解决方案会非常有效。您跳过了一半的数字,并且不需要使用模检查条件。

绝对是第一个。
原因:

-更少的代码行

-如果有其他方法处理这种情况,则主要避免使用分支语句(if、if-else、switch cases等)。

-这两种算法的时间复杂度是相同的O(n)。所以这主要是哪个代码更完美的问题。请记住,可读性更强的代码更漂亮

编辑

  • 第一个解决方案在边缘具有未定义的行为这一事实是显而易见的。但这些输入验证必须在算法部分之外进行检查。强烈建议不要将验证代码与逻辑混合使用。您可以轻松地在函数的第一部分检查
    i
    ,如果
    i==INT\M,则打印
    INT\u MAX
    AX-1
    i==INT\u MAX

    • 第二种解决方案是“专业”方式

      您可以更改的一件事是布局:

      void print_odd_integers(int n)  
      {
          int i;
          for (i=1; i<=n; i++)
          {
              if (i%2 != 0)
              {
                  printf("%d\n", i);
               }
          }
          printf("End.\n");
          system("Pause"); //So you can see what you did :)
      }
      
      void print\u奇数\u整数(int n)
      {
      int i;
      
      对于(i=1;i如果
      n
      不是像
      INT_MAX
      那样的极端情况,并且当
      i
      从奇数整数开始时,因为它已经跳过了一半的迭代次数,则使用第一个循环


      否则使用第二个循环,因为如果由于算术溢出,第一个循环将成为无限循环,如果
      n=INT\u MAX
      两个循环都有未定义的行为

      • 第一个循环可能会给您带来更好的性能

      • 如果以后将代码更改为从任意值开始,则第二个循环可能更具可读性(对于初学者),并且不太容易出错

        我会在
      主体的
      周围使用大括号,因为它不是简单的单行语句,在二进制运算符周围使用空格可以提高可读性:

      void print_odd_integers(int n)  {
          int i;
          for (i = 1; i <= n; i++) {
              if (i % 2 != 0)
                  printf("%d ", i);
          }
          printf("\n");
      }
      
      void print\u奇数\u整数(int n){
      int i;
      
      对于(i=1;我在什么意义上更好?我被逐字逐句地问到“哪一个更好”,没有具体说明什么依据或什么术语-对此很抱歉!@Brianley我冒昧地编辑了一下这个问题,因此它不会以“主要基于意见”的方式结束。如果您不同意我的编辑,请随时回滚。您只需转储每个循环生成的程序集并进行比较即可轻松回答问题。对于gcc,只需在顶部添加
      #include
      ,在函数名末尾添加
      1
      2
      ,将其保存为
      loop.c
      ,然后添加
      gcc-S-ma即可sm=intel-o loops.asm loops.c
      (如果用户感兴趣,可以添加不同级别的优化以检查差异)。你会发现循环1仅凭指令和分支计数就赢了。你觉得哪一个更容易阅读?它们在功能上不一样。第一个循环在n=INT\u MAX-1时表现出未定义的行为。@PaulHankin它们在功能上有什么不同?在我看来,它们似乎会打印完全相同的内容。@emptyAsenal If
      n=INT\u MAX-1
      那么什么是
      n+2
      ?未定义的行为。不管怎样,一旦达到最大int,您就会遇到问题,因为他正在使用
      ,当
      n=int\u max
      时,第二个循环不也可能无限执行吗?无论如何,它在两个版本的循环中都存在。第二个解决方案是“专业”方式。不完全是这样。此外,你的布局被破坏了,
      系统(“暂停”);
      完全不专业。布局仍然被破坏了……你投票反对我了吗?被破坏了?我认为在这个基本程序中,可以使用“系统(“暂停”)……NASA可能会在使用代码飞往火星之前检查代码:D
      系统(“暂停”);
      是一种特定于窗口的技巧,用于防止在运行非GUI程序时自动关闭外壳程序窗口。在现有外壳程序窗口中的命令提示符下运行该程序可避免此类解决方法的需要。布局仍然中断,因为
      }
      没有对齐。没什么大不了的,但是因为这是OP代码的唯一变化,所以它应该是一致的,比如说。我宁愿
      void printOdd(int I){unsigned counter=0;unsigned number;while((number=)((counter++@Peter_J):你有趣的建议实现了与OP代码不同的语义(应该包括结束值)并且它不会解决架构上的
      INT\u MAX==UINT\u MAX
      -)
      INT\u MAX==UINT\u MAX
      任何示例(a不是1的补码,因为这些机器不再存在0,除了一些偏心的向后兼容univac兼容模式。顺便说一句,我相信C编译器从未为该体系结构实现过)我并没有暗示存在这样的体系结构,两者都可以解释这一点。我正在研究的原型DS9K将有一个兼容的C编译器和建议的方法,使用
      DS9K-在这个例子中,我总是说:作为死亡机器,它将在任何程序执行之前爆炸:).我不是理论家,这是一门实用科学。如果我曾经用这种约束对真正的机器进行编程,我将采取适当的步骤来避免UBs-无除法(mod)操作
      I%2
      @i486如果你愿意,建议编辑,我接受,tnx。
      void print_odd_integers(int n)  {
          int i;
          for (i = 1; i <= n; i++) {
              if (i % 2 != 0)
                  printf("%d ", i);
          }
          printf("\n");
      }
      
      void print_odd_integers(int n)  {
          for (int i = 1; i <= n; i += 2) {
              printf("%d", i);
              if (i == n)
                 break;
          }
          printf("\n");
      }