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 structs
que los hace retornables por funciones a pesar de que pueden contener matrices.
¿Por qué la struct
envoltura hace válido el siguiente programa?
#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;
}
union
. ¿Qué tienen de especial los sindicatos?memcpy()
la pérdida de la memoria 'oculta' es la razón principal por la que una estructura no debería serpassed to
nireturned from
una función. La mejor política es pasar un puntero a la estructura.Respuestas:
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 adjunto, no
struct
s.El comportamiento de pasar y devolver matrices por puntero se remonta a la implementación original de C. Las matrices "decaen" a punteros, causando mucha confusión, especialmente entre personas nuevas en el lenguaje. Las estructuras, por otro lado, se comportan como tipos incorporados, como
int
s,double
s, etc. Esto incluye cualquier matriz incrustada enstruct
, excepto los miembros de matriz flexible , que no se copian.fuente
struct
s por valor no fue posible?struct Point {short x, y, z;};
. ¿Realmente quieres usar punteros para moverlos? Ciertamente no está ahorrando espacio de esta manera.En primer lugar, para citar
C11
, el capítulo §6.8.6.4,return
declaración, (el énfasis es mío )Devolver una variable de estructura es posible (y correcto) porque se devuelve el valor de la estructura . Esto es similar a devolver cualquier tipo de datos primitivo (devolver
int
, por ejemplo).Por otro lado, si devuelve una matriz , al usar la
return <array_name>
, esencialmente devuelve la dirección del primer elemento de la matriz NOTA , que se vuelve inválida en el llamador si la matriz era local a las funciones llamadas. Entonces, devolver la matriz de esa manera no es posible.Entonces, TL; DR , no hay nada especial con
struct
s, la especialidad está en las matrices .NOTA:
Citando de
C11
nuevo, el capítulo §6.3.2.1, ( énfasis mío )fuente
No hay nada especial en los
struct
tipos; es que hay algo especial en los tipos de matriz que evita que sean devueltos directamente desde una función.Una
struct
expresión se trata como una expresión de cualquier otro tipo que no sea de matriz; evalúa el valor destruct
. Entonces puedes hacer cosas comostruct foo { ... }; struct foo func( void ) { struct foo someFoo; ... return someFoo; }
La expresión
someFoo
evalúa el valor delstruct foo
objeto; el contenido del objeto se devuelve desde la función (incluso si esos contenidos contienen matrices).Una expresión de matriz se trata de manera diferente; si no es el operando de los operadores
sizeof
unarios o&
, o si no es un literal de cadena que se usa para inicializar otra matriz en una declaración, la expresión se convierte ("decae") del tipo "matriz deT
" a "puntero aT
" 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.
fuente
Las estructuras tienen miembros de datos públicos de forma predeterminada, por lo que es posible, en el caso de una estructura, acceder a los datos en main pero no en el caso de la clase. Entonces, el ajuste de estructura es válido.
fuente
public
/private
y no hayclass
es. La pregunta es por quéstruct
se necesita a en C para devolver el valor de una matriz.