c++ - globales - Definiendo una variable y su equivalente estático en la misma función.
variables estaticas java (3)
Es posible declarar una variable con el mismo nombre dentro de un ámbito anidado. El compilador los ve como variables diferentes. Es muy confuso, pero la variable a la que está accediendo cada vez es la declarada en el ámbito más interno. Fuera del while
es int i = 3;
y dentro de ella está la 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;
}
Si esta fuera una función diferente a la principal, entonces la segunda llamada a ella produciría
96
95
94
y así...
No entiendo cómo funciona el siguiente código:
#include "stdio.h"
int main(void) {
int i = 3;
while(i--) {
static int i = 100;
i--,
printf("%d/n", i);
}
return 0;
}
El código compilado con Clang o GCC imprime el siguiente resultado:
99
98
97
¿Puede alguien explicarme lo que pasa aquí? Parece que dos operaciones se logran en una sola instrucción y más de una vez. ¿Es un comportamiento indefinido? Observo el mismo comportamiento en C ++.
Esto no es un comportamiento indefinido.
#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;
}
En el cuerpo del bucle while, se prefiere la mayoría i
local (segunda i
). Mientras se verifica la condición en el bucle while, no se sabe qué hay en el cuerpo. Así que no tiene problema en elegir primero.
Wikipedia dice algo muy prominente en esto:
En la programación de computadoras, el sombreado de variables ocurre cuando una variable declarada dentro de un cierto alcance (bloque de decisión, método o clase interna) tiene el mismo nombre que una variable declarada en un alcance externo. En el nivel de identificadores (nombres, en lugar de variables), esto se conoce como enmascaramiento de nombres. Se dice que esta variable externa está sombreada por la variable interna, mientras que se dice que el identificador interno enmascara el identificador externo.
Ahora aquí, dentro del bloque, encuentra la variable estática y trabaja en ella, pero la condición while disminuye la i
que es la declarada fuera del bloque. El alcance es diferente, no es un problema usar el valor correcto de i
. Este es un código C legal, pero no necesariamente una buena manera de escribir cosas.
De hecho, hacer esto gcc -Wshadow progname.c
da
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;
^
De la norma § 6.2.1p4
... Si un identificador designa dos entidades diferentes en el mismo espacio de nombres, los ámbitos podrían superponerse. Si es así, el alcance de una entidad (el alcance interno) terminará estrictamente antes del alcance de la otra entidad (el alcance externo). Dentro del alcance interno, el identificador designa la entidad declarada en el alcance interno; la entidad declarada en el ámbito externo está oculta (y no es visible) dentro del ámbito interno .