更新: 我现在重新测试了简化的测试用例和恢复共享名称的完整代码,并且它可以正常工作。我的代码中的其他地方可能还有一些其他错误现在已修复。很抱歉浪费你的时间和精力;将来不会在没有工作测试用例的情况下发布。 Mea culpa。
我有一个C ++函数,我反复调用它。它有以下片段
switch(c)
{
case 1:
{
static int i = 0;
if ( ... ) { i = 0; }
....
break;
}
case 2:
{
static int i = 0;
if ( ... ) { i = 0; }
....
break;
}
case 3:
{
static int i = 0;
if ( ... ) { i = 0; }
....
break;
}
}
这个想法是它必须记住每个案例的状态,有时它必须重置它。
它无法正常工作。当我调试它时(MSVC ++ 2010 Express Edition),我注意到每个i
都没有独立行为,它们的价值看起来似乎在变化;此外,当重置条件被点击时,相应的if
输入OK,但i = 0;
语句只是... 跳过 !!!并且“locals”窗口显示i
及其先前的值,不变(当前语句是下一个,仍在if
内)。 if
内的其他陈述正在正确执行。
当我使用唯一名称(i
,i1
,i2
)重命名每个i3
时,问题就消失了。
这是一些我应该知道的错误或某些语言功能吗?我认为每个块{ ... }
定义了独立范围。这里发生了什么?它会在C中工作吗?
编辑:抱歉没有构建测试用例。会这样做,稍后再报告。
答案 0 :(得分:4)
这听起来像是代码或解释中的错误。我可以想象你的调试器中的“监视窗口”功能会出错,因为块没有名称,因此难以在文本中识别。
static
存储持续时间的本地变量受块范围约束。
以下是不具有功能范围的证据:
[C++11: 3.3.5/1]:
标签(6.1)具有功能范围,可以在声明它们的函数中的任何位置使用。 只有标签才有功能范围。
这是一个实际的演示:
#include <iostream>
void f(const int i)
{
switch (i) {
case 3: {
static int x = 0;
std::cout << x;
x = 3;
std::cout << x << ' ';
break;
}
case 4: {
static int x = 0;
std::cout << x;
x = 4;
std::cout << x << ' ';
break;
}
}
}
int main()
{
f(3);
f(4);
}
// Output: 03 04
这表明当输入第二种情况时,您正在使用不同的本地静态变量x
。否则你会看到03 34
。
答案 1 :(得分:3)
函数内部的静态变量具有块作用域,并且它们在连续调用它时是持久的。您不能在同一范围内声明两个具有相同名称的变量,但如果它们位于不同的范围内,则可以这样做,表示为
{}
这是你的情况。
switch(c)
{
case 1:
{
static int i = 0;
}
case 2:
{
static int i = 0;
}
case 3:
{
static int i = 0;
}
}
所以这应该按照你的预期工作,因此这可能是编译器,调试器(或者其他没有给出更多信息的情况下很难猜到的)的错误,它将所有这些静态变量视为同一个变量。这就是为什么更改这些变量的名称可以解决您的问题。
答案 2 :(得分:1)
我必须自己检查,以为我会分享我的小测试。变量仅在大括号内可见。并且可以在另一个案例中声明相同的变量名称,它不会覆盖另一个变量。
变量在函数中不可见,但仅在switch语句中的花括号内。
#include<stdio.h>
int call_switch(int);
int main()
{
call_switch(2);
call_switch(3);
call_switch(2);
call_switch(3);
return 0;
}
int call_switch(int a){
switch(a)
{
case 2:
{
static int i = 5;
i++;
printf(" i declared as 5 %d\n",i);
break;
}
case 3:
{
static int i = 10;
i++;
printf("i declared as 10 %d\n",i);
break;
}
}
// printf("%d",i ); not visible here
return 0;
}
输出
i declared as 5 6
i declared as 10 11
i declared as 5 7
i declared as 10 12
答案 3 :(得分:-1)
static
变量具有函数范围。变量在整个函数中都可见。
static
个变量有文件范围,它在文件中可见,但不在文件中可见。