不了解某些编程模式

Not understanding some programming patterns

本文关键字:模式 编程 不了解      更新时间:2023-10-16

当我阅读经验丰富的程序员代码时,我意识到一些我不认为优化代码的模式。我一直在谷歌上搜索这个,但没有关于我能找到的主题的讨论。

在程序开始时声明所有变量的原因是什么?例如,为什么有人使用:

GtkWidget *window;
gtk_init(NULL, NULL);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

而不是

gtk_init(NULL, NULL);
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

或者,例如,为什么要为循环声明一个变量i,例如

int i;
char *a;
(code)
for(i = 0; i < n; i++)

而不是在 for 循环上方声明i

char *a;
(code)
int i;
for(i = 0; i < n; i++)

我认为它会更容易阅读。这不就是在泄露记忆吗?因为在调用for之前,内存中有 4 个字节未使用。

我不记得我曾经在其他代码中看到的其他模式,但我经常发现这样的事情,我想知道为什么是这样的;特别是如果它们没有优化(我猜)。我问有些人为什么他们这样做,但他们要么告诉我他们是这样教的,要么他们被冒犯了,就像我不应该问的那样。

我真的很想知道为什么程序员要这样构建他们的代码,以便理解和改进我的编码。如果您对如何构建代码有任何建议或有关良好编程行为的提示,请告诉我。

这不就是在泄露记忆吗?因为在调用 for 之前,内存中有 4 个字节未使用。

我不这么认为。在我工作过的常见平台 Linux 和 Windows 中,无论您是在函数顶部声明变量还是随时声明变量,堆栈帧的大小都是相同的。

函数顶部声明变量会产生不利影响的唯一情况是对象的构造成本很高。

大多数情况下,是在函数顶部声明它们还是根据需要声明它们,都是开发团队中的策略决策。

旧版本的C(K&R C,C89)要求在块中的任何代码之前声明所有变量。 直到 C99 标准,声明才可以与代码混合(C++显然更早地这样做了)。 至于为什么会这样,请记住,C 是 1970 年代早期的产物,当时 256 千字是很多内存,处理器速度比今天慢几个数量级。 任何简化解析和代码生成的东西都是一件好事,强迫你把声明组合在一起有助于做到这一点(请注意,许多与 C 同时代的人,如 Fortran 和 Pascal 也强制所有声明发生在函数或块的开头)。

至于内存,大多数编译器将生成代码,以便在函数入口时为所有块范围对象分配存储,而不管声明在源代码中实际发生在哪里。 IOW,两个片段

int i;
// bunch of code here
for ( i = 0; i < 10; i++ ) 
  do_something_interesting();

// bunch of code here
for ( int i = 0; i < 10; i++ ) 
  do_something_interesting();

将(最有可能)产生相同的机器代码,该机器代码在功能输入时为i分配空间。

延迟声明(无论如何,在 C 中)的唯一真正优势是使代码更易于阅读和维护。 它对运行时性能几乎没有影响(编译器可能会根据声明内容的位置进行略有不同的优化,但 IME 不会发生太多)。

在您描述的情况下,任何体面的优化编译器都会缩短int或指针的有效生存期,以实现通过缩短的生存期实现的任何性能改进。

所以早期的声明C++风格不好(在现代版本的 C 中是糟糕的 C 风格)。 但是你需要一个更困难的例子来生成效率较低的代码。

阅读代码的人

没有编译器那么多的内存,因此任何声明的生存期超过其有用生存期的变量都会让任何试图理解你的代码的人感到困惑。 首先担心这一点,并且(大多数时候)让编译器编写者担心性能。

来自 http://www.dummies.com/how-to/content/declaring-variables-in-c.html:"这样,编译器就知道变量叫什么,变量是什么类型(它们可以包含什么值)"

我认为这篇文章是相关的:在哪里你可以和不能在 C 中声明新变量?