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

Funkcje, typy i zastosowanie. Jak używać?

VPS Starter Arubacloud
+1 głos
667 wizyt
pytanie zadane 19 lipca 2019 w C i C++ przez magda_19 Gaduła (3,080 p.)
Jaka jest różnica między funkcją bez argumentów, w której ciele umieścimy argumenty a funkcją z podanymi argumentami w nagłówku? Po co używamy czasami funkcji void?

5 odpowiedzi

+1 głos
odpowiedź 19 lipca 2019 przez Paweł Nąckiewicz Nałogowiec (48,990 p.)

Zacznę od końca. Za przykład wezmę system rezerwacji biletów w kinie. Będę pisać w Javie ale mam nadzieje, że ktoś z C++ mnie zrozumie :)

Funkcji void używamy aby powiedzieć, że dana funkcja ma nic nie zwracać. Tutaj trudno moim zdaniem bez większego doświadczenia zorientować się, kiedy użyć funkcji zwracającej coś lub nie. Ale załóżmy, że mamy program który ma dodać użytkownika do seansu. (To jest bardzo prymitywny przykład ale chodzi o zrozumienie). Nie musisz tutaj nic zwracać (choć oczywiście możesz). Im więcej będziesz programować tym częściej będziesz używać funkcji void ale to przyjdzie z czasem. 

class RezerwacjaService{
    public void zarezerwujBilet(Widz widz, Film film){
        System.out.println(widz + "zakupil bilet na " + film);
    }
}
class Widz{
    String imie;
}
class Film{
    String tytul;
}
   

Jeśli chodzi o funkcję z argumentami a bez to tutaj wyłania się kolejny problem, który pokazuje kod wyżej. Mając tak napisaną funckcję zarezerwujBilet możesz dynamicznie zarządzać wartościami przy których operuje funkcja. Możesz ta samą funkcję wywołać dla różnych tytułów filmów bo podajesz je w argumencie podczas wywoływania funkcji. Jeśli nie użyłbyś argumentów w funkcji mógłbyś skomplikować swój kod do takiego poziomu. 

class login {
    public static void main(String[] args) {
        RezerwacjaService rezerwacjaService = new RezerwacjaService(); //tworzenie obiektu z klasy RezerwacjaService
        rezerwacjaService.zarezerwujBiletHarryPoter(); //wywołanie medoty -> wysiwetli sie "widz zakupil bilet na HarryPoter w dniu dd-mm-rrrr hh-mm"
        rezerwacjaService.zarezerwujBiletIgrzyskaSmierci();
        rezerwacjaService.zarezerwujBiletMadagaskar();
    }
}
class RezerwacjaService{
    public void zarezerwujBiletMadagaskar(){
        System.out.println("widz zakupil bilet na Madagaskar w dniu dd-mm-rrrr hh-mm ");  //wyswietlanie tekstu
    }
    public void zarezerwujBiletHarryPoter(){
        System.out.println("widz zakupil bilet na HarryPoter w dniu dd-mm-rrrr hh-mm ");
    }
    public void zarezerwujBiletIgrzyskaSmierci(){
        System.out.println("widz zakupil bilet na Igrzyska Smierci w dniu dd-mm-rrrr hh-mm ");
    }
}

Dobra praktyka, używaj funkcji wszędzie gdzie się da ale staraj się nie robić funkcji więcej niż z 4 argumentami. Kodu koduj koduj i wszystko wejdzie do głowy. Mam nadzieję, że pomogłem i kod Javowy dasz rade ogarnąć. 

0 głosów
odpowiedź 19 lipca 2019 przez profesorek96 Szeryf (91,420 p.)
Tak naprawdę to możesz pisać programy bez funkcji. Będzie to działało jednak ewentualna zmiana wymusi zmianę nie w jednym miejscu a w wielu. Przykład masz funkcje licząca wartość podatku VAT z kwoty netto. Możesz to zrobić bez funkcji, o ile twój kod jest krótki to nie ma to problemu. Wyobraź sobie że wielokrotnie liczysz wartość podatku, kod obliczający to pojawia się często. Teraz np musisz zmienić wartość VAT z 21 na 18 procent. Swoją zmianę musisz wykonać skrupulatnie w wielu miejscach, łatwo o pominięcie czegoś. Jeśli używasz funkcji to wystarczy że zmienisz w jej wnętrzu i to wystarczy. Funkcje pomagają porządkować twój kod oraz sprawiają że jest on reuzywalny, raz napisane funkcje możesz używać w innych programach.
0 głosów
odpowiedź 19 lipca 2019 przez adrian17 Ekspert (344,100 p.)

Jaka jest różnica między funkcją bez argumentów, w której ciele umieścimy argumenty

Nie ma czegoś takiego. Pokażesz, co masz na myśli?

Po co używamy czasami funkcji void?

Gdy funkcja nic nie zwraca. Na przykład może napisać coś do pliku lub na konsolę - nie ma potrzeby wtedy cokolwiek zwracać.

komentarz 19 lipca 2019 przez magda_19 Gaduła (3,080 p.)

Różnica między takimi funkcjami: 

#include <iostream>

using namespace std;

int suma ()
{
   int liczba1, liczba2;

//Jakieś obliczenia


}

A taką funkcją:

#include <iostream>

using namespace std;

int suma (int liczba1, int liczba2)
{
   //Jakieś obliczenia


}

 

komentarz 19 lipca 2019 przez Paweł Nąckiewicz Nałogowiec (48,990 p.)

Wyjaśniłem to w mojej odpowiedzi ale powtórzę. W tym przypadku jak będziesz używała funckji 1 - bez argumentów, zawsze funkcja będzie zwracać to samo (ponieważ wartości masz stałe z góry zadeklarowane). Jeśli wywołasz funckję z argumentami możesz za każdym razem otrzymywać inny wynik (co jest lepsze) 

#include <iostream>

using namespace std:

int suma(){
   int a =1 , b =2;
   return a+b; //zawsze zwroci to samo =3
}
int suma(int a, int b){
   return a+b; //zworci liczbe zalezna od podanych argumentow
}


int main(){

   suma(); //zwroci 3
   suma(2,4) //zwroci 6
   // jesli programujesz kalkulator i masz funkcje dodaj to lepiej zastosowan w funkcji argumenty
   //nigdy nie wiadomo jakie liczby ktos bedzie chcial do siebie dodac -> ot cala rozniaca
}

 

1
komentarz 19 lipca 2019 przez adrian17 Ekspert (344,100 p.)
int suma ()
{
   int liczba1, liczba2;

To nie są "argumenty w ciele funkcji", to zwykłe zmienne.

int suma (int liczba1, int liczba2)

A ta funkcja bierze dwa argumenty.

0 głosów
odpowiedź 19 lipca 2019 przez Chess Szeryf (76,710 p.)
edycja 19 lipca 2019 przez Chess

x86 Jeśli utworzysz ramkę stosu, to pierwszy przykład przedstawia zmienne lokalne znajdujące się w funkcji.

push ebp
mov ebp, esp
sub esp, 8

mov dword[ebp-4], 1
mov dword[ebp-8], 2

; ...

mov esp, ebp
pop ebp
retn 8

Natomiast drugi przykład oznacza argumenty funkcji.

push ebp
mov ebp, esp
sub esp, 8

mov dword[ebp+8], 1
mov dword[ebp+12], 2

; ...

mov esp, ebp
pop ebp
retn 8

Jest to przydatne, jeśli chcesz wywoływać tę samą funkcję z różnymi argumentami, czyli np. 

(defun sum-1 (a b)
  (+ a b)) ; => SUM-1

(sum-1 5 9) ; => 14
(sum-1 10 2) ; => 12

; Common Lisp

Bazując na zmiennych lokalnych byłoby to niemożliwe.

Poniżej kod konkatenacji dwóch łańcuchów znaków, nie wiem czy poprawnie napisany, ponieważ za bardzo nie testowałem.


	global _main
	extern _printf

	section .data

fmt_c:	db "%c", 0
fmt_s:	db "%s", 0
fmt_n:	db "%hhu", 0
s1:	db "abcdef_as", 0
s2:	db "123def", 0
s3:	db "flower", 0

	section .text

_main:	

	push ebp
	mov ebp, esp
	sub esp, 8

	mov dword[ebp+8], s1
	mov dword[ebp+12], s2
	

	call concat
	
	push eax
	push fmt_s
	call _printf
	add esp, 8


	mov esp, ebp
	pop ebp

	retn 8

concat:	


	mov eax, dword[ebp+8]
	lea eax, [eax]

	call len_s

	mov esi, ecx

	mov ebx, dword[ebp+12]
	lea ebx, [ebx]

	dec ebx
	
	mov ecx, 0

l2:


	xor edx, edx
	
	inc ebx

	
	mov dl, [ebx]

	mov edi, ecx
	

	add ecx, esi
	
	mov word[eax+ecx], dx


	mov ecx, edi
	
	inc ecx
	cmp ecx, esi
	jne l2


	ret
	

len_s:

	mov ecx, -1

l1:


	inc ecx

	cmp byte[eax+ecx], 0x00
	jne l1
	

	ret
	

Kompilacja pod Windows (10) - assembler NASM.

nasm -fwin32 concat.asm && gcc concat.obj -o concat.exe && concat.exe

Prototyp funkcji (jest to już gotowa napisana funkcja) np. w Common Lisp wygląda tak

(let ((source-1 "abcdef_as")
      (destination-1 "123def"))
  (concatenate 'string source-1 destination-1)) ; => abcdef_as123def
2
komentarz 21 lipca 2019 przez adrian17 Ekspert (344,100 p.)
(...huh. Nie odpowiedziałeś przypadkiem na złe pytanie? :P Bo tu autor pyta raczej o podstawy składni C++a, strzelam że nie zrozumie ani tego asma, ani lispa.)
0 głosów
odpowiedź 21 lipca 2019 przez niezalogowany
edycja 21 lipca 2019

a to nie wiem czy się przyda

#include <iostream>
struct flagi
{
    bool cout_flaga_1=0;
    bool cout_flaga_2=0;
    bool cout_flaga_3=0;
    bool cout_flaga_4=0;
    bool cout_flaga_5=0;
    bool cout_flaga_6=0;
    bool cout_flaga_7=0;
    bool cout_flaga_8=0;
    bool cout_flaga_9=0;
} f; // globalny f
using namespace std;
void ustaw_flagi (flagi &f, bool cout_flaga_1,bool cout_flaga_2,bool cout_flaga_3,bool cout_flaga_4,bool cout_flaga_5,bool cout_flaga_6,bool cout_flaga_7,bool cout_flaga_8,bool cout_flaga_9);
void liczbe();
void zeruj_flagi (flagi &f);
string kot {"kot"};

int main ()
{
// flagi steruj¹ce%%%%%%%%%%%%%%%%%%%%%%%%%%%%

// flagi steruj¹ce end%%%%%%%%%%%%%%%%%%%%%%%%%%%
    ustaw_flagi (f,1,1,1,0,0,1,1,0,2);
    liczbe();

    zeruj_flagi(f);


    return 0;
}
//********************
void ustaw_flagi (flagi &f,bool cout_flaga_1,bool cout_flaga_2,bool cout_flaga_3,bool cout_flaga_4,bool cout_flaga_5,bool cout_flaga_6,bool cout_flaga_7,bool cout_flaga_8,bool cout_flaga_9)
{
    f.cout_flaga_1=cout_flaga_1;
    f.cout_flaga_2=cout_flaga_2;
    f.cout_flaga_3=cout_flaga_2;
    f.cout_flaga_4=cout_flaga_4;
    f.cout_flaga_5=cout_flaga_5;
    f.cout_flaga_6=cout_flaga_6;
    f.cout_flaga_7=cout_flaga_7;
    f.cout_flaga_8=cout_flaga_8;
    f.cout_flaga_9=cout_flaga_9;
};
void zeruj_flagi (flagi &f)
{
 f={0,0,0,0,0,0,0,0,0};
};
void liczbe()
{
    cout<<f.cout_flaga_1<<endl;
    cout<<f.cout_flaga_2<<endl;
    cout<<f.cout_flaga_3<<endl;
    cout<<f.cout_flaga_4<<endl;
    cout<<f.cout_flaga_5<<endl;
    cout<<f.cout_flaga_6<<endl;
    cout<<f.cout_flaga_7<<endl;
    cout<<f.cout_flaga_8<<endl;
    cout<<f.cout_flaga_9<<endl;
    kot="pies";
    cout<<kot;
}

Edit:

liczbe(); //to wygląda bardzej fanie niż to
liczbe(flagi &f,bool cout_flaga_1,bool cout_flaga_2,bool cout_flaga_3,bool cout_flaga_4,bool cout_flaga_5,bool cout_flaga_6,bool cout_flaga_7,bool cout_flaga_8,bool cout_flaga_9)

A jak by było 10 funkcji liczbe1(), liczbe2(), ...... i poustawiać każdy argument;

Napisałem parę głupot wczoraj, ale kompilator mi to uświadomił i miałem dobrą powtórkę wiedzy,
a więc dzięki za wątek.

i tak
funkcje bez argumentu, czy ze zmienną nie przekazaną jako argument.

Są to zmienne globalne i dopuszczasz by funkcja mogła je zmienić bez referencji, niby zmiennych globalnych sie nie stosuje,
ale jakieś główne (zmienne) nastawy programu, myślę że jak najbardziej.

edit : A tak w ogóle to mnie nie słuchaj, bo nie jestem programistą i nie wiem czy to dobra praktyka.

Podobne pytania

0 głosów
1 odpowiedź 632 wizyt
pytanie zadane 16 maja 2018 w JavaScript przez Tomasz Ozi Orzech Początkujący (300 p.)
0 głosów
1 odpowiedź 536 wizyt
pytanie zadane 13 października 2016 w C i C++ przez Evelek Nałogowiec (28,960 p.)
–2 głosów
1 odpowiedź 274 wizyt
pytanie zadane 18 grudnia 2018 w C i C++ przez pysiek Początkujący (280 p.)

92,455 zapytań

141,263 odpowiedzi

319,100 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!

...