重用变量是好还是坏?

时间:2013-07-26 14:41:22

标签: c variables

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

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(可能更好的可读性),但我想知道它是否会为二进制大小,性能或其他任何东西带来任何好处?

9 个答案:

答案 0 :(得分:19)

一般来说,为不同目的重复使用变量名称是非常糟糕的做法 - 如果其他人需要稍后维护您的代码,则必须在代码中找到这些“上下文切换”,其中x现在突然意味着在该行代码之前的其他内容。

您可能会节省一些内存,但与其引入的问题相比,这是一个很小的内容。 (也请阅读下面的编辑。)

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

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

答案 1 :(得分:7)

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

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

重用一个变量将避免在堆栈中保留空间,这会导致更快(您不会浪费时间在堆栈中保留空间并推送值)并减少内存消耗(您不会将其存储在堆栈中)程序。但是这种好处在整个程序环境中是绝对可以忽略不计的,也与架构,语言和编译器有关。所以我更担心可读性而不是这个微小的好处。

答案 2 :(得分:4)

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

例如,我使用32位发布模式在Visual Studio 2010中编译了以下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   :    }

您可以看到编译器正在为esii使用j寄存器。

答案 3 :(得分:3)

  int x=0;

  //..
  x = atoi(char_var);

  //..
  int x = 0;

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

答案 4 :(得分:2)

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

答案 5 :(得分: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

编译器列出了使用过的变量:ij。它列出了正在使用的块:BLOCK 1,BLOCK 2.父函数也是一个块,但ij仅在块1和块2中可见。因此,它生成一个图表变量,只有在同一个块中可见时才连接它们。然后,它尝试计算为每个顶点着色所需的最小颜色数,而不给两个相邻的顶点使用相同的颜色,类似于Haken-Appel Four Color Theorem。这里;只需要一种颜色。

答案 6 :(得分:1)

这样说 - 如果我以这种方式编写了大量未记录的复杂代码,你会怎么做呢?然后,你得到维护/增强它的工作。

请不要做这样的事情:)

答案 7 :(得分:0)

最好根据内存重用变量。 但是请注意,在重用之前不需要变量中的值。 除此之外,你不应该总是使用变量。保持清晰易读的代码非常重要。因此,我建议您根据上下文选择具有名称的不同变量,以便您的代码不会混淆。

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

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

答案 8 :(得分:-1)

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

重用您正在节省内存的变量。

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