就我今天所知,在 C 语言中,如果循环 for/while 有括号,它就有作用域,对吗?我在 GCC 中尝试了一些代码,情况似乎如此,例如:
for(unsigned char i=0;...;...){
unsigned char j=0;
}
//Outside of the for scope:
unsigned char j=0;
这里我们完全没有问题,但是,循环参数内的变量呢?
例如,GBD C COMPILER(在线)中的这段代码:
switch(Maneral){
case 1:
for(unsigned char i=0x0A;i<=0x64;i=i+0x0A){
indice++;
}
break;
case 2:
for(unsigned char i=0x0A;i<=0x64;i=i+0x0A){
indice++;
}
break;
}
没有给出错误,我认为它没有给出错误,因为在 for 'share' 的参数内初始化的变量各自 for 的括号的范围
至少直到今天这都是我的头炮,因为我正在使用 CCS C 编译器为 MCU 编写一些嵌入式代码;该编译器表示具有“97% ANSI C 兼容性”,在此编译器中,下一个代码:
switch(Maneral){
case M_CONICO:
for(unsigned char i=0x0A;i<=0x64;i=i+0x0A){ unsigned char too=0;
ActualizaValor(i,DataConico[index]);
index++;
}
break;
case M_CHICO:
for(unsigned char i=0x0A;i<=0x64;i=i+0x0A){ //LINE 'X'
ActualizaValor(i,DataChico[index]);
index++;
}
break;
}
在“X”行上给出错误,它表示标识符已在此范围内使用,例如,如果我在第二个 for 循环中将“i”更改为“j”,则不会给出错误,对于声明的变量/在括号内定义(而不是在循环的参数中)它没有问题(CCS C 编译器)
因此,在“for()”这样的循环参数内初始化的变量的范围类似于实现定义的行为/未定义的行为,或者它是97% ANSI C 兼容性?
提前致谢!
编辑:我知道我可以在开关之外声明/定义“i”,但我想理解这一点,因为我认为我确定我所知道的
从 C99 开始,在
for
循环的 init 子句中声明的变量的作用域为 整个 循环,因此 for
循环的行为大致就像在其周围有一组额外的隐式大括号一样,例如:
for(unsigned char i=0;...;...){
unsigned char j=0;
}
表现得就像您键入:
{
unsigned char i=0
for(;...;...){
unsigned char j=0;
}
}
但这是 C99(及更高版本)的功能,并且声称“ANSI C 兼容性”的内容可能指的是 C89/C90 标准,而
for
循环的此功能不是标准的一部分。
C 2017 在 6.8.5.3p1 中说:
如果子句 1 是声明,则它声明的任何标识符的范围 是声明的剩余部分和整个循环,包括其他两个表达式;这是 在第一次计算控制表达式之前达到的执行顺序。如果子句-1 是一个表达式,在第一次评估控制之前,它被评估为 void 表达式 表达。
所以编译器过于热心了。