16

我想知道如果我尽可能多地重用变量名是好是坏(或无关紧要)?例如

int main(void){
  //...
  int x=0;

  //..
  x = atoi(char_var);

  //..

  for (x=0; x<12; x++){
   //...
  }

  //..
  x = socket(...)
  if(x<0){
  //...
  }

  for(x=0;x<100;x++{
  //...
  }

  return 0;
}

可以使用其他变量而不是x上面的变量(可能更好的可读性),但我想知道它是否会给我带来二进制大小、性能或其他方面的任何好处?

4

9 回答 9

22

一般来说,将变量名用于不同目的是非常糟糕的做法——如果其他人稍后需要维护您的代码,则该人将不得不在您的代码中找到这些“上下文切换”,x现在突然意味着与之前的含义不同的东西行代码。

您可能会节省一些内存,但与它所建议的问题相比,这太小了。(也请阅读下面的编辑。)

通常,还建议不要将 1 个字符的变量名称用于循环计数器以外的其他名称。有人可能会争辩说,x它也可能是 X 坐标,但在这种情况下我会使用一些前缀或更长的名称。单字母变量名称太短,无法提供有关变量用途的有意义的提示。

编辑:正如几条评论(和其他一些答案)指出的那样,潜在的内存节省(如果有的话)取决于编译器的好坏。编写良好的优化编译器可能会意识到两个变量没有重叠的生命周期,因此无论如何它们只分配一个变量槽。最终结果将是没有运行时增益,而且源代码更难维护。这只是强化了论点:不要重用变量。

于 2013-07-26T14:44:58.057 回答
8

与编程中的几乎所有内容一样,这取决于情况。

如果您将相同的变量用于不同的目的,那么它会降低您的代码的可读性,您不应该这样做。如果目的相同(例如循环计数器),那么您可以毫无问题地重用,因为这不会使您的代码可读性降低。

重用变量将避免在堆栈中保留空间,这会导致更快(您不会浪费时间在堆栈中保留空间并推送值)和更少的内存消耗(您没有将其存储在堆栈中)程序。但是这种好处在整个程序上下文中绝对可以忽略不计,而且相对于体系结构、语言和编译器也是如此。所以我会更担心可读性而不是这个微小的好处。

于 2013-07-26T14:47:54.337 回答
6

坏的。对于像 s 这样的简单类型int,按值传递,编译器将能够找出何时不需要它们并重用空间。

例如,我在 Visual Studio 2010 中使用 32 位发布模式编译了以下 C++ 代码:

for (int i = 0; i < 4; ++i)
{
    printf("%d\n", i);
}

for (int j = 0; j < 4; ++j)
{
    printf("%d\n", j);
}

并得到以下汇编程序输出:

; 5    :    for (int i = 0; i < 4; ++i)

    mov edi, DWORD PTR __imp__printf
    xor esi, esi
    npad    6
$LL6@main:

; 6    :    {
; 7    :        printf("%d\n", i);

    push    esi
    push    OFFSET ??_C@_03PMGGPEJJ@?$CFd?6?$AA@
    call    edi
    inc esi
    add esp, 8
    cmp esi, 4
    jl  SHORT $LL6@main

; 8    :    }
; 9    : 
; 10   :    for (int j = 0; j < 4; ++j)

    xor esi, esi
$LL3@main:

; 11   :    {
; 12   :        printf("%d\n", j);

    push    esi
    push    OFFSET ??_C@_03PMGGPEJJ@?$CFd?6?$AA@
    call    edi
    inc esi
    add esp, 8
    cmp esi, 4
    jl  SHORT $LL3@main

; 13   :    }

您可以看到编译器同时使用 和的esi寄存器。ij

于 2013-07-26T15:08:45.700 回答
3
  int x=0;

  //..
  x = atoi(char_var);

  //..
  int x = 0;

您不能x在同一范围内重新声明。如果您不是重新声明它而是将其用于不同目的,您可以自由地这样做。但这是一种不好的做法,应该避免,因为它会降低代码的可读性。出于同样的原因,您还应该为变量找到有意义的名称。

于 2013-07-26T14:43:37.067 回答
2

您可以重复使用它,但我认为它不会给您的程序带来任何显着的好处,并且会降低您的代码的可读性。

于 2013-07-26T14:45:26.073 回答
1

一般来说,对于任何语言,如果您重用变量名,然后您决定将部分代码重构为另一种方法,您最终不得不添加或编辑声明。

int i;
for(i = 0; i < 10; ++i) {
    printf("%d\t%d\n", i , i * i);
}
for(i = 0; i < 10; ++i) {
    printf("%d\t%d\n", i , i * i * i);
}

假设您采用第二个循环并将其移至一个print_cubes方法。您将不能只剪切和粘贴 for 循环,因为i那里没有声明。一个好的 IDE 可能能够插入声明,但它可能会担心i您键入的代码中的副作用。

通常,编译器可以通过所谓的图形着色算法来合并使用的变量。考虑这个变体:

for(int i = 0; i < 10; ++i) {  // BLOCK 1
    printf("%d\t%d\n", i , i * i);
} // END BLOCK 1
for(int j = 0; j < 10; ++j) { // BLOCK 2
    printf("%d\t%d\n", j , j * j * j);
} // END BLOCK 2

编译器列出了使用的变量:i, j. 它列出了正在使用的块:BLOCK 1,BLOCK 2。父函数也是一个块,但仅在 BLOCK 1ijBLOCK 2 中可见。因此,它制作了变量图,并仅在它们存在时才连接它们在同一块中可见。然后,它尝试计算为每个顶点着色所需的最小颜色数,而不给两个相邻顶点相同的颜色,类似于 Haken-Appel 四色定理。这里; 只需要一种颜色。

于 2013-07-26T15:13:27.027 回答
1

这么说吧——如果我以这种方式写了一大堆未记录的复杂代码,然后你得到维护/增强它的工作,你会怎么想。

请不要做这样的事情,永远:)

于 2013-07-26T17:09:59.297 回答
0

最好在内存方面重用变量。但请注意,在重用变量之前,您不需要变量中的值。除此之外,您不应始终使用该变量。保持干净和可读的代码很重要。所以我建议你根据上下文选择不同的变量名称,这样你的代码就不会变得混乱。

您还应该看看 C 中的动态内存分配,这对于管理内存和变量非常有用。

https://en.wikipedia.org/wiki/C_dynamic_memory_allocation

于 2013-07-26T14:48:21.137 回答
-2

唯一的缺点是代码的可读性。

重用变量可以节省内存。

速度不受影响(除非您必须使用更多指令才能重用变量)。

于 2013-07-26T14:44:58.793 回答