Wiem, że w C nie możemy zwrócić tablicy z funkcji, ale wskaźnik do tablicy. Ale chcę wiedzieć, na czym polega szczególna cecha structs
tego, że są one zwracane przez funkcje, nawet jeśli mogą zawierać tablice.
Dlaczego struct
opakowanie sprawia, że następujący program jest ważny?
#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
. Co jest specjalnego w związkach zawodowych?memcpy()
i utrata „ukrytej” pamięci są głównym powodem, dla którego struktura nie powinna byćpassed to
anireturned from
funkcją. Najlepszą zasadą jest przekazanie wskaźnika do struktury.Odpowiedzi:
Lepszym sposobem zadania tego samego pytania byłoby „co jest specjalnego w tablicach”, ponieważ to tablice mają dołączoną specjalną obsługę,
struct
a nie s.Zachowanie przekazywania i zwracania tablic przez wskaźnik prowadzi do pierwotnej implementacji C. Tablice „rozpadają się” na wskaźniki, powodując spore zamieszanie, zwłaszcza wśród osób nieznających języka. Z drugiej strony struktury zachowują się tak samo, jak typy wbudowane, takie jak
int
s,double
s itp. Obejmuje to wszelkie tablice osadzone w elemencie, zstruct
wyjątkiem elastycznych elementów tablicy , które nie są kopiowane.źródło
struct
wartości przez wartość nie było możliwe?struct Point {short x, y, z;};
. Naprawdę chcesz używać wskaźników, aby je przesuwać? Z pewnością nie oszczędzasz w ten sposób miejsca.Przede wszystkim, aby zacytować
C11
, rozdział §6.8.6.4,return
oświadczenie, ( moje wyróżnienie )Zwracanie zmiennej strukturalnej jest możliwe (i poprawne), ponieważ zwracana jest wartość struktury . Jest to podobne do zwracania dowolnego pierwotnego typu danych (
int
na przykład zwracania ).Z drugiej strony, jeśli zwrócisz tablicę , używając funkcji
return <array_name>
, zwróci ona zasadniczo adres pierwszego elementu tablicy UWAGA , który staje się nieprawidłowy w funkcji wywołującej, jeśli tablica była lokalna dla wywoływanych funkcji. Zatem zwrócenie tablicy w ten sposób nie jest możliwe.Tak więc, TL; DR , nie ma nic specjalnego w
struct
s, specjalnością są tablice .UWAGA:
Cytując
C11
ponownie, rozdział §6.3.2.1, (wyróżnienie moje )źródło
Nie ma nic specjalnego w
struct
typach; chodzi o to, że jest coś szczególnego w typach tablicowych, które uniemożliwiają zwracanie ich bezpośrednio z funkcji.struct
Ekspresja jest traktowany jak ekspresja dowolnego innego rodzaju niż tablica; ocenia do wartości zstruct
. Możesz więc robić takie rzeczy jakstruct foo { ... }; struct foo func( void ) { struct foo someFoo; ... return someFoo; }
Wyrażenie
someFoo
ocenia do wartości wstruct foo
obiekcie; zawartość obiektu jest zwracana przez funkcję (nawet jeśli ta zawartość zawiera tablice).Wyrażenie tablicowe jest traktowane inaczej; jeśli nie jest operandem operatorów
sizeof
jednoargumentowych&
lub lub jeśli nie jest to literał łańcuchowy używany do inicjalizacji innej tablicy w deklaracji, wyrażenie jest konwertowane („rozpada się”) z typu „tablicaT
” na „wskaźnik doT
” , a wartością wyrażenia jest adres pierwszego elementu.Dlatego nie można zwrócić tablicy według wartości z funkcji, ponieważ każde odwołanie do wyrażenia tablicowego jest automatycznie konwertowane na wartość wskaźnika.
źródło
Struktury mają domyślnie publiczne elementy składowe danych, więc w przypadku struct możliwe jest uzyskanie dostępu do danych w main, ale nie w przypadku klasy. Tak więc zawijanie struktury jest prawidłowe.
źródło
public
/private
i nie maclass
es. Pytanie dotyczy tego, dlaczego astruct
jest potrzebne w C, aby zwrócić wartość tablicy.