我不明白以下代码的工作原理:
id="Picture"
使用Clang或GCC编译的代码打印以下输出:
Observable.range(0,50)
.subscribeOn(Schedulers.computation())
.delay(1000, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(integer -> mProgressBar.setProgress(integer));
有人可以向我解释这里发生了什么吗?看起来在一条指令中实现了两次操作并且不止一次。是不确定的行为? 我在C ++中观察到相同的行为。
答案 0 :(得分:24)
这不是未定义的行为。
#include "stdio.h"
int main(void) {
int i = 3; //first i
while(i--) {
static int i = 100; //second i
i--,
printf("%d\n", i);
}
return 0;
}
在while循环体中,大多数本地i
(第二i
)是首选。在while循环中检查条件时,它不知道身体中有什么。因此,首先选择i
是没有问题的。
答案 1 :(得分:11)
维基百科对此非常突出:
在计算机编程中,当在特定范围内声明的变量(决策块,方法或内部类)与在外部范围内声明的变量具有相同的名称时,会发生变量阴影。在标识符(名称而不是变量)的级别上,这称为名称屏蔽。该外部变量被称为由内部变量遮蔽,而内部标识符被称为掩盖外部标识符。
现在,在块内部,它找到静态变量并对其进行处理,但while条件会减少i
,这是在块外声明的值。范围不同 - 使用i
的正确值是没有问题的。这是合法的C代码,但不一定是写东西的好方法。
实际上这样做gcc -Wshadow progname.c
会给出
progname.c: In function 'main':
progname.c:7:20: warning: declaration of 'i' shadows a previous local [-Wshadow]
static int i=2;
^
progname.c:5:9: warning: shadowed declaration is here [-Wshadow]
int i=2;
^
来自标准§6.2.1p4
...如果标识符指定同一名称空间中的两个不同实体,则范围可能会重叠。如果是这样,一个实体(内部范围)的范围将严格地在另一个实体(外部范围)的范围之前结束。 在内部范围内,标识符指定在内部范围内声明的实体;在外部范围内声明的实体在内部范围内隐藏(并且不可见)。
答案 2 :(得分:2)
可以在嵌套范围内声明相同的命名变量。编译器将它们视为不同的变量。这非常令人困惑,但每次访问的变量都是在最大范围内声明的变量。 while
之外是int i = 3;
,里面是static int i = 100;
#include "stdio.h"
int main(void) {
int i = 3; // outer i
while(i--) { // outer i
static int i = 100; // inner i
i--, // inner i
printf("%d\n", i); // inner i
}
return 0;
}
如果这是main之外的函数,则第二次调用它将产生
96
95
94
依旧......