在同一个函数中定义变量及其静态等价物
Defining a variable and its static equivalent in the same function
我不明白下面的代码是如何工作的:
#include "stdio.h"
int main(void) {
int i = 3;
while(i--) {
static int i = 100;
i--,
printf("%d\n", i);
}
return 0;
}
使用 Clang 或 GCC 编译的代码打印出以下输出:
99
98
97
谁能给我解释一下这里发生了什么?看起来两个操作是在一条指令中完成的,而且不止一次。它是未定义的行为吗?
我在 C++ 中观察到相同的行为。
这不是未定义的行为。
#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 循环中检查条件时,它不知道 body 中有什么。所以选择第一个i
.
是没有问题的
可以在嵌套范围内声明同名变量。编译器将它们视为不同的变量。这非常令人困惑,但您每次访问的变量都是在最内部范围内声明的变量。 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
等等...
维基百科对此说得很突出:
In computer programming, variable shadowing occurs when a variable declared within a certain scope (decision block, method, or inner class) has the same name as a variable declared in an outer scope. At the level of identifiers (names, rather than variables), this is known as name masking. This outer variable is said to be shadowed by the inner variable, while the inner identifier is said to mask the outer identifier.
现在在块内,它找到静态变量并对其进行处理,但是 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
... If an identifier designates two different entities in the same name space, the scopes might overlap. If so, the scope of one entity (the inner scope) will end strictly before the scope of the other entity (the outer scope). Within the inner scope, the identifier designates the entity declared in the inner scope; the entity declared in the outer scope is hidden (and not visible) within the inner scope.
我不明白下面的代码是如何工作的:
#include "stdio.h"
int main(void) {
int i = 3;
while(i--) {
static int i = 100;
i--,
printf("%d\n", i);
}
return 0;
}
使用 Clang 或 GCC 编译的代码打印出以下输出:
99
98
97
谁能给我解释一下这里发生了什么?看起来两个操作是在一条指令中完成的,而且不止一次。它是未定义的行为吗? 我在 C++ 中观察到相同的行为。
这不是未定义的行为。
#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 循环中检查条件时,它不知道 body 中有什么。所以选择第一个i
.
可以在嵌套范围内声明同名变量。编译器将它们视为不同的变量。这非常令人困惑,但您每次访问的变量都是在最内部范围内声明的变量。 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
等等...
维基百科对此说得很突出:
In computer programming, variable shadowing occurs when a variable declared within a certain scope (decision block, method, or inner class) has the same name as a variable declared in an outer scope. At the level of identifiers (names, rather than variables), this is known as name masking. This outer variable is said to be shadowed by the inner variable, while the inner identifier is said to mask the outer identifier.
现在在块内,它找到静态变量并对其进行处理,但是 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
... If an identifier designates two different entities in the same name space, the scopes might overlap. If so, the scope of one entity (the inner scope) will end strictly before the scope of the other entity (the outer scope). Within the inner scope, the identifier designates the entity declared in the inner scope; the entity declared in the outer scope is hidden (and not visible) within the inner scope.