Hay una regla (estúpida) en C que dice que cualquier variable simple puede inicializarse con una lista de inicializadores entre llaves, como si fuera una matriz.
Por ejemplo, puede escribir int x = {0};
, que es completamente equivalente a int x = 0;
.
Entonces, cuando escribe int *nums = {5, 2, 1, 4};
, en realidad está dando una lista de inicializadores a una sola variable de puntero. Sin embargo, es solo una variable, por lo que solo se le asignará el primer valor 5, el resto de la lista se ignora (en realidad, no creo que el código con un exceso de inicializadores deba compilarse con un compilador estricto); no es así escribir en la memoria en absoluto. El código es equivalente a int *nums = 5;
. Lo que significa que nums
debe apuntar a la dirección 5
.
En este punto, ya debería haber recibido dos advertencias / errores del compilador:
- Asignación de un entero al puntero sin conversión.
- Exceso de elementos en la lista de inicializadores.
Y luego, por supuesto, el código se bloqueará y se quemará, ya que 5
lo más probable es que no sea una dirección válida con la que pueda eliminar la referencia nums[0]
.
Como nota al margen, debe señalar las printf
direcciones con el %p
especificador o, de lo contrario, está invocando un comportamiento indefinido.
No estoy muy seguro de lo que está tratando de hacer aquí, pero si desea establecer un puntero para apuntar a una matriz, debe hacer:
int nums[] = {5, 2, 1, 4};
int* ptr = nums;
int* ptr = (int[]){5, 2, 1, 4};
O si desea crear una matriz de punteros:
int* ptr[] = { };
EDITAR
Después de investigar un poco, puedo decir que la "lista de inicializadores de elementos en exceso" no es C válida, es una extensión GCC .
La inicialización estándar 6.7.9 dice (el énfasis es mío):
2 Ningún inicializador intentará proporcionar un valor para un objeto que no esté contenido en la entidad que se está inicializando.
/ - /
11 El inicializador de un escalar será una sola expresión, opcionalmente encerrada entre llaves. El valor inicial del objeto es el de la expresión (después de la conversión); Se aplican las mismas restricciones de tipo y conversiones que para la asignación simple, tomando el tipo del escalar como la versión no calificada de su tipo declarado.
"Tipo escalar" es un término estándar que se refiere a variables individuales que no son de tipo matriz, estructura o unión (se denominan "tipo agregado").
Entonces, en inglés simple, el estándar dice: "cuando inicializa una variable, no dude en agregar algunas llaves adicionales alrededor de la expresión del inicializador, solo porque puede".