Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

157
Vistas
¿Función C que devuelve un puntero a una matriz sintaxis correcta?

En C puedes declarar una variable que apunte a una matriz como esta:

 int int_arr[4] = {1,2,3,4}; int (*ptr_to_arr)[4] = &int_arr;

Aunque prácticamente es lo mismo que declarar un puntero a int:

 int *ptr_to_arr2 = int_arr;

Pero sintácticamente es algo diferente.

Ahora, ¿cómo se vería una función que devuelve un puntero de este tipo a una matriz (de int, por ejemplo)?

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Una declaración de int es int foo; .

Una declaración de un arreglo de 4 int es int foo[4]; .

Una declaración de un puntero a una matriz de 4 int es int (*foo)[4]; .

Una declaración de una función que devuelve un puntero a una matriz de 4 int es int (*foo())[4]; . El () se puede completar con declaraciones de parámetros.

over 4 years ago · Santiago Trujillo Denunciar

0

Como ya se mencionó, la sintaxis correcta es int (*foo(void))[4]; Y como puedes ver, es muy difícil de leer.

Soluciones cuestionables:

  • Use la sintaxis como C le pediría que la escribiera. En mi opinión, esto es algo que debes evitar, ya que es increíblemente difícil de leer, hasta el punto de que es completamente inútil. Esto simplemente debería prohibirse en su estándar de codificación, al igual que cualquier estándar de codificación sensato exige que los punteros de función se usen con un typedef .

  • Oh, ¿así que simplemente typedef esto como cuando usamos punteros de función? Uno podría tener la tentación de esconder toda esta sustancia pegajosa detrás de un typedef , pero eso también es problemático. Y esto se debe a que tanto las matrices como los punteros son "bloques de construcción" fundamentales en C, con una sintaxis específica que el programador espera ver cada vez que trata con ellos. Y la ausencia de esa sintaxis sugiere un objeto que puede ser direccionado, "accedido a lvalue" y copiado como cualquier otra variable. Ocultarlos detrás de typedef podría al final crear aún más confusión que la sintaxis original.

    Toma este ejemplo:

     typedef int(*arr)[4]; ... arr a = create(); // calls malloc etc ... // somewhere later, lets make a hard copy! (or so we thought) arr b = a; ... cleanup(a); ... print(b); // mysterious crash here

    Por lo tanto, este sistema de "esconderse detrás de typedef" depende en gran medida de que nombramos tipos somethingptr para indicar que es un puntero. O digamos... LPWORD ... y ahí está, la "notación húngara", el sistema de tipos muy criticado de la API de Windows.

  • Una solución un poco más sensata es devolver la matriz a través de uno de los parámetros. Esto tampoco es exactamente bonito, pero al menos algo más fácil de leer ya que la sintaxis extraña está centralizada en un parámetro:

     void foo (int(**result)[4]) { ... *result = &arr; }

    Es decir: un puntero a un puntero a matriz de int[4] .

  • Si uno está preparado para tirar la seguridad tipográfica por la ventana, entonces, por supuesto, void* foo (void) resuelve todos estos problemas... pero crea otros nuevos. Muy fácil de leer, pero ahora el problema es la seguridad de tipo y la incertidumbre con respecto a lo que realmente devuelve la función. Tampoco es bueno.


Entonces, ¿qué hacer entonces, si todas estas versiones son problemáticas? Hay algunos enfoques perfectamente sensatos.

Buenas soluciones:

  • Deje la asignación a la persona que llama. Este es , con mucho , el mejor método, si tiene la opción. Su función se convertiría en void foo (int arr[4]); que es legible y seguro para escribir ambos.

  • Vieja escuela C. Simplemente devuelva un puntero al primer elemento de la matriz y pase el tamaño por separado. Esto puede o no ser aceptable de un caso a otro.

  • Envuélvalo en una estructura. Por ejemplo, esta podría ser una implementación sensata de algún tipo de matriz genérica:

     typedef struct { size_t size; int arr[]; } array_t; array_t* alloc (size_t items) { array_t* result = malloc(sizeof *result + sizeof(int[items])); return result; }
over 4 years ago · Santiago Trujillo Denunciar

0

La palabra clave typedef puede hacer las cosas mucho más claras/simples en este caso:

 int int_arr[4] = { 1,2,3,4 }; typedef int(*arrptr)[4]; // Define a pointer to an array of 4 ints ... arrptr func(void) // ... and use that for the function return type { return &int_arr; }

Nota: Como se señaló en los comentarios y en la excelente respuesta de Lundin , usar un typedef para ocultar/enterrar un puntero es una práctica que (la mayoría de) la comunidad profesional de programación C desaprueba, y por muy buenas razones. Hay una buena discusión al respecto aquí .

Sin embargo, aunque, en su caso, no está definiendo un puntero de función real (que es una excepción a la 'regla' que la mayoría de los programadores aceptarán), está definiendo un tipo de retorno de función complicado (es decir, difícil de leer). La discusión al final de la publicación vinculada profundiza en el tema "demasiado complicado", que es lo que usaría para justificar el uso de un typedef en un caso como el suyo. Pero, si debe elegir este camino, hágalo con precaución.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda