微分销手机网站制作,网站设计潮流,排版网站推荐,网站安全写算法题的时候突然想到#xff0c;为什么循环内定义变量不会算作是重复定义#xff0c;以及变量作用域问题#xff0c;为此#xff0c;进行了一次探索 c#xff1a;
代码#xff1a;
#include stdio.h
int main()
{int a 0;int* b a;for (int i 0; i …写算法题的时候突然想到为什么循环内定义变量不会算作是重复定义以及变量作用域问题为此进行了一次探索 c
代码
#include stdio.h
int main()
{int a 0;int* b a;for (int i 0; i 3; i) {printf(%d\n, a);printf(%p\n,a);int a i;printf(%d\n, a);printf(%p\n, a);printf(------------------\n);}return 0;
}
运行结果
0
010FF91C
0
010FF8F8
------------------
0
010FF91C
1
010FF8F8
------------------
0
010FF91C
2
010FF8F8
------------------ java:
代码
public class Main{public static void main(String[]args) {int a 1;for(int i 0 ;i2;i){int a i;System.out.println(a);System.out.println(---------------------);}}
}
java: 已在方法 main(java.lang.String[])中定义了变量 a go
代码
import fmtfunc main() {a : 0for i : 0; i 3; i {fmt.Println(a)fmt.Println(a)var a ifmt.Println(a)fmt.Println(a)fmt.Println(________________________)}
}
结果
0
0xc00000a0b8
0
0xc00000a100
________________________
0
0xc00000a0b8
1
0xc00000a110
________________________
0
0xc00000a0b8
2
0xc00000a120
________________________查阅资料得知这个属于是变量作用域的问题局部变量如果超出作用域就会销毁正如C语言代码运行结果那样循环内定义同一变量的地址值是不会改变的。
而且代码在编译时会将重复定义的变量”提出“到循环外定义也就是说在循环内定义和循环外定义在占用内存上几乎一样
至于同名变量可以既在循环内定义又在循环外定义这点还是跟作用域有关但为什么java不能这样定义emmm没有查到相关资料知道的可以补充一下 还有个问题那为什么go定义出来的变量地址不一样呢是没有销毁原来的局部变量吗这就要说到Go 有 escape analysis, 在编译期它会分析你的变量是否在函数执行完毕那一刻程序有没有可能有别的对象引用到它所谓逃逸如果没有那这个变量就可以在栈上分配完全不经过 gc如果它已经逃逸了那就不知道什么时候才能gc了~
这个代码中的逃逸是由于fmt导致的我们不妨不恰当的修改一下代码
import fmtfunc main() {a : 0for i : 0; i 3; i {println(a)println(a)var a iprintln(a)println(a)fmt.Println(________________________)}
}结果
0
0xc00006ff18
0
0xc00006ff10
________________________
0
0xc00006ff18
1
0xc00006ff10
________________________
0
0xc00006ff18
2
0xc00006ff10
________________________可以看到当我们不使用标准输出流而是使用标准错误流打印的时候可能就不会触发逃逸看到此时地址是一样的也就是印证了我们上面的结论。