Terugkeer array in een functie

Ik heb een array int arr[5]die wordt doorgegeven aan een functie fillarr(int arr[]):

int fillarr(int arr[])
{
    for(...);
    return arr;
}
  1. Hoe kan ik die array retourneren?
  2. Hoe zal ik het gebruiken, zeg dat ik een aanwijzer terugstuurde, hoe ga ik er toegang toe?

1, Autoriteit 100%

In dit geval kan uw arrayvariabele arrook worden behandeld als een aanwijzer naar het begin van het blok van uw array in het geheugen, door een impliciete conversie. Deze syntaxis die u gebruikt:

int fillarr(int arr[])

is een soort van alleen syntactische suiker. Je zou het echt kunnen vervangen en het zou nog steeds werken:

int fillarr(int* arr)

Dus in dezelfde zin, wat u wilt terugkeren uit uw functie is eigenlijk een aanwijzer naar het eerste element in de array:

int* fillarr(int arr[])

En je kunt het nog steeds gebruiken, net zoals je een normale array zou doen:

int main()
{
  int y[10];
  int *a = fillarr(y);
  cout << a[0] << endl;
}

2, Autoriteit 54%

C++ -functies kunnen C-Style-arrays per waarde niet retourneren. Het dichtstbijzijnde is om een ​​aanwijzer te retourneren. Verder wordt eenvoudigweg een array-type in de argumentlijst geconverteerd naar een aanwijzer.

int *fillarr( int arr[] ) { // arr "decays" to type int *
    return arr;
}

Je kunt het verbeteren door een array-referentie te gebruiken voor het argument en de return, waardoor het verval wordt voorkomen:

int ( &fillarr( int (&arr)[5] ) )[5] { // no decay; argument must be size 5
    return arr;
}

Met Boost of C++11 is pass-by-referentie alleen optioneel en is de syntaxis minder verbijsterend:

array< int, 5 > &fillarr( array< int, 5 > &arr ) {
    return arr; // "array" being boost::array or std::array
}

De sjabloon arraygenereert eenvoudig een structdie een array in C-stijl bevat, zodat u objectgeoriënteerde semantiek kunt toepassen en toch de oorspronkelijke eenvoud van de array kunt behouden.


Antwoord 3, autoriteit 13%

In C++11 kun je std::arrayretourneren.

#include <array>
using namespace std;
array<int, 5> fillarr(int arr[])
{
    array<int, 5> arr2;
    for(int i=0; i<5; ++i) {
        arr2[i]=arr[i]*2;
    }
    return arr2;
}

Antwoord 4, autoriteit 11%

$8.3.5/8 staten-

“Functies mogen geen return type array of functie hebben, hoewel ze wel een return type pointer of verwijzing naar dergelijke dingen kunnen hebben. Er mogen geen arrays van functies zijn, hoewel er wel arrays van pointers naar functies kunnen zijn .”

int (&fn1(int (&arr)[5]))[5]{     // declare fn1 as returning refernce to array
   return arr;
}
int *fn2(int arr[]){              // declare fn2 as returning pointer to array
   return arr;
}
int main(){
   int buf[5];
   fn1(buf);
   fn2(buf);
}

Antwoord 5, autoriteit 7%

het antwoord hangt misschien een beetje af van hoe je die functie wilt gebruiken. Laten we voor het eenvoudigste antwoord besluiten dat in plaats van een array, je echt een vector wilt. Vectoren zijn leuk omdat de look voor de hele wereld saaie, gewone waarden zijn die je in gewone pointers kunt opslaan. We zullen daarna kijken naar andere opties en waarom je ze wilt:

std::vector<int> fillarr( std::vector<int> arr ) {
    // do something
    return arr;
}

Dit doet precies wat je ervan verwacht. Het voordeel is dat std::vectorervoor zorgt dat alles netjes wordt afgehandeld. het nadeel is dat dit een zeer grote hoeveelheid gegevens kopieert, als je array groot is. In feite kopieert het elk element van de array twee keer. eerst kopieert het de vector zodat de functie het als parameter kan gebruiken. dan kopieert het het opnieuw om het terug te sturen naar de beller. Als je de vector zelf kunt beheren, kun je dingen een stuk eenvoudiger doen. (het kan het een derde keer kopiëren als de beller het in een of andere variabele moet opslaan om meer berekeningen uit te voeren)

Het lijkt erop dat je eigenlijk gewoon een verzameling wilt vullen. als je geen specifieke reden hebt om een nieuw exemplaar van een collectie te retourneren, doe dat dan niet. we kunnen het zo doen

void fillarr(std::vector<int> &  arr) {
    // modify arr
    // don't return anything
}

op deze manier krijg je een verwijzing naar de array die aan de functie is doorgegeven, geen privékopie ervan. alle wijzigingen die u aanbrengt in de parameter worden gezien door de beller. Je zou er een verwijzing naar kunnen terugsturen als je wilt, maar dat is niet echt een goed idee, omdat het een soort van impliceert dat je iets anders krijgt dan wat je hebt gehaald.

Als je echt een nieuw exemplaar van de collectie nodig hebt, maar je wilt vermijden om het op de stapel te hebben (en alle kopieën die met zich meebrengt), moet je een soort van contract maken voor hoe dat geval wordt afgehandeld. De gemakkelijkste manier om dat te doen, is om een ​​slimme wijzer te gebruiken, die de verwijzingsinstantie rond houdt zolang iedereen erop vasthoudt. Het gaat netjes weg als het uit de reikwijdte gaat. Dat zou er als volgt uitzien.

std::auto_ptr<std::vector<int> > fillarr( const std::vector<int> & arr) {
    std::auto_ptr<std::vector<int> > myArr(new std::vector<int>);
    // do stuff with arr and *myArr
    return myArr;
}

Voor het grootste deel, met *myArrwerkt identiek aan het gebruik van een gewone vanille-vector. Dit voorbeeld wijzigt ook de parameterlijst door de consttrefwoord toe te voegen. Nu krijg je een referentie zonder het te kopiëren, maar je kunt het niet wijzigen, dus de beller weet dat het hetzelfde zal zijn als voordat de functie erbij kwam.

Dit alles is opzwelt, maar idiomatische C++ werkt zelden met collecties als geheel. Normaal gesproken gebruikt u iterators over die collecties. Dat lijkt er iets meer uit

template <class Iterator>
Iterator fillarr(Iterator arrStart, Iterator arrEnd) {
    Iterator arrIter = arrStart;
    for(;arrIter <= arrEnd; arrIter++)
       ;// do something
    return arrStart;
}

het gebruiken, ziet er een beetje vreemd uit als je niet gewend bent om deze stijl te zien.

vector<int> arr;
vector<int>::iterator foo = fillarr(arr.begin(), arr.end());

foo ‘wijst nu naar’ het begin van de gewijzigde arr.

Het mooie hieraan is dat het net zo goed werkt op vector als op gewone C-arrays en vele andere soorten verzamelingen, bijvoorbeeld

int arr[100];
int *foo = fillarr(arr, arr+100);

Wat nu erg veel lijkt op de eenvoudige aanwijzervoorbeelden die elders in deze vraag worden gegeven.


Antwoord 6, autoriteit 4%

Dit:

int fillarr(int arr[])

wordt eigenlijk hetzelfde behandeld als:

int fillarr(int *arr)

Als u nu echt een array wilt retourneren, kunt u die regel wijzigen in

int * fillarr(int arr[]){
    // do something to arr
    return arr;
}

Het geeft niet echt een array terug. je stuurt een aanwijzer terug naar het begin van de
array-adres.

Maar onthoud dat als je de array doorgeeft, je alleen een pointer doorgeeft.
Dus wanneer u de arraygegevens wijzigt, wijzigt u in feite de gegevens die de
de aanwijzer wijst naar. Daarom moet u zich realiseren voordat u de array doorgeeft:
dat je al aan de buitenkant het gewijzigde resultaat hebt.

bijv.

int fillarr(int arr[]){
   array[0] = 10;
   array[1] = 5;
}
int main(int argc, char* argv[]){
   int arr[] = { 1,2,3,4,5 };
   // arr[0] == 1
   // arr[1] == 2 etc
   int result = fillarr(arr);
   // arr[0] == 10
   // arr[1] == 5    
   return 0;
}

Ik stel voor dat je zou kunnen overwegen om een lengte in je fillarr-functie te zetten, zoals
dit.

int * fillarr(int arr[], int length)

Op die manier kun je lengte gebruiken om de array tot zijn lengte te vullen, ongeacht wat het is.

Om het daadwerkelijk op de juiste manier te gebruiken. Doe zoiets als dit:

int * fillarr(int arr[], int length){
   for (int i = 0; i < length; ++i){
      // arr[i] = ? // do what you want to do here
   }
   return arr;
}
// then where you want to use it.
int arr[5];
int *arr2;
arr2 = fillarr(arr, 5);
// at this point, arr & arr2 are basically the same, just slightly
// different types.  You can cast arr to a (char*) and it'll be the same.

Als u alleen de array op een aantal standaardwaarden wilt instellen, kunt u overwegen om
de ingebouwde memset-functie.

zoiets als:
memset((int*)&arr, 5, sizeof(int));

Terwijl ik het toch over het onderwerp heb. Je zegt dat je C++ gebruikt. Kijk eens naar het gebruik van stl-vectoren. Uw code is waarschijnlijk robuuster.

Er zijn veel tutorials. Hier is er een die u een idee geeft van hoe u ze kunt gebruiken.
http://www.yolinux.com/TUTORIALS/LinuxTutorialC++STL.html


Antwoord 7, autoriteit 2%

om een array van een functie terug te geven, laten we die array in een structuur definiëren;
Dus het ziet er ongeveer zo uit

struct Marks{
   int list[5];
}

Laten we nu variabelen van de typestructuur maken.

typedef struct Marks marks;
marks marks_list;

We kunnen array op de volgende manier doorgeven aan een functie en er waarde aan toekennen:

void setMarks(int marks_array[]){
   for(int i=0;i<sizeof(marks_array)/sizeof(int);i++)
       marks_list.list[i]=marks_array[i];
}

We kunnen de array ook retourneren. Om de array te retourneren, moet het retourtype van de functie van het structuurtype zijn, dat wil zeggen marks. Dit komt omdat we in werkelijkheid de structuur passeren die de array bevat. De uiteindelijke code kan er dus zo uitzien.

marks getMarks(){
 return marks_list;
}

Antwoord 8

de eenvoudigste manier om dit te doen, is het terug te sturen door middel van verwijzing, zelfs als u niet schrijft
de ‘&’ symbool , het wordt automatisch geretourneerd door verwijzing

    void fillarr(int arr[5])
  {
       for(...);
  }

Antwoord 9

int *fillarr(int arr[])

Je kunt het resultaat nog steeds gebruiken zoals

int *returned_array = fillarr(some_other_array);
if(returned_array[0] == 3)
    do_important_cool_stuff();

10

Zoals hierboven genoemde paden correct zijn. Maar ik denk dat als we gewoon een lokale array-variabele van een functie retourneren, soms retourneert het vuilniswaarden als elementen.

In de volgorde om te voorkomen dat ik de array dynamisch moest maken en doorgaan. Wat zoiets is.

int* func()
{
  int* Arr = new int[100];
  return Arr;
}
int main()
{
  int* ArrResult = func();
  cout << ArrResult[0] << " " << ArrResult[1] << endl;
  return 0;
} 

11

template<typename T, size_t N>
using ARR_REF = T (&)[N];
template <typename T, size_t N>
ARR_REF<T,N> ArraySizeHelper(ARR_REF<T,N> arr);
#define arraysize(arr) sizeof(ArraySizeHelper(arr))

12

Bron: https://www.tutorialspoint.com/cplusplus/cpp_return_arrays_from_functies.htm

C++ staat niet toe om een ​​hele array als een argument aan een functie terug te sturen. U kunt echter een aanwijzer terugsturen naar een array door de naam van de array zonder een index op te geven.

  1. Als u een array met één dimensie van een functie wilt retourneren, moet u een functie aangeven die een aanwijzer terugkeert als in het volgende voorbeeld:
int * myFunction()    {
   .
   .
   .
}
  1. C++ pleiten niet om het adres van een lokale variabele naar buiten de functie te retourneren, zodat u de lokale variabele als statische variabele moet definiëren.

Het toepassen van deze regels inzake de huidige vraag, kunnen we het programma als volgt schrijven:

# include <iostream>
using namespace std;
int * fillarr( );
int main ()
{
   int *p;
   p = fillarr();
   for ( int i = 0; i < 5; i++ )
       cout << "p[" << i << "] : "<< *(p + i) << endl;
    return 0;
}
int * fillarr( )
{
    static int  arr[5];
    for (int i = 0; i < 5; ++i)
        arr[i] = i;
    return arr;
 }

De uitvoer is:

p[0]=0
p[1]=1
p[2]=2
p[3]=3
p[4]=4

13

en hoe zit het met:

int (*func())
{
    int *f = new int[10] {1,2,3};
    return f;
}
int fa[10] = { 0 };
auto func2() -> int (*) [10]
{
    return &fa;
}

14

Eigenlijk wanneer u een array in een functie passeert, wordt de aanwijzer naar de originele array doorgegeven in de functieparameter en wordt de wijzigingen die zijn aangebracht in de array in die functie daadwerkelijk op de originele array gemaakt.

#include <iostream>
using namespace std;
int* func(int ar[])
{
    for(int i=0;i<100;i++) 
        ar[i]=i;
    int *ptr=ar;
    return ptr;
}
int main() {
    int *p;
    int y[100]={0};    
    p=func(y);
    for(int i=0;i<100;i++) 
        cout<<i<<" : "<<y[i]<<'\n';
}

Voer het uit en u ziet de wijzigingen


15

En waarom niet “retourneren” de array als parameter?

fillarr(int source[], size_t dimSource, int dest[], size_t dimDest)
{
    if (dimSource <= dimDest)
    {
        for (size_t i = 0; i < dimSource; i++)
        {   
            //some stuff...
        }
    }
    else 
    {
        //some stuff..
    }
}

of..in een eenvoudiger manier (maar je moet de dimensies kennen …):

fillarr(int source[], int dest[])
{
    //...
}

16

Ik heb statische array gebruikt, zodat tijdens het terugsturen van de array het geen fout zou moeten gooien terwijl u het adres van de lokale variabele retourneert …
Dus nu kunt u een lokaal gemaakte variabele van de functie verzenden door het als statisch te maken … omdat het werkt als globale variabele ….

#include<iostream>
using namespace std;
char *func(int n)
{
   // char a[26]; /*if we use this then an error will occur because you are 
                        //  returning address of a local variable*/
    static char a[26];
    char temp='A'; 
    for(int i=0;i<n;i++)
    {
     a[i]=temp;temp++;
    }
    return a;
}
int main()
{
    int n=26;
    char *p=func(n);
    for(int i=0;i<n;i++)
     cout<<*(p+i)<<" ";
   //or you can also print like this
    for(int i=0;i<n;i++)
     cout<<p[i]<<" ";    
}

17

Hier is een volledig voorbeeld van dit soort probleem om

op te lossen

#include <bits/stdc++.h>
using namespace std;
int* solve(int brr[],int n)
{
sort(brr,brr+n);
return brr;
}
int main()
{
int n;
cin>>n;
int arr[n];
for(int i=0;i<n;i++)
{
    cin>>arr[i];
}
int *a=solve(arr,n);
for(int i=0;i<n;i++)
{
    cout<<a[i]<<endl;
}
return 0;
}

Antwoord 18

Definieer gewoon een type[ ] als retourwaarde, zoals:

       private string[] functionReturnValueArray(string one, string two)
    {
        string[] x = {one, two};
        x[0] = "a";
        x[1] = "b";
        return x;
    }

.
.
.
functie-aanroep:

string[] y;
y = functionReturnValueArray(stringOne, stringTwo)

Other episodes