为啥将 C 代码块用花括号括起来?
Posted
技术标签:
【中文标题】为啥将 C 代码块用花括号括起来?【英文标题】:Why enclose blocks of C code in curly braces?为什么将 C 代码块用花括号括起来? 【发布时间】:2010-12-13 06:17:56 【问题描述】:我正在查看一些 C 代码,并注意到它充满了围绕代码块的大括号,没有任何类型的控制结构。看一看:
//do some stuff . . .
fprintf(stderr, "%.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC);
//a block! why not?
char *tmp_argv[3];
tmp_argv[0] = argv[0]; tmp_argv[1] = str; tmp_argv[2] = prefix;
t = clock();
fprintf(stderr, "[bwa_index] Convert nucleotide PAC to color PAC... ");
bwa_pac2cspac(3, tmp_argv);
fprintf(stderr, "%.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC);
为什么要在代码中插入这样的块?它充满了他们。有某种性能优势吗?一些神秘的C东西?为什么???
编辑:此代码来自BWA,这是一个使用Burrows-Wheeler transform 将小序列与大参考序列对齐的生物信息学程序,以防你们中的任何人想知道。此代码示例与应用程序的功能并不是特别相关。
【问题讨论】:
这种做法在 C 和 C++ 中可能有不同的动机。您的代码看起来像 C,而您的问题被标记为C++
。你确定你正确地标记了你的问题吗?
啊,不错。这确实是 C。我不知道为什么我认为它是 C++。更改了标签。
然后也编辑文本。它仍然说“我正在查看一些 C++ 代码......”
【参考方案1】:
需要遗留代码 才能进行声明
在 C89 中,您不能只在任何地方执行 int i;
;声明仅在块的开头有效。
所以:
a = 1;
int i; /* error */
i = 2;
...无效,但是
a = 1
if (e)
int i;
...很好,就像一个普通的块一样。
即使在声明变得有效 (C99) block-item(s) 之后,所产生的样式仍然继续存在,部分原因是惯性,部分原因是为了向后可移植性,还因为建立新的范围是有意义的声明。
【讨论】:
严格来说,声明在 C 中从未变成 语句。即使在 C99 中,声明也不是 not 语句。在 C++ 中它们是,但在 C 中不是。 基于这个答案,它可能表明不再需要普通的块成语。事实上,许多人喜欢继续使用它来限制他们创建的变量的范围,即使不再需要在块中间声明新变量。我认为范围界定答案比传统答案更重要,尽管 C89 兼容性也是这样做的一个很好的理由(因为很少有编译器能很好地实现 C99)。 @AndreyT:叹息,你是对的,当时这么说确实让我有点困扰。作为记录:-) C89:复合语句 ::= 声明列表(选择)语句列表(选择),而在 C99 中:块项目 ::= 声明 |声明。 如果您在家庭逆向计算实验室或虚拟机中回溯到足够远的地方,您只会得到功能块的开头,而不是内部块。【参考方案2】:范围变量。例如。变量tmp_argv
仅在大括号之间有效。
【讨论】:
虽然这里似乎不是这种情况,但作用域的结束会触发析构函数,这些析构函数直到以后才会被触发。 @Keith: +1 我过去常常在我的多线程代码中做这种事情,创建类会在其 ctor 中锁定互斥锁并在 dtor 中解锁它【参考方案3】:我最近发现的另一个用例是当你有打开/关闭语义并且你想清楚地标记“内部”代码时:
f = fopen('file');
// do stuff
fclose(f);
这可以很好地提醒您关闭/释放对象,并使代码更加简洁。
【讨论】:
【参考方案4】:块是一个范围,它决定了变量的生命周期,以及它们对编译器的可见性。因此,当控制退出块时,在块内创建的变量就会消失。
当这些变量是具有构造函数和析构函数的类的实例时,它会非常方便。
但是,在您的示例中并没有太大优势。
【讨论】:
【参考方案5】:它正在创建一个范围。堆栈对象在超出范围时被销毁。看起来它正在做某种类型的打字,这意味着每个块都是他们想要计时的东西。但是,我没有看到任何作用域计时器对象,所以,是的,没有任何意义。
【讨论】:
【参考方案6】:您在块内声明的变量是该块的本地变量。这样您就可以在代码的其他位置(如下)重新定义tmp_argv
,而不会与这段代码冲突。
【讨论】:
【参考方案7】:就这些了吗?也许程序员在代码的其他地方使用了tmp_argv
。我想不出任何其他原因,因为 和
之间的
tmp_argv
与大括号之外的任何内容都是分开的。
【讨论】:
不,还有很多。我只是随便举了一个例子。 那么程序员在大括号外的范围内使用tmp_argv
吗?【参考方案8】:
我有时会在这些情况下使用块: - 本地化变量 - 或者更容易阅读 ...
【讨论】:
【参考方案9】:嗯 - 我可能不在此处列出,但我认为在此类块内定义的局部变量在块外将无效
【讨论】:
以上是关于为啥将 C 代码块用花括号括起来?的主要内容,如果未能解决你的问题,请参考以下文章