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

Tablica jako argument funkcji

0 głosów
1,340 wizyt
pytanie zadane 15 marca 2020 w Programowanie przez Daaa22 Dyskutant (8,250 p.)

Mam taki kod

void funkcja( int* tab )
{
    return;
}

int main()
{
    int tab[ 3 ] = { 1, 2, 3 };

    funkcja( tab );

    return 0;
}

Czy jest możliwość zapisania tego bez tworzenia zmiennej tab? Bo pisząc taki kod wyskakuje błąd

void funkcja( int* tab )
{
    return;
}

int main()
{
    funkcja( { 1, 2, 3 } );

    return 0;
}

 

3 odpowiedzi

+1 głos
odpowiedź 15 marca 2020 przez mokrowski Mędrzec (158,580 p.)

Oczywiście że jest. W C (bez plusów), w standardzie C99, można stosować wywołanie narzucające typ danych w trakcie wykonania. Reguły wnioskowania domyślnych konwersji do typu docelowego, przekształcają, typ tablicy we wskaźnik na dane. https://en.cppreference.com/w/c/language/array sekcja Array to pointer conversion

#include <stdio.h>

void funkcja( int* tab )
{
    do {
        printf("%d ", *(tab++));
    } while(*tab != 0);
}

int main(void)
{
    funkcja( (int[]){ 1, 2, 3, 0 } );

    return 0;
}

https://en.cppreference.com/w/c/language/compound_literal

Pamięć takiej tablicy alokowana jest w ramach ramki stosu funkcji wywołującej (w tym przypadku main(...) ) i poprawnie usunięta w przypadku zwinięcia ramki https://godbolt.org/z/ShNyY3 Nie następuje tu żadne alokowanie dynamiczne i nie wymaga to również żadnego dealokowania.

Nie jest natomiast to poprawne w C++. Tu od podobnych działań, masz r-referencję.

0 głosów
odpowiedź 15 marca 2020 przez adrian17 Mentor (354,120 p.)
Nie możesz.

(a czemu potrzebujesz coś takiego?)
komentarz 15 marca 2020 przez Daaa22 Dyskutant (8,250 p.)

Chciałem krócej zapisać. I jak się okazuje jednak mogę

void funkcja( int* tab )
{
    return;
}
 
int main()
{
    funkcja( new int[3]{ 1, 2, 3 } );
 
    return 0;
}

 

komentarz 15 marca 2020 przez adrian17 Mentor (354,120 p.)
Tylko, że to robi coś innego - alokujesz dynamicznie (a nie na stosie) i w dodatku nie zwalniasz pamięci, więc masz wycieki.
komentarz 15 marca 2020 przez Daaa22 Dyskutant (8,250 p.)
A jak dopisze delete [] tab; w środku funkcji to nie zwolni się pamięć?
komentarz 15 marca 2020 przez adrian17 Mentor (354,120 p.)
Zwolni się... tylko że to bardzo niezalecany sposób zarządzania pamięcią; ogólnie to jest dużo skompilkowania, plus marnowanie czasu i pamięci programu bo z jakiegoś powodu nie chcesz zrobić zwykłej zmiennej.
komentarz 15 marca 2020 przez Daaa22 Dyskutant (8,250 p.)
Czyli w sumie to kod jest dobry tylko bardzo nieczytelny?
komentarz 15 marca 2020 przez adrian17 Mentor (354,120 p.)
Technicznie poprawny, ale bardzo odradzany.

(wciąż nie wiem, czemu koniecznie chcesz ominąć używanie zmiennej)
0 głosów
odpowiedź 15 marca 2020 przez profesorek96 Szeryf (91,400 p.)

To co próbujesz zrobić nie jest poprawne w żaden sposób. Język C++ nie posiada mechanizmu GarbageColector. Jeśli wykonujesz tak kod

void funkcja( int* tab )
{
    return;
}
  
int main()
{
    funkcja( new int[3]{ 1, 2, 3 } );
  
    return 0;
}

Twoja funkcja przyjmuje wskaźnik na int, jest to ok zaś ty w mainie przekazujesz jej dynamicznie zablokowaną tablice. Dokładniej mówiąc operator new alokuje pamięć i zwraca wskaźnik na początek tablicy. Jest to ok do czasu kiedy nie chciałbyś zwolnić, gubisz wskaźnik na tą pamięć. Jeśli używasz operatora new to tak za alokowana pamięć musi zostać zwolniona za pomocą operatora delete. Jeśli tego nie zrobisz masz tak zwany wyciek pamięci.

komentarz 15 marca 2020 przez Daaa22 Dyskutant (8,250 p.)
A w środku funkcji nie można napisać "delete [] tab"?
komentarz 15 marca 2020 przez profesorek96 Szeryf (91,400 p.)
Mnożna napisać czemu by nie. Czemu chcesz tak zrobić ?

Podobne pytania

0 głosów
1 odpowiedź 750 wizyt
pytanie zadane 15 grudnia 2018 w C i C++ przez niezalogowany
0 głosów
3 odpowiedzi 2,039 wizyt
pytanie zadane 31 grudnia 2019 w C i C++ przez Mavimix Dyskutant (8,420 p.)
+1 głos
0 odpowiedzi 665 wizyt
pytanie zadane 2 czerwca 2021 w C i C++ przez Mavimix Dyskutant (8,420 p.)

93,424 zapytań

142,421 odpowiedzi

322,646 komentarzy

62,785 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

VMware Cloud PRO - przenieś swoją infrastrukturę IT do chmury
...