不了解某些编程模式
Not understanding some programming patterns
当我阅读经验丰富的程序员代码时,我意识到一些我不认为优化代码的模式。我一直在谷歌上搜索这个,但没有关于我能找到的主题的讨论。
在程序开始时声明所有变量的原因是什么?例如,为什么有人使用:
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 中声明新变量?
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 有一个打印语句的函数是一种糟糕的编程实践吗
- 为什么在保护模式下继承升级不起作用
- 如何在全屏模式下(在OpenGL中)使背景透明
- 为什么使用__LINE_的代码在发布模式下在MSVC下编译,而不是在调试模式下
- 派生类是否可以在抽象工厂设计模式中具有数据成员
- 我是C++编程的新手,这些代码之间有什么区别,我应该使用哪一个
- 此模式的C++RegEx
- avrogencpp能为模式中的每种类型生成单独的头文件吗
- 使用可变模板的Broadcaster/Listener模式
- c++方法参数只能在linux的发布模式下自行更改
- 模板元编程:如何将参数包组合成新的参数包
- 将 GtkTreeView 中的单元格设置为以编程方式编辑模式
- C++模板元编程:如何在表达式模式中推断类型
- 不了解某些编程模式
- 在epoll边缘触发模式下,哪些常见的编程错误会导致CLOSE_WAIT卡住?
- 在镜像模式下以编程方式改变屏幕方向
- 如果字符位于引号之间,则不匹配(AKA具有编程字符串模式)
- 我在编程面试中遇到的问题:反转一个字符串,找出数组的模式
- 关于设计模式和高级编程的好书,而不是头优先