if(TRUE) 在 C 语言中是个好主意吗?

Is if(TRUE) a good idea in C?

提问人:Tim 提问时间:2/12/2009 最后编辑:userTim 更新时间:4/3/2012 访问量:32281

问:

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

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

     if(TRUE)
     {
         char a;
         int b;

         ... Do some more stuff ...
     }

     ... Do even more stuff ...
 }

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

感谢您的输入!

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

c if 语句

评论

0赞 George 2/12/2009
afaik, {} 有自己的范围 sine ansi C(即大约 1990 年)
0赞 ypnos 2/12/2009
典型的用例是调试,您可以在 if (42) 和 if (0) 之间轻松切换,而不是注释。
0赞 BobbyShaftoe 2/13/2009
你的标题根本没有真正描述这个问题。你似乎在问定义 TRUE 是否是好的做法。

答:

7赞 Lars Mæhlum 2/12/2009 #1

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

评论

2赞 joel.neely 2/13/2009
不一定。我经常遇到需要一些高度局部变量(带有一个漂亮的助记符名称)来保存几行的中间值。通过使用嵌套范围,可以明确其预期(受限)用途。
3赞 Jason Punyon 2/12/2009 #2

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

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

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

评论

0赞 Jonathan Leffler 2/13/2009
宏在编译时计算,而不是在运行时计算。
2赞 VBNight 2/12/2009 #3

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

只需 { } 即可确定变量的作用域。

2赞 Magilla Gorilla #4

我的回答如下:

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

6赞 chaos 2/12/2009 #5

由于您可以只使用没有 if 的示波器块,因此这是一个更好的主意。

void foo() {
     ... Do some stuff ...
     {
         char a;
         int b;
         ... Do some more stuff ...
     }
     ... Do even more stuff ...
}
16赞 George 2/12/2009 #6

据我所知,您可以创建一个没有 if 的作用域。

只使用大括号,如下所示:

{
    int x;

}

我建议不要

if (TRUE)

因为它阻碍了可读性。

评论

7赞 Pete Kirkham 2/12/2009
特别是如果你 #define 真 0
52赞 Philip Reynolds 2/12/2009 #7

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

然而,这可能应该是一个单独的功能。

示例如下:

#include <stdio.h>

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

评论

0赞 Tim 2/12/2009
这是否曾经在生产代码中使用过?我的想法是,我希望能够访问现有函数中的所有变量,但一些新变量仅适用于一小部分。一个函数意味着我必须传递一大堆变量,并将这些变量添加到主变量中......
0赞 Tim 2/12/2009
...函数会使函数的现有变量混乱
0赞 rmeador 2/12/2009
我的公司广泛使用它。当我开始在这里工作时,我曾经非常反对它,但现在我喜欢它。不过,我仍然不喜欢我们使用它的方式,这通常是将 1000 行函数的块分解,这些函数应该是它们自己的函数......
3赞 ypnos 2/12/2009
范围界定是一件好事,我也倾向于使用它。使用相同的名称对变量进行重影 ..没那么多;)
5赞 2/13/2009
在 C++(而不是 C)中,它被广泛使用。一个普遍的例子是互斥锁的锁类,它将互斥锁锁定在其构造函数中,并在析构函数中解锁它。然后,在堆栈上创建锁变量可以保护与块作用域相同的关键部分。
4赞 Mark Pim 2/12/2009 #8

您可以删除

if(TRUE)

只留下大括号,它们本身定义了一个新的句法块 - 复合语句

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

5赞 Avi 2/12/2009 #9

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

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

 {
     char a;
     int b;

     ... Do some more stuff ...
 }

 ... Do even more stuff ...
}

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

3赞 Anonymous 2/12/2009 #10

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

#define TRUE 0
#define FALSE 1

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

1赞 Eduard - Gabriel Munteanu 2/12/2009 #11

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

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

评论

0赞 rtperson 2/12/2009
我不确定你为什么说不要这样做。如果我需要一个简单的 int 或 char,那么在将要使用它的代码附近声明它似乎更干净,而不是将其发送到函数的顶部。我这样做放弃了什么?
0赞 David Thornley 2/13/2009
在首次使用时声明变量被认为是 C++ 中的良好做法。为什么不在 C99 中?
0赞 Eduard - Gabriel Munteanu 2/13/2009
@David Thornley:C语言通常允许程序员编写很长的函数,由于缺乏OOP语言特性,这比C++更有可能。在函数的开头有许多变量是一个好兆头,表明它太长了。练习可以成为一种习惯。但是在首次使用之前声明可能是合法的
1赞 rtperson 2/12/2009 #12

我认为你正在使用一些过时的假设。几个月来,我一直在使用 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 语言的另一个很好的补充是可变长度数组,它允许您将数组及其大小传递给函数。在过去,你所能做的就是传入一个指针。

评论

0赞 Martin Beckett 2/12/2009
小心 gcc 的可变长度数组不是 C99 标准
0赞 rtperson 2/12/2009
啊,很高兴知道。谢谢。我主要是用它来自己闲逛,所以我不太担心,但如果我必须专业地使用它,我会欠你一杯啤酒。:)
4赞 Johannes Schaub - litb 2/12/2009 #13

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

因为仍然存在默认呻吟的编译器,所以我不喜欢混合声明和代码。出于兼容性原因,我会继续将声明放在块的开头。

评论

0赞 BobbyShaftoe 2/14/2009
是的,我认为 C 语言中的这种不良做法。如果使用 -Wall -ansi -pedantic 进行编译,则会收到警告。我的经验法则是,如果它没有干净地通过这些标志,那通常是错误的。
0赞 Johannes Schaub - litb 2/14/2009
鲍比·沙夫托(BobbyShaftoe)。嗯,这是一个有效的观点。但我不认为这是不好的做法。我避免使用 -Werror 正是因为有时编译器可能会错误地发出警告。那么,如果它警告“......{ ... }..."正确评论,对我来说是误报。
6赞 starblue 2/12/2009 #14

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

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

1赞 c0m4 2/12/2009 #15

假设你使用一个旧的编译器(像我一样,它用于旧硬件),你像其他人建议的那样跳过if(TRUE),并且你有一个非常巨大的函数(女巫你不应该首先拥有),那么我认为这有点可以。 我已经做到了,但感觉不太好......

1赞 Eric 2/13/2009 #16

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

if( 1 ) // just to establish scope
{
   // do stuff here
}
2赞 BobbyShaftoe 2/13/2009 #17

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