Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

160
Visualizações
¿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 Respostas
Responde à pergunta

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 Relatório

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda