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

Jaka jest różnica między tymi dwiema funkcjami używającymi struktur?

0 głosów
60 wizyt
pytanie zadane 6 września w C i C++ przez magda_19 Obywatel (1,650 p.)

Witam, właśnie przerabiam funkcje i struktury i nie mogę zrozumieć jaka jest różnica między funkcją, która przyjmuje obiekt struktury jako argument, a czasami ma postać jakby się do struktury odwoływała. Jaka jest różnica między obiema oraz dlaczego w ogóle używamy travel_time sum?

#include <iostream>

using namespace std;

struct travel_time
{
    int hours;
    int minutes;
};

const int minutes_per_hr = 60;

travel_time sum(travel_time t1, travel_time t2)
{
    travel_time total;

    total.minutes = (t1.minutes + t2.minutes) % minutes_per_hr;
    total.hours = t1.hours + t2.hours + (t1.minutes + t2.minutes) / minutes_per_hr;

    return total;
}

void show_time(travel_time t)
{
    cout << t.hours << " godzin, "
         << t.minutes << " minut\n";
}

int main()
{
    travel_time day1 = {5, 45};  //obiekt struktury travel_time; oznacza 5 godz. 45 min
    travel_time day2 = {4, 55};  //obiekt struktury travel_time; oznacza 4 godz. 55 min

    travel_time trip = sum(day1, day2);
    cout << "Suma dwoch dni: ";
    show_time(trip);

    travel_time day3 = {4, 32};
    cout << "Suma trzech dni: ";
    show_time(sum(trip, day3));
    return 0;
}

 

komentarz 6 września przez tangarr Nałogowiec (38,440 p.)

Co masz na myśli mówiąc "czasami ma postać jakby się do struktury odwoływała"?
Każda funkcja ma postać:

zwracany_typ nazwa_funkcji(argumenty_funkcji)

Funkcja travel_time sum(travel_time t1, travel_time t2) przyjmuje dwa parametry typu travel_time, wykonuje na nich jakieś obliczenia i zwraca wynik typu travel_time.
Pytasz dlaczego masz w kodzie funkcję travel_time sum(travel_time t1, travel_time t2)? A dlaczego w ogóle dzielimy kod na funkcje? Po to aby ułatwić sobie życie. Przeniesienie obliczeń do osobnej funkcji pozwala nam używać tych obliczeń wiele razy na niezależnych obiektach, ułatwia czytelność kodu i pozwala uniknąć błędów spowodowanych pomyłką podczas modyfikacji skopiowanego kodu.

komentarz 6 września przez magda_19 Obywatel (1,650 p.)
No właśnie co masz na myśli, pisząc, że zwraca wynik typu travel_time?

Dlaczego druga funkcja już nie zwraca takiego wyniku?
komentarz 6 września przez adrian17 Mędrzec (199,740 p.)

Dlaczego druga funkcja już nie zwraca takiego wyniku?

show_time?

Bo nie ma w niej "return" (dosłownie "zwróć") bo nie ma potrzeby by cokolwiek zwracała - bo tylko pokazuje na konsoli to co dostała.

1 odpowiedź

0 głosów
odpowiedź 6 września przez tangarr Nałogowiec (38,440 p.)
wybrane 6 września przez magda_19
 
Najlepsza

Wróćmy do podstaw.
Jak już pisałem w komentarzu, każda funkcja ma postać

zwracany_typ nazwa_funkcji(argumenty_funkcji)

Typ void oznacza, że funkcja nie zwraca wyniku.
Przykładowe funkcje:

int dodaj(int a, int b) { // funkcja zwraca wartość int
    int wynik = a+b; 
    return wynik // zwracana wartość
}
void dodaj_i zapomnij(int a, int b) { // funkcja nie zwraca wartości
    int wynik = a+b; 
    // funkcja kończy swoje działanie bez zwracania wyniku
    // zmienna wynik jest "zapominana", nie ma znaczenia dla programu
}
void wczesniejsze_wyjscie(int a, int b) { // funkcja nie zwraca wartości
    if (a == b)
        return; // wyjście z funkcji bez zwracania wartości
    int wynik = a+b; 
    // funkcja kończy swoje działanie bez zwracania wyniku
    // zmienna wynik jest "zapominana", nie ma znaczenia dla programu    
}

Zamiast prostego typu danych funkcja może zwracać klasę lub strukturę.

#include <iostream>

using namespace std;

struct osoba {
    string imie;
    string nazwisko;
    int wiek;
};

osoba utworz_mariana_kowalskiego_18() {
    osoba marian = { "Marian", "Kowalski", 18 };
    return marian;
}

int main() {
   osoba ktos = utworz_mariana_kowalskiego_18();
   cout << "Imie: " << ktos.imie << endl;
   cout << "Nazwisko: " << ktos.nazwisko << endl;
   cout << "Wiek: " << ktos.wiek << endl;
   return 0;
}

Zawsze gdy podajesz zmienną jako argument funkcji, tak naprawdę do funkcji przekazywana jest kopia obiektu. Jeżeli twoja struktura jest duża kopiowanie może zająć dużo czasu, a przy niektórych obiektach może być wręcz niemożliwe (usunięty lub prywatny konstruktor kopiujący).
Dlatego zawsze lepiej jest używać referencji do obiektu (a jeszcze lepiej stałej referencji, żeby uniknąć przypadkowej modyfikacji twojego obiektu).
 

void tu_jest_robiona_kopia(osoba ktos) {
   // pracujesz na kopii
   // modyfikacja zmiennej ktos nie modyfikuje oryginalnego obiektu
   // tylko kopię wewnątrz tej funkcji
}

void tu_jest_przekazywana_referencja(osoba &ktos) {
   ktos.imie = "Ktoś inny"; // zmienną ktoś można zmodyfikować
}

void tu_jest_przekazywana_stala_referencja(const osoba &ktos) {
   // możesz czytać ze zmiennej ktoś, ale nie możesz jej modyfikować
}

 

komentarz 6 września przez magda_19 Obywatel (1,650 p.)
Dziękuję bardzo za tak rzetelne wytłumaczenie. Teraz już mi się wszystko rozjaśnia w głowie.

Podobne pytania

0 głosów
1 odpowiedź 125 wizyt
pytanie zadane 29 listopada 2018 w C i C++ przez ciocialol Nowicjusz (140 p.)
+1 głos
2 odpowiedzi 67 wizyt
pytanie zadane 2 września w C i C++ przez magda_19 Obywatel (1,650 p.)
0 głosów
1 odpowiedź 40 wizyt
Porady nie od parady
Pytania na temat serwisu SPOJ należy zadawać z odpowiednią kategorią dotyczącą tej strony.SPOJ

66,453 zapytań

113,207 odpowiedzi

239,680 komentarzy

46,704 pasjonatów

Przeglądających: 266
Pasjonatów: 15 Gości: 251

Motyw:

Akcja Pajacyk

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

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...