我正在查看一些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将小序列与大型参考序列对齐,以防任何人想知道。此代码示例与应用程序的功能并不特别相关。
答案 0 :(得分:89)
在C89中,你不能只在任何地方int i;
;声明仅在块的开头有效。
所以:
a = 1;
int i; /* error */
i = 2;
...无效,但
a = 1
if (e) {
int i;
......很好,就像一个普通的街区。
即使在声明生效(C99)块项目(s)之后,结果样式仍然继续,部分是惯性,部分是为了向后移植,并且还因为建立新的范围是有意义的声明。
答案 1 :(得分:38)
范围变量。例如。变量tmp_argv
仅在大括号之间有效。
答案 2 :(得分:7)
块是一个范围,用于确定变量的生命周期以及它们对编译器的可见性。因此,当控件退出块时,在块中创建的变量就会消失。
当这些变量是带有构造函数和析构函数的类的实例时,它会非常方便。
但是,在你的例子中没有太大的优势。
答案 3 :(得分:6)
正在创建一个范围。堆栈对象超出范围时会被销毁。看起来它正在进行某种打字,这意味着每个块都是他们想要的时间。但是,我没有看到任何作用域计时器对象,所以,是的,没有任何意义。
答案 4 :(得分:6)
我最近发现的另一个用例就是当你有开/关语义并想要清楚地标记'内部'代码时:
f = fopen('file');
{
// do stuff
}
fclose(f);
这很有效,可以提醒您关闭/释放对象,并使代码更清晰。
答案 5 :(得分:5)
您在块中声明的变量是该块的本地变量。通过这种方式,您可以在代码的其他位置(下方)重新定义tmp_argv
,而不会与此代码冲突。
答案 6 :(得分:1)
这就是全部吗?也许程序员在代码中的其他地方使用tmp_argv
。我想不出任何其他原因,因为tmp_argv
和{
之间的}
与大括号之外的任何内容都是分开的。
答案 7 :(得分:1)
我有时会在这些情况下使用块: - 本地化变量 - 或者更容易阅读 ...
答案 8 :(得分:-2)
嗯 - 我可能会离开这里的图表,但我认为这个区域内的局部变量定义在块之外是无效的