Soovitud eesmärgi saavutamiseks on mitu võimalust:
viis, mis ei tööta
Kas proovisite koostada küsimuses antud koodi? Siis ilmselt märkasite, et see ei koosta. Proovisin ja sain: "error: eeldatav esmane-avaldis enne ']' märki", mis tähendab, et koostaja ootas return massiiv [some_index];
.
Peaaegu töötav viis
Eemaldage sulgud ja tagastage lihtsalt array
:
int * function () {int array [3]; massiiv [0] = 19; massiiv [1] = 7; massiiv [2] = 69; return array;}
Sõltuvalt ümbritsevast koodist võib see toimida või mitte selles, kuidas optimeerija teie programmi töötleb ja kui õnne teil testimise ajal on. Seda nimetatakse määratlemata käitumiseks ja seda peaksite alati vältima.
Nii juhtub: C-s (ja C ++) ei saa massiivi tagastada. Identifikaator array
laguneb selle esimesele elemendile osutava osuti juurde. Siis return array
on põhimõtteliselt samaväärne väärtusega return &array [0]
. Probleem on selles, et kuna massiiv on eraldatud funktsiooni virnaraamis, siis funktsiooni naastes lakkab see olemast, nii et callergetid osutavad mälupiirkonnale, mida enam ei eraldata. Eeldatav on tõenäoliselt mälu rikkumine. Koostaja hoiatas mind, kui proovisin todot, et: "hoiatus: kohaliku muutuja" massiivi "aadress saadeti tagasi". See on väga tõsine hoiatus, mida ei tohiks kunagi ignoreerida.
Lihtsaim lahendus: massiivi muutmine staatiliseks
Nagu Chris Stratton kommentaaris soovitas, saate massiivi muuta staatiliseks, nii et see eraldada kogu programmi eluks:
int * function () {static int array [3]; massiiv [0] = 19; massiiv [1] = 7; massiiv [2] = 69; return array;}
Ainus takistus on see, et funktsioon pole nüüd reentrant , mis tähendab, et iga kord, kui seda nimetate, varjab sama massiivi, mille ta eelmisel korral tagastas kõned. Sõltuvalt teie kasutusjuhtumist ei pruugi see probleem olla,
kuid see on midagi, mida peate teadma.
Las helistaja haldab jaotust
Turvalisem (uuesti sisenev) viis on lasta helistajal pakkuda massiivi jaoks vajalikku mälu. See on C-s väga levinud meetod ja seda pakuvad nii Harper Shelby vastus kui ka Chris Strattoni kommentaar:
int * funktsioon (int massiiv [3]) {array [0] = 19; massiiv [1] = 7; massiiv [2] = 69; return array;}
Helistaja saab eraldada staatilises mälus või oma virna raamis või kuhja peal ... aga see ei huvita, eraldamine on nüüd helistaja probleem .
Siinkohal tuleb märkida paar asja:
- Prototüüp on samaväärne funktsiooniga
int * (int * array)
: funktsioon saab ainult osuti. massiivi [3]
kirjutamine * array
asemel on ainsana dokumenteerimine see, et funktsioon eeldab, et kursor osutab kuhugi, kus on ruumi 3 väärtusele . Selle võiksite dokumenteerida hoopis kommentaaris. - Funktsioon võib tagastada
void
, kuna helistaja teab arvatavasti aadressi, mille ta teile annab. Sama aadressi tagastamine on lihtsalt ebamugavus, kuna see võib aidata teil kette kutsuda nagu another_function (function (array))
.
Massiivi tagastamine struktuuris
Võib imestada: miks me ei saaks massiivi üldse tagastada. Ma ei tea kindlalt, miks keele autorid selle valiku tegid, kuid üks võimalik seletus on see, et suure massiivse väärtuse tagastamine on kallis, kuna see hõlmab kogu selle kopeerimist. Kui nüüd on teie massiiv tegelikult ainult kolm inti, siis see argument ei kehti ja võite põhjendatult soovida kogu massiivi väärtuse järgi tagastada. See võib hõlbustada, kinnistades selle struktuuri:
// Struct definition.struct Array3 {int array [3];}; Array3 function () {Array3 a; a.array [0] = 19; a.array [1] = 7; a.array [2] = 69; tagastage a;}