• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Dodawanie zmiennych w tablicach z użyciem różnych funkcji i ich zwracanie.

VPS Starter Arubacloud
0 głosów
427 wizyt
pytanie zadane 27 kwietnia 2017 w C i C++ przez Matheyas Obywatel (1,520 p.)

Cześć

Mam coś takiego:

 

#include <iostream> 
using namespace std;
float Super_Grzybo_Suchar (float grzyb[], float suchar[])
{
 float wynik[5];
 for (int i=0; i<5; i++)
 {
   wynik[i]=grzyb[i]+suchar[i];
   cout<< wynik[i]<< " ";
 }
return wynik; // ??? problem, nie wiem jak zwrócić
}

int main()
{
      float Grzybki[]={60.04, 0, 598.56, 24.04, 32.1,0};
      float Sucharki[]={57.58, 0, 582.12, 24.88, 31.1,0};



    cout <<"wynik to: " << Super_Grzybo_Suchar(Grzybki,Sucharki); // Tutaj też mi coś nie pasuje...


    return 0;

 

Mam problem z zwrotem wyniku do main, tak abym mógł zarządzać ów sumą w tablicach. Tak wiem, że do tak łatwej rzeczy nie potrzebuję funkcji, lecz mam zamiar wprowadzić więcej danych.

Szukając informacji, często natykałem się na wskaźniki (nie jestem jeszcze w stanie się do nich przekonać :) ) Czy rozwiązaniem będą wskaźniki? Nie rozumiem ich więc pewności nie mam. Tak, mam zamiar do nich przysiąść, ale w późniejszym terminie. Podzielicie się wskazówką?  :)

Pozdrawiam Mateusz.

 

 

3 odpowiedzi

+1 głos
odpowiedź 27 kwietnia 2017 przez Evelek Nałogowiec (28,960 p.)

Na przykład tak:

#include <iostream> 
using namespace std;

float *Super_Grzybo_Suchar(float grzyb[], float suchar[]) {
	float *wynik = new float[5];
	for (int i = 0; i < 5; i++) {
		wynik[i] = grzyb[i] + suchar[i];
		cout << wynik[i] << " ";
	}
	return wynik;
}

int main() {
	float Grzybki[] = { 60.04, 0.0, 598.56, 24.04, 32.1, 0.0 };
	float Sucharki[] = { 57.58, 0.0, 582.12, 24.88, 31.1, 0.0 };

	float *wynik = Super_Grzybo_Suchar(Grzybki, Sucharki);
	cout.put('\n');
	for (int i = 0; i < 5; ++i)
		cout << *(wynik + i) << endl;

	cin.get();
	return 0;
}

 

1
komentarz 28 kwietnia 2017 przez draghan VIP (106,230 p.)

Tworzysz w ten sposób wyciek pamięci.

int main() {
    float Grzybki[] = { 60.04, 0.0, 598.56, 24.04, 32.1, 0.0 };
    float Sucharki[] = { 57.58, 0.0, 582.12, 24.88, 31.1, 0.0 };
 
    float *wynik = Super_Grzybo_Suchar(Grzybki, Sucharki);
    cout.put('\n');
    for (int i = 0; i < 5; ++i)
        cout << *(wynik + i) << endl; // nie prościej: cout << wynik[i] << '\n'; ?
 
    cin.get();
    delete[] wynik;
    return 0;
}

 

komentarz 28 kwietnia 2017 przez Matheyas Obywatel (1,520 p.)
Sprawdzę w domu, czyli wskaźniki powinny być moim priorytetem do nauki?
komentarz 28 kwietnia 2017 przez Matheyas Obywatel (1,520 p.)
Działa :) Czytam o tych wskaźnikach, strasznie ciężkie...
komentarz 28 kwietnia 2017 przez draghan VIP (106,230 p.)
Nie są takie straszne. :) Podstawy działania są nietrudne do ogarnięcia, a wskaźniki "trudniejsze", czyli wskaźniki na funkcje czy wskaźniki na wskaźniki na wskaźniki... są tylko groźnie wyglądające z powodu notacji.

Jednakże nie ma potrzeby teraz się tego uczyć. Po to wprowadzono pewne klasy biblioteczne do standardu C++, żeby nie było konieczności bezpośredniego używania wskaźników, przy których bardzo łatwo o błąd (patrz przykład Evelka - niby w main() nie widać żadnego new, a delete należy zrobić...). Głównymi zastępcami są std::string i std::vector, które zastępują działania na łańcuchach znaków char[] i gołych tablicach (statycznych i dynamicznych) oraz std::shared_ptr i std::unique_ptr, które zastępują surowe wskaźniki tam, gdzie jednak wypadałoby wskaźników użyć.
komentarz 28 kwietnia 2017 przez Evelek Nałogowiec (28,960 p.)
Celowo musiałem zwrócić na to uwagę, aby się bardziej w oczy rzucało o czym trzeba pamiętać. :D ...a tak serio to zapomniałem, smart pointery mnie wyręczają z takich rzeczy. :/
komentarz 28 kwietnia 2017 przez Matheyas Obywatel (1,520 p.)

Od kilku godzin studiuje wskaźniki. Coraz więcej rozumiem, ale nadal mam problem z funkcja+tablica+wskazniki. Najczęściej wyskakuje (w sumie prawie zawsze) błąd:

error: cannot convert 'int*' to 'int**' for argument '1' to 'int oblicz(int**, int*)'|

Prędzej czy później ogarnę. Dzięki panowie.

komentarz 28 kwietnia 2017 przez draghan VIP (106,230 p.)
Pokaż kod, którym powodujesz taki błąd. Coś poradzimy. ;)
+1 głos
odpowiedź 28 kwietnia 2017 przez mokrowski Mędrzec (155,460 p.)

Tu jest kilka zagadnień które trzeba dotknąć:

1. Tablica w języku C++ ("odziedziczona po C"), przy przesyłaniu do funkcji, wymaga przekazania wymiaru. Jeśli upierasz się na tablice, będzie konieczne zdefiniowanie tego wymiaru i konsekwentne stosowanie wszędzie gdzie występuje tablica. Innym rozwiązaniem będzie przesyłanie tego wymiaru za każdym razem do funkcji. Możliwe definicje funkcji:

void func1(float table1[20]);
void func2(float * table1, size_t table_length);

// Lub.. 
constexpr static size_t table_size = 5;
void func3(float table3[table_size]);

Wprawdzie jest możliwe dedukowanie wymiaru z szablonu ale to technika która ma konsekwencje.

2. Zwrócenie wartości w postaci tablicy z funkcji, będzie wymagało alokowania pamięci na stercie. Znów tablica "gubi wymiar" i w zasadzie jedyne co możesz zrobić to zwrócić wskaźnik. Trzeba wtedy użyć new i po sobie posprzątać poprzez delete. W przeciwnym wypadku dojdzie do wycieku pamięci. Obecnie jednak już nie ma powodu by posługiwać się "gołym new/delete" i stosuje się wskaźniki inteligentne. 

Przykład z new/delete:

#include <iostream>

using namespace std;

constexpr static size_t table_size = 5;

float * Super_Grzybo_Suchar (float grzyb[table_size], float suchar[table_size])
{
    float * wynik = new float[table_size]; // Alokowanie miejsca na stercie
    for (size_t i = 0; i < table_size; ++i)
    {
        wynik[i] = grzyb[i] + suchar[i];
    }
    return wynik; 
}

int main()
{
    float Grzybki[]= {60.04, 0, 598.56, 24.04, 32.1};
    float Sucharki[]= {57.58, 0, 582.12, 24.88, 31.1};


    float * wynik = Super_Grzybo_Suchar(Grzybki, Sucharki); 
    
    cout << "Wynik to: ";
    for(size_t i = 0; i < table_size; ++i) {
        cout << wynik[i] << ' ';
    }
    cout << '\n';
    
    delete [] wynik; // Tu sprzątanie.
}

Przykład z unique_ptr. Jak widać nie trzeba "sprzątać". Podawałem typy jawnie abyś wiedział co się dzieje. Jak widzisz dalej jest problem z rozmiarem. Inteligentny wskaźnik rozwiązuje problem usuwania z pamięci a nie rozmiaru tablicy.

#include <iostream>
#include <memory>

using namespace std;

constexpr static size_t table_size = 5;

unique_ptr<float[]> Super_Grzybo_Suchar (float grzyb[table_size], float suchar[table_size])
{
    unique_ptr<float[]> wynik = make_unique<float[]>(table_size); // Alokowanie miejsca na stercie
    for (size_t i = 0; i < table_size; ++i)
    {
        wynik[i] = grzyb[i] + suchar[i];
    }
    return wynik; 
}

int main()
{
    float Grzybki[]= {60.04, 0, 598.56, 24.04, 32.1};
    float Sucharki[]= {57.58, 0, 582.12, 24.88, 31.1};


    unique_ptr<float[]> wynik = Super_Grzybo_Suchar(Grzybki, Sucharki); 
    
    cout << "Wynik to: ";
    for(size_t i = 0; i < table_size; ++i) {
        cout << wynik[i] << ' ';
    }
    cout << '\n';
    
}

3. I na koniec dedukcja poprzez szablon, inteligentne wskaźniki, typ auto:

#include <iostream>
#include <memory>

using namespace std;

constexpr static size_t table_size = 5;

template<typename T, size_t N>
auto Super_Grzybo_Suchar (T (&grzyb)[N], T (&suchar)[N])
{
    auto wynik = make_unique<T[]>(N); // Alokowanie miejsca na stercie
    for (size_t i = 0; i < N; ++i)
    {
        wynik[i] = grzyb[i] + suchar[i];
    }
    return wynik; 
}

int main()
{
    float Grzybki[table_size] = {60.04, 0, 598.56, 24.04, 32.1};
    float Sucharki[table_size] = {57.58, 0, 582.12, 24.88, 31.1};


    auto wynik = Super_Grzybo_Suchar(Grzybki, Sucharki); 
    
    cout << "Wynik to: ";
    for(size_t i = 0; i < table_size; ++i) {
        cout << wynik[i] << ' ';
    }
    cout << '\n';
    
}

Wow... jaka fajna zabawka! Tyko... 

4. Powiedz po co to wszystko robić kiedy masz .... vector? Sam zajmie się usunięciem z pamięci danych, przechowuje wielkość i nie zawracasz sobie głowy rzeczami które opisałem wcześniej:

#include <iostream>
#include <vector>

using namespace std;

auto Super_Grzybo_Suchar (const vector<float>& grzyb, 
    const vector<float>& suchar)
{
    auto wynik = grzyb;
    for (size_t i = 0; i < grzyb.size(); ++i)
    {
        wynik[i] += suchar[i];
    }
    return wynik; 
}

int main()
{
    vector<float> Grzybki = {60.04, 0, 598.56, 24.04, 32.1};
    vector<float> Sucharki = {57.58, 0, 582.12, 24.88, 31.1};


    auto wynik = Super_Grzybo_Suchar(Grzybki, Sucharki); 
    
    cout << "Wynik to: ";
    for(const auto v: wynik) {
        cout << v << ' ';
    }
    cout << '\n';
    
}

 

 

komentarz 28 kwietnia 2017 przez Matheyas Obywatel (1,520 p.)
edycja 28 kwietnia 2017 przez Matheyas
Jej, fajne informacje​. Teraz wiem co szukać. Jednakże dopiero zaczynam zabawę z funkcjami, znam tablice dlatego ich uzywam. Chcę przechowywać w jednej zmiennej kilka, kilkanaście wartości, które później będę sumowal, dzielił, mnożył itd za pomocą funkcji.

Przetestuje to co napisałes, gdy wrócę pracy. Dzięki :)

//Niestety żadna metoda nie działa. Wyskakują błędy.
komentarz 30 kwietnia 2017 przez Matheyas Obywatel (1,520 p.)
Jak tylko wrócę z majówki, wyślę błędy które mi wyskakują. Widocznie problem leży po stronie mojego kompilatora. (Code::block)
0 głosów
odpowiedź 28 kwietnia 2017 przez Knayder Nałogowiec (37,640 p.)
Zawsze możesz przekazać tablicę przez referencję do funkcji i tam wpisać potrzebne dane. W ten sposób nie musisz nic zwracać. (Może zwracać bool, który powie czy wszystko poszło ok)
komentarz 28 kwietnia 2017 przez unknown Nałogowiec (39,560 p.)

Zawsze możesz przekazać tablicę przez referencję do funkcji

Ale po co? 

Podobne pytania

0 głosów
1 odpowiedź 241 wizyt
pytanie zadane 26 sierpnia 2019 w JavaScript przez Whereismycode Obywatel (1,710 p.)
0 głosów
1 odpowiedź 1,736 wizyt
pytanie zadane 26 listopada 2020 w C i C++ przez mik53r Nowicjusz (150 p.)
0 głosów
1 odpowiedź 559 wizyt
pytanie zadane 25 kwietnia 2020 w C i C++ przez Anahan89 Obywatel (1,270 p.)

92,452 zapytań

141,262 odpowiedzi

319,085 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...