una pagina keywords etiquetas estructura ejemplos definicion c arrays struct return return-value

c - pagina - meta keywords ejemplos



¿Qué tienen de especial las estructuras? (4)

Sé que en C no podemos devolver una matriz de una función, sino un puntero a una matriz. Pero quiero saber qué es lo especial de las structs que los hace structs por funciones, aunque puedan contener matrices.

¿Por qué la struct envoltura hace que el siguiente programa sea válido?

#include <stdio.h> struct data { char buf[256]; }; struct data Foo(const char *buf); int main(void) { struct data obj; obj = Foo("This is a sentence."); printf("%s/n", obj.buf); return 0; } struct data Foo(const char *buf) { struct data X; strcpy(X.buf, buf); return X; }


En primer lugar, para citar C11 , capítulo §6.8.6.4, declaración de return , ( énfasis mío )

Si se ejecuta una declaración de return con una expresión, el valor de la expresión se devuelve al llamante como el valor de la expresión de llamada de función.

Es posible devolver una variable de estructura (y correcta) porque se devuelve el valor de la estructura. Esto es similar a devolver cualquier tipo de datos primitivos (devolviendo int , por ejemplo).

Por otro lado, si devuelve una matriz , al usar return <array_name> , esencialmente devuelve la dirección del primer elemento de la matriz NOTA , que se invalida en la persona que llama si la matriz era local para las funciones llamadas. Por lo tanto, no es posible devolver la matriz de esa manera.

Entonces, TL; DR , no hay nada especial con las struct , la especialidad está en las matrices .

NOTA:

Citando de nuevo C11 , capítulo §6.3.2.1, ( mi énfasis )

Excepto cuando es el operando del operador sizeof , el operador _Alignof , o el operador unario & , o es un literal de cadena utilizado para inicializar una matriz, una expresión que tiene el tipo '''' matriz de tipo '''' se convierte en una expresión con escriba '''' puntero para escribir '''' que apunta al elemento inicial del objeto de matriz y no es un valor l. [...]


Las estructuras tienen miembros de datos públicos de forma predeterminada, por lo que es posible en caso de estructura acceder a los datos en main pero no en el caso de la clase. Entonces, la envoltura de estructura es válida.


No hay nada especial sobre los tipos de struct ; Es que hay algo especial sobre los tipos de matriz que impide que sean devueltos directamente desde una función.

Una expresión de struct se trata como una expresión de cualquier otro tipo que no sea de matriz; evalúa el valor de la struct . Entonces puedes hacer cosas como

struct foo { ... }; struct foo func( void ) { struct foo someFoo; ... return someFoo; }

La expresión someFoo evalúa el valor del objeto struct foo ; el contenido del objeto se devuelve desde la función (incluso si ese contenido contiene matrices).

Una expresión de matriz se trata de manera diferente; si no es el operando de sizeof o unary & operadores, o si no se utiliza un literal de cadena para inicializar otra matriz en una declaración, la expresión se convierte ("decae") del tipo "matriz de T " a " puntero a T ", y el valor de la expresión es la dirección del primer elemento.

Por lo tanto, no puede devolver una matriz por valor de una función, porque cualquier referencia a una expresión de matriz se convierte automáticamente en un valor de puntero.


Una mejor manera de hacer la misma pregunta sería "qué tienen de especial las matrices", ya que son las matrices las que tienen un manejo especial asociado, no las struct .

El comportamiento de pasar y devolver matrices por puntero se remonta a la implementación original de C. Las matrices "decaen" a los punteros, causando una gran confusión, especialmente entre las personas nuevas en el lenguaje. Las estructuras, por otro lado, se comportan como los tipos integrados, como int s, double s, etc. Esto incluye cualquier matriz incrustada en la struct , excepto los miembros de matriz flexible , que no se copian.