【问题标题】:Is if(TRUE) a good idea in C?if(TRUE) 在 C 语言中是个好主意吗?
【发布时间】:2009-02-12 15:12:06
【问题描述】:

在C编程语言中,我的理解是变量只能在代码块的开头定义,并且变量将具有声明它的块的范围。考虑到这一点,我想知道像本例那样人为地创建新范围是否被认为是不好的做法:

void foo()
{
     ... Do some stuff ...

     if(TRUE)
     {
         char a;
         int b;

         ... Do some more stuff ...
     }

     ... Do even more stuff ...
 }

假设在宏定义中将 TRUE 设置为 1,这段代码会被认为是“好代码”,还是会让经验丰富的程序员一想到它就畏缩?

感谢您的意见!

编辑:为了回应一些答案,我正在使用的代码需要与一些非常古老的遗留系统一起使用。虽然在 C99 的假设上进行操作会很好,但我们真的不能保证他们会拥有它。

【问题讨论】:

  • afaik,{} 有自己的范围正弦 ansi C(大约是 1990 年)
  • 典型的用例是调试,您可以轻松地在 if (42) 和 if (0) 之间切换,而不是评论。
  • 你的标题根本没有真正描述这个问题。似乎您在问定义 TRUE 是否是一种好习惯。

标签: c if-statement


【解决方案1】:

您甚至不需要 if 语句。您可以使用 {}

创建块

不过,这应该是一个单独的函数。

这里的例子:

#include <stdio.h>

int
main(int argc, char **argv) {
    int i = 0;
    {
        int i = 10;
        printf("%d\n", i);
    }
    printf("%d\n", i);
}

【讨论】:

  • 这曾经在生产代码中使用过吗?我的想法是我想访问现有函数中的所有变量,但一些新变量仅适用于一小部分。一个函数意味着我必须传递一大堆变量,并将变量添加到主...
  • ...函数会使函数的现有变量变得混乱
  • 我的公司广泛使用它。当我开始在这里工作时,我曾经非常反对它,但现在我喜欢它。我仍然不喜欢我们使用它的方式,这通常是将 1000 行函数分解成块,这些函数应该是它们自己的函数......
  • 作用域是个好东西,我也倾向于使用它。通过使用相同的名称来隐藏变量.. 不是那么多;)
  • 在 C++(而不是 C)中,这被广泛使用。一个普遍的例子是互斥锁的锁类,它将互斥锁锁定在其构造函数中,并在其析构函数中解锁。在堆栈上创建一个锁变量,然后保护一个与该块具有相同范围的临界区。
【解决方案2】:

据我所知,您可以在没有 if 的情况下创建范围。

像这样只使用大括号:

{
    int x;

}

我反对

if (TRUE)

因为它妨碍了可读性。

【讨论】:

  • 特别是如果你#define TRUE 0
【解决方案3】:

您可能希望为该范围创建一个新函数。
如果它真的需要有自己的作用域,它可能是一个单独的逻辑函数。

【讨论】:

  • 不一定。我经常遇到需要一些高度局部变量(具有良好的助记名称)来保存仅几行的一些中间值。通过使用嵌套范围,您可以明确其预期(受限)用途。
【解决方案4】:

由于您可以在没有 if 的情况下创建范围块,所以这是一个更好的主意。

void foo() {
     ... Do some stuff ...
     {
         char a;
         int b;
         ... Do some more stuff ...
     }
     ... Do even more stuff ...
}

【讨论】:

    【解决方案5】:

    请注意,在 C99 中,允许在块的中间声明局部变量。

    C99 是 1999 年的 C 标准版本;大多数现代 C 编译器都支持它。

    【讨论】:

      【解决方案6】:

      首先,新块不需要是 if 块。它可能只是一段用大括号括起来的代码,如下所示:

      void foo() {
       ... Do some stuff ...
      
       {
           char a;
           int b;
      
           ... Do some more stuff ...
       }
      
       ... Do even more stuff ...
      }
      

      其次,在任何符合 C 标准(我认为是 C99)的现代 C 编译器中,您可以在块中的任何位置声明变量,因此您根本不需要创建新块。

      【讨论】:

        【解决方案7】:

        你可以删除

        if(TRUE)
        

        只留下花括号,花括号本身定义了一个新的句法块 - compound statement

        这绝对比之前的 false 更干净,但你可能仍然想问自己为什么要创建一个新块 - 定义一个子例程会更好吗?

        【讨论】:

          【解决方案8】:

          正如许多答案已经说过的那样,您不需要“如果”的东西。只需创建裸块。但我想再谈一点。在 C 中,您可以在块中的任何位置创建变量声明,而不仅仅是在开始处。在 C89 中,您有这个限制。从 C99 开始(现在已经 10 年了),您不再有这种限制,尽管有些编译器无论如何都会抱怨。但是,如果您告诉 GCC 使用带有 -std=c99 选项的最新“最新”C 标准,则 GCC 不会。

          因为仍然存在默认情况下抱怨的编译器,但我不喜欢混合声明和代码。出于兼容性原因,我会继续将声明放在块的开头。

          【讨论】:

          • 是的,我认为这是 C 语言中的不良做法。如果您使用 -Wall -ansi -pedantic 进行编译,您会收到警告。我的经验法则是,如果它没有通过这些标志,通常是错误的。
          • BobbyShaftoe。嗯,这是一个有效的观点。但我不认为这是不好的做法。我避免使用 -Werror 正是因为有时编译器可能会错误地发出警告。那么,如果它警告正确评论的“... { ... } ...”,对我来说是误报。
          【解决方案9】:

          我不会称自己经验丰富,但我有点畏缩。

          我的问题是 if 语句会导致某人相信某些东西实际上正在被评估......但是在运行时,宏要么是真要么是假的,它不会改变为其他东西。您应该包含代码或不包含代码。

          如果你的意思是像#ifdef DEBUG 这样你应该这样做以向读者表明这是调试代码......

          【讨论】:

          • 宏是在编译时评估的,而不是运行时。
          【解决方案10】:

          为一些有创造力的人敞开大门:

          #define TRUE 0
          #define FALSE 1
          

          只需使用大括号来声明范围。

          【讨论】:

            【解决方案11】:

            我认为您不需要 if(true) 部分。

            只需要 { } 来确定变量的范围。

            【讨论】:

              【解决方案12】:

              我的回答如下:

              这让经验丰富的程序员一想到它就畏缩不前。

              【讨论】:

                【解决方案13】:

                只需在块的开头定义变量或使用其他函数。添加带有空 {} 或任何替代项的人工作用域不是好的做法。

                【讨论】:

                  【解决方案14】:

                  C99 允许您在几乎任何地方声明变量。但是,不要在没有充分理由的情况下这样做。首先尝试将您的函数拆分为更小的(可能是内联的)函数。

                  这样的事情可能有意义的唯一地方是当你有一个在你的函数中间初始化的变量时,例如类似于在 C++ 中创建对象。

                  【讨论】:

                  • 我不知道你为什么说不要这样做。如果我需要一个简单的 int 或 char,在将要使用它的代码附近声明它似乎更简洁,而不是将它发送到函数的顶部。这样做我放弃了什么?
                  • 在第一次使用时声明变量被认为是 C++ 中的好习惯。为什么不在 C99 中?
                  • @David Thornley:C 通常允许程序员编写很长的函数,由于缺乏 OOP 语言特性,比 C++ 更有可能。在函数的开头有很多变量是一个很好的迹象,表明它太长了。练习可以成为一种习惯。但在首次使用前声明是合法的
                  【解决方案15】:

                  我认为您正在处理一些过时的假设。几个月来,我一直在使用 GCC 直接编写 C 代码,您不需要在块的开头声明变量,即使第二版 K&R 说您必须这样做。你可以在任何地方声明你的变量,就像这个不太有用的例子:

                  char* palstring;
                  palstring = malloc(LARGEST_STRING);
                  memset(palstring, 0, sizeof palstring);
                  fgets(palstring, LARGEST_STRING, fin);
                  
                  char* cur = palstring;
                  char letter;
                  letter = *cur;
                  

                  所以没有必要按照你的建议去做。语言已经发展。

                  C 语言的另一个很好的补充是可变长度数组,它允许您将数组连同其大小一起传递给函数。在过去,你所能做的就是传递一个指针。

                  【讨论】:

                  • 小心 gcc 的可变长度数组不是 C99 标准
                  • 啊,很高兴知道。谢谢你。我主要是自己玩玩,所以我不太担心,但如果我必须专业使用它,我会欠你一杯啤酒。 :)
                  【解决方案16】:

                  假设您使用旧编译器(就像我一样,它适用于旧硬件),您像其他人建议的那样跳过 if(TRUE),并且您有一个非常巨大的功能(女巫您不应该在第一名),那我觉得还可以。 我做了,但是感觉不太好……

                  【讨论】:

                    【解决方案17】:

                    显然我是少数,但我发现“只是大括号”更难阅读,因为它偏离了通常的模式。在(诚然不常见的)我想要一个范围块而不定义另一个函数的情况下,我更喜欢包含“if”,但没有任何宏并带有注释来解释原因:

                    if( 1 ) // just to establish scope
                    {
                       // do stuff here
                    }
                    

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 2021-11-03
                      • 1970-01-01
                      • 2010-11-05
                      • 1970-01-01
                      • 1970-01-01
                      • 2013-04-02
                      • 2020-03-29
                      相关资源
                      最近更新 更多