C Language
Inicialización
Buscar..
Inicialización de variables en C
En ausencia de una inicialización explícita, se garantiza que las variables externas y static
se inicialicen a cero; las variables automáticas (incluidas register
variables de register
) tienen valores iniciales 1 (es decir, basura) indeterminados .
Las variables escalares pueden inicializarse cuando se definen siguiendo el nombre con un signo igual y una expresión:
int x = 1;
char squota = '\'';
long day = 1000L * 60L * 60L * 24L; /* milliseconds/day */
Para variables externas y static
, el inicializador debe ser una expresión constante 2 ; La inicialización se realiza una vez, conceptualmente antes de que el programa comience la ejecución.
Para register
variables automáticas y de register
, el inicializador no se limita a ser una constante: puede ser cualquier expresión que involucre valores previamente definidos, incluso llamadas a funciones.
Por ejemplo, vea el fragmento de código a continuación
int binsearch(int x, int v[], int n)
{
int low = 0;
int high = n - 1;
int mid;
...
}
en lugar de
int low, high, mid;
low = 0;
high = n - 1;
En efecto, la inicialización de las variables automáticas son solo una abreviatura de las declaraciones de asignación. Qué forma de preferencia es en gran medida una cuestión de gusto. Generalmente usamos asignaciones explícitas, porque los inicializadores en las declaraciones son más difíciles de ver y están más alejados del punto de uso. Por otro lado, las variables solo deben declararse cuando estén a punto de usarse siempre que sea posible.
Inicializando una matriz:
Una matriz puede inicializarse siguiendo su declaración con una lista de inicializadores entre llaves y separados por comas.
Por ejemplo, para inicializar una matriz de días con el número de días en cada mes:
int days_of_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
(Tenga en cuenta que enero se codifica como mes cero en esta estructura).
Cuando se omite el tamaño de la matriz, el compilador calculará la longitud contando los inicializadores, de los cuales hay 12 en este caso.
Si hay menos inicializadores para una matriz que el tamaño especificado, los demás serán cero para todos los tipos de variables.
Es un error tener demasiados inicializadores. No hay una manera estándar de especificar la repetición de un inicializador, pero GCC tiene una extensión para hacerlo.
En C89 / C90 o versiones anteriores de C, no había manera de inicializar un elemento en medio de una matriz sin proporcionar también todos los valores anteriores.
Con C99 y superior, los inicializadores designados le permiten inicializar elementos arbitrarios de una matriz, dejando los valores sin inicializar como ceros.
Inicializando matrices de caracteres:
Las matrices de caracteres son un caso especial de inicialización; Se puede utilizar una cadena en lugar de la notación de llaves y comas:
char chr_array[] = "hello";
Es una abreviatura para el más largo pero equivalente:
char chr_array[] = { 'h', 'e', 'l', 'l', 'o', '\0' };
En este caso, el tamaño de la matriz es seis (cinco caracteres más la terminación '\0'
).
1 ¿Qué le sucede a una variable declarada, sin inicializar en C? ¿Tiene un valor?
2 Tenga en cuenta que una expresión constante se define como algo que se puede evaluar en tiempo de compilación. Entonces, int global_var = f();
no es válido. Otro error común es pensar en una variable cualificada const
como una expresión constante . En C, const
significa "solo lectura", no "constante de tiempo de compilación". Entonces, las definiciones globales como const int SIZE = 10; int global_arr[SIZE];
y const int SIZE = 10; int global_var = SIZE;
No son legales en C.
Inicializando estructuras y matrices de estructuras.
Las estructuras y matrices de estructuras pueden inicializarse mediante una serie de valores entre llaves, un valor por miembro de la estructura.
struct Date
{
int year;
int month;
int day;
};
struct Date us_independence_day = { 1776, 7, 4 };
struct Date uk_battles[] =
{
{ 1066, 10, 14 }, // Battle of Hastings
{ 1815, 6, 18 }, // Battle of Waterloo
{ 1805, 10, 21 }, // Battle of Trafalgar
};
Tenga en cuenta que la inicialización de la matriz se podría escribir sin las llaves interiores, y en tiempos pasados (antes de 1990, por ejemplo) a menudo se habría escrito sin ellas:
struct Date uk_battles[] =
{
1066, 10, 14, // Battle of Hastings
1815, 6, 18, // Battle of Waterloo
1805, 10, 21, // Battle of Trafalgar
};
Aunque esto funciona, no es un buen estilo moderno; no debe intentar usar esta notación en un código nuevo y debe corregir las advertencias del compilador que generalmente produce.
Ver también los inicializadores designados .
Usando inicializadores designados
C99 introdujo el concepto de inicializadores designados. Estos le permiten especificar qué elementos de una matriz, estructura o unión deben inicializarse con los valores siguientes.
Inicializadores designados para elementos de matriz
Para un tipo simple como llano int
:
int array[] = { [4] = 29, [5] = 31, [17] = 101, [18] = 103, [19] = 107, [20] = 109 };
El término entre corchetes, que puede ser cualquier expresión de entero constante, especifica qué elemento de la matriz debe inicializarse con el valor del término después del signo =
. Los elementos no especificados se inicializan por defecto, lo que significa que los ceros están definidos. El ejemplo muestra los inicializadores designados en orden; No tienen que estar en orden. El ejemplo muestra las lagunas; esos son legitimos El ejemplo no muestra dos inicializaciones diferentes para el mismo elemento; eso también está permitido (ISO / IEC 9899: 2011, §6.7.9 Inicialización, ¶19 La inicialización se producirá en el orden de la lista de inicializadores, cada inicializador proporcionado para un subobjeto en particular anulará cualquier inicializador previamente listado para el mismo subobjeto ).
En este ejemplo, el tamaño de la matriz no se define explícitamente, por lo que el índice máximo especificado en los inicializadores designados determina el tamaño de la matriz, que sería 21 elementos en el ejemplo. Si se definió el tamaño, inicializar una entrada más allá del final de la matriz sería un error, como de costumbre.
Inicializadores designados para estructuras.
Puede especificar qué elementos de una estructura se inicializan utilizando el .
notación del element
struct Date
{
int year;
int month;
int day;
};
struct Date us_independence_day = { .day = 4, .month = 7, .year = 1776 };
Si los elementos no están listados, están inicializados por defecto (a cero).
Inicializador designado para uniones
Puede especificar qué elemento de una unión se inicializa con un inicializador designado.
Antes de la norma C, no había manera de inicializar una union
. El estándar C89 / C90 le permite inicializar el primer miembro de una union
, por lo que la elección de qué miembro aparece primero es lo primero.
struct discriminated_union
{
enum { DU_INT, DU_DOUBLE } discriminant;
union
{
int du_int;
double du_double;
} du;
};
struct discriminated_union du1 = { .discriminant = DU_INT, .du = { .du_int = 1 } };
struct discriminated_union du2 = { .discriminant = DU_DOUBLE, .du = { .du_double = 3.14159 } };
Tenga en cuenta que C11 le permite utilizar miembros anónimos de la unión dentro de una estructura, por lo que no necesita el nombre du
en el ejemplo anterior:
struct discriminated_union
{
enum { DU_INT, DU_DOUBLE } discriminant;
union
{
int du_int;
double du_double;
};
};
struct discriminated_union du1 = { .discriminant = DU_INT, .du_int = 1 };
struct discriminated_union du2 = { .discriminant = DU_DOUBLE, .du_double = 3.14159 };
Inicializadores designados para matrices de estructuras, etc.
Estas construcciones se pueden combinar para matrices de estructuras que contienen elementos que son matrices, etc. El uso de conjuntos completos de llaves asegura que la notación sea inequívoca.
typedef struct Date Date; // See earlier in this example
struct date_range
{
Date dr_from;
Date dr_to;
char dr_what[80];
};
struct date_range ranges[] =
{
[3] = { .dr_from = { .year = 1066, .month = 10, .day = 14 },
.dr_to = { .year = 1066, .month = 12, .day = 25 },
.dr_what = "Battle of Hastings to Coronation of William the Conqueror",
},
[2] = { .dr_from = { .month = 7, .day = 4, .year = 1776 },
.dr_to = { .month = 5, .day = 14, .year = 1787 },
.dr_what = "US Declaration of Independence to Constitutional Convention",
}
};
Especificando rangos en inicializadores de matriz
GCC proporciona una extensión que le permite especificar un rango de elementos en una matriz que debe tener el mismo inicializador:
int array[] = { [3 ... 7] = 29, 19 = 107 };
Los puntos triples deben estar separados de los números para que uno de los puntos no se interprete como parte de un número de punto flotante (regla de munch máxima ).