我看到有类似的问题关于C++,在C++中重新声明变量会产生任何影响吗?
那么在C语言中呢?重新声明变量会有任何显著影响吗?这通常被认为是代码组织不良吗?
for(;;) {
int y = 1 + 2 + 3; // some kind of repeated redeclaration?
}
编辑:
完善我的问题。
如果我在一个函数中有一个循环,那么重复调用“int y = 1 + 2 + 3;”是否允许?会引起问题吗?它是什么作用,声明一次y
?
我看到有类似的问题关于C++,在C++中重新声明变量会产生任何影响吗?
那么在C语言中呢?重新声明变量会有任何显著影响吗?这通常被认为是代码组织不良吗?
for(;;) {
int y = 1 + 2 + 3; // some kind of repeated redeclaration?
}
编辑:
完善我的问题。
如果我在一个函数中有一个循环,那么重复调用“int y = 1 + 2 + 3;”是否允许?会引起问题吗?它是什么作用,声明一次y
?
C 语言有变量作用域的概念。简而言之,每对 {
和 }
引入一个新的作用域,并且变量绑定到这些作用域中。你可以使用相同名称的变量,只要它们在不同的作用域中即可。
这就是为什么下面的代码是有效的:
if(...) {
int y; # y is valid here
} # end of scope, y is not valid here
if(...) { # new scope
int y; # That's another y
}
那是无效的:
if(...) {
int y;
int y; # error, redeclaration
}
此外,声明是源代码属性,而不是运行时程序属性。
因此,如果您写入:
for(;;) {
int y = 1 + 2 + 3;
}
你只需声明y
一次(因为你只写了一次),而不是无限次数。
大多数C编译器会尽可能地进行优化。如果您想真正了解情况,请使用标志编译以查看汇编代码并查看它正在执行的操作。就像有人说的那样,如果它是一个简单类型(没有构造函数),特别是如果您使用所有文字,编译器可能只会将一个固定值移动到每个迭代的寄存器中,或者如果在迭代之间没有任何变量更改,则甚至不会费心。
我刚刚检查了您下面显示的示例,并将其更改为在循环中修改变量,您可以看到生成的汇编代码如何更改。
在第一个示例中,请注意LBB0_1处的循环,它只是一个movl指令。
在第二个示例中,它仍然非常简单,但即使结果未被使用,它仍然会保存堆栈上的内容。我添加了一些注释来解释循环正在做什么。
$ cc -fno-asynchronous-unwind-tables -S dummy.c
int main(void) {
for(;;) {
int y = 1 + 2 + 3;
}
}
$ cat dummy.s
.section __TEXT,__text,regular,pure_instructions
.macosx_version_min 10, 12
.globl _main
.align 4, 0x90
_main: ## @main
## BB#0:
pushq %rbp
movq %rsp, %rbp
movl $0, -4(%rbp)
LBB0_1: ## =>This Inner Loop Header: Depth=1
movl $6, -8(%rbp)
jmp LBB0_1
.subsections_via_symbols
$ cc -fno-asynchronous-unwind-tables -S dummy.c
int main(void) {
int i = 0;
for(;;) {
int y = i + 2 + 3;
i++;
}
}
$ cat dummy.s
.section __TEXT,__text,regular,pure_instructions
.macosx_version_min 10, 12
.globl _main
.align 4, 0x90
_main: ## @main
## BB#0:
pushq %rbp
movq %rsp, %rbp
movl $0, -4(%rbp)
movl $0, -8(%rbp) ## i = 0
LBB0_1:
movl -8(%rbp), %eax ## y = i
addl $2, %eax ## y += 2
addl $3, %eax ## y += 3
movl %eax, -12(%rbp) ## -12(rbp) = y
movl -8(%rbp), %eax ## eax = i
addl $1, %eax ## i++
movl %eax, -8(%rbp) ## -8(rbp) = i
jmp LBB0_1
.subsections_via_symbols
int y = 1; int y = 2; int y = 3;
这里会发生什么是我的问题。 - visc