C 重用变量是好还是坏?

C 重用变量是好还是坏?,c,variables,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;

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

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;
}
int main(无效){
//...
int x=0;
//..
x=atoi(字符变量);
//..
对于(x=0;x

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

通常这是一种非常糟糕的做法为了不同的目的重用变量名-如果其他人以后需要维护您的代码,那么此人必须在您的代码中找到这些“上下文开关”,其中
x
现在突然意味着与该行代码之前的含义不同的东西

您可能会节省一些内存,但与它所带来的问题相比,这是非常小的,因此建议您不要这样做

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


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

唯一的缺点是可读性你的代码的可靠性

重用变量可以节省内存


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

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

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

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


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

最好在内存方面重用变量。 但是要小心,在重用变量之前,不需要变量中的值。 除此之外,您不应该总是使用变量。保持代码干净易读是很重要的。因此,我建议您根据上下文选择不同的变量名称,以免代码变得混乱

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


糟糕。对于像
int
s这样的简单类型,通过值传递,编译器将能够确定何时不需要它们并重用空间

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

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

for (int j = 0; j < 4; ++j)
{
    printf("%d\n", j);
}
for(int i=0;i<4;++i)
{
printf(“%d\n”,i);
}
对于(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   :    }
;5:for(int i=0;i<4;++i)
mov edi,DWORD PTR\uuuuu imp\uuuuuu printf
xor esi,esi
新议程6
$LL6@main:
; 6    :    {
;7:printf(“%d\n”,i);
推动esi
推送偏移_C@_03PMGGPEJJ@?$CFd?6?$AA@
打电话给edi
公司esi
添加esp,8
cmp esi,4
jl短$LL6@main
; 8    :    }
; 9    : 
;10:for(int j=0;j<4;++j)
xor esi,esi
$LL3@main:
; 11   :    {
;12:printf(“%d\n”,j);
推动esi
推送偏移_C@_03PMGGPEJJ@?$CFd?6?$AA@
打电话给edi
公司esi
添加esp,8
cmp esi,4
jl短$LL3@main
; 13   :    }

您可以看到,编译器通常对任何语言都使用
i
j

esi
寄存器,如果您重用变量名,然后决定将部分代码重构为另一个方法,那么您将不得不添加或编辑声明

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);
}

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

这样说-如果我以这种方式编写了一大堆未记录的复杂代码,然后你得到了工作,你会怎么想b维持/加强信息技术


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

在大多数情况下,这是不好的。每个变量都应该发挥自己的作用role@AndreyChernukha一个简单的计数器(例如,
i
)怎么样@m0skit0我说过,在大多数情况下,不使用与套接字和循环计数器相同的变量肯定不会提高代码的可读性。使用有意义的变量名也被认为是一种很好的做法。可能是重复的。谢谢你的回复和解释。顺便说一句,我不打算这样做
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);
}
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