Przekazywanie listy do fukncji wiele razy.

Przekazywanie listy do fukncji wiele razy.
D0
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 11
0

Witam!

Mam taki problem otóź:
Mam stukturę:

Kopiuj
typedef struct dane_produktu{

        char nazwa[50];
        int kalorie;
        int w_raporcie; /*0-nie 1-tak*/
        struct dane_produktu *nast;

}dane_produktu;

i chcę ją przekazać parę razy przez fukcję

W main mam

Kopiuj
dane_produktu *lista;

Potem ją przekazuję do
f menu(); potem do
edytuj_baze_danych();
nowy_produkt();
dodaj(); i tam podpinam element do listy głownej

kiedy przekazywać (&lista) kiedy (lista) jak przechodzę przez parę funkcji?

Tu cały kod:
http://wklej.org/id/760424/

Za każdą pomoc z góry dziękuję.
Pozdrawiam

  • Rejestracja: dni
  • Ostatnio: dni
0

Tyle, że Ty do funkcji przekazujesz wskaźnik na wskaźnik. Wywal & w wywołaniu funkcji.

  • Rejestracja: dni
  • Ostatnio: dni
0
Kopiuj
void f(int* p);
int a = 5;
f(&a); //wyłuskujesz adres zmienne a i przekazujesz do funkcji
Kopiuj
void f(int* p);
int a = 5;
int* wsk = &a;
f(wsk); //przekazujesz wskaźnik zawierający adres.
KU
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 166
0

Lista po przekazaniu do funkcji nie "ginie" (o ile funkcja jej nie zdealokuje). Przekazując listę do funkcji przekazujesz tak naprawdę wskaźnik (na jej pierwszy element), zatem przy każdym przekazaniu zawartość listy nie jest w funkcji kopiowana (duplikowany jest jedynie wskaźnik). Nie wiem zbytnio w jaki sposób wywołujesz te funkcje, anie chce mi się analizować kodu, więc dam Ci przykład:

Kopiuj
void  first(int  *list)
{
	// tutaj `list' jest wskaźnikiem
}

void  second(int  *list)
{
	// tutaj też jest wskaźnikiem
}

Teraz, jeśli chcesz wywołać powyższe dwie funkcje na tym samym poziomie, robisz to w ten sposób:

Kopiuj
int   my_list[100];

first(my_list);
second(my_list);

Jeśli jedna funkcja wywołuje drugą i chcesz przekazać listę "w dół", to przesyłasz wskaźnik bez kombinowania:

Kopiuj
void  first(int  *list)
{
	// tu robimy coś z listą
}

void  second(int  *list)
{
	first(list);
}

// I wywołanie (np. w main())
int  main(void)
{
	int	my_list[100];

	second(my_list);
	// ...

Warto pamiętać, że przekazując wskaźnik między funkcjami przekazujesz jego wartość, a nie zmienną. Często potocznie mówi się o "przekazywaniu zmiennej", ale to tylko skrót myślowy.
Aby wyjaśnić to prościej... Zmienna jest jak kontener, pojemnik z naklejoną nazwą, który może przechowywać dane określonego typu. Zmienna wskaźnikowa także jest takim kontenerem, przechowującym informację gdzie można znaleźć dane, na które wskazuje. Przekazując listę do funkcji dajesz jej taki wskaźnik-kontener z wiadomością "tablica zaczyna się pod adresem X" (zwróć uwagę, że nie mówi ona jak pojemna jest ta tablica, ani ile elementów w niej ma nadane przez Ciebie wartości). Funkcja tworzy sobie własny pojemnik (w powyższych przykładach pojemnik ma naklejkę `list'), kopiuje przekazaną przez Ciebie wiadomość i tę kopię wrzuca do swojego pojemnika. Tablica, na którą wskazuje wiadomość nie jest kopiowana i dalej siedzi w tym samym miejscu w pamięci. W funkcji możesz wykorzystać wiadomość we wskaźniku do znalezienia tablicy i dostania się do jej zawartości.

D0
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 11
0

Dzięki. Już łapie powoli.
Ale mam problem.

Kopiuj
void edytuj_baze_danych(dane_produktu *lista){  
    int wybor_edycja;
    
    while(wybor_edycja!=9){
    ClrScr();
    printf("Wybierz operacje: \n");
    printf("1. Dodaj nowy produkt\n");
    printf("2. Edytuj produkt\n");
    printf("3. Usun produkt\n");
    printf("4. Wyswietl liste produktow\n");
    printf("9. Wroc\n");
  
    scanf("%d",&wybor_edycja);
    
    switch(wybor_edycja){
        case 1: nowy_produkt(&lista);
            break;
        case 2: edytuj_wybrany_produkt(&lista);
            break;
        case 3: usun_produkt(&lista);
            break;
        case 4: wyswietl_liste(lista);
            break;
        case 9: ;
            break;
        default:
            printf("Nie poprawny wybór!...");
        }
    }
}


void menu(dane_produktu *lista){
  
  int wybor;
  while(wybor!=9){
  
  ClrScr();
  printf("%s",lista->nazwa);/*Tu jest null  :/*/
 
  printf("1. Operacje na bazie danych \n");
  printf("2. Twoja dieta \n");
  printf("3. Kalkulator BMI\n");
  printf("4. Przelicznik wartosci kcal, J...\n");
  printf("5. Dobre rady\n\n");
  printf("9. KONIEC");
  
  
  scanf("%d",&wybor);
  
  switch(wybor){
        case 1: edytuj_baze_danych(lista);
            break;
        case 2: ;
            break;
        case 3: kalkulator_bmi();
            break;
        case 4: ;
            break;
        case 5: dobre_rady();
            break;
        case 9: ;
            break;
        default:
            printf("Nie poprawny wybór!...");
    }
  }
}

int main(int argc, char** argv) {
    
    dane_produktu *lista;
    lista==NULL;
    
    wczytaj_z_pliku_bin(&lista);
    menu(lista);
    zapisz_do_pliku_bin(lista);
    
/*tu lista jest null? czemu?*/    
    
    return (EXIT_SUCCESS);
}

Chyba gdzieś gubię wskaźnik na listę.
W funkcji void edytuj_baze_danych wykonuję operację dodania, edycji, itp.
Tam dając printf widzę głowę listy, ale w menu już lista jest null.
W main tak samo null (skoro w menu null).
Proszę o pomoc.

_13th_Dragon
  • Rejestracja: dni
  • Ostatnio: dni
0
Kopiuj
int main() // nie potrzebujesz parametrow
  {
   dane_produktu *lista;
   lista=NULL; // ma być inicjalizacja a nie porównanie

   wczytaj_z_pliku_bin(&lista); 
   menu(&lista); // tu tez musi być wskaźnik na wskaźnik bo lisa może się zmienić wewnątrz funkcji.
   zapisz_do_pliku_bin(lista);
 
   return 0;
  }
 
D0
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 11
0
Kopiuj
menu(&lista);

potem idzie do 

void menu(dane_produktu **lista){
edytuj_baze_danych(&lista);
}

potem idzie do

void edytuj_baze_danych(dane_produktu **lista){
nowy_produkt(&lista);

} 

potem idzie do

void nowy_produkt(dane_produktu **lista){
dodaj(lista,nowa);
}

a to funkcja dodaj

void dodaj(dane_produktu **lista, dane_produktu *nowa){
    
    nowa->nast=NULL;
 
     if((*lista)==NULL)
     {
        *lista = nowa;
     }
     else
     {
         dane_produktu* wsk = *lista;
         
         while(wsk->nast != NULL)
         {
                wsk = wsk->nast;
         }
         wsk->nast = nowa;
     }
}

Jak to przekazywać dalej poza menu?

_13th_Dragon
  • Rejestracja: dni
  • Ostatnio: dni
0
Kopiuj
void menu(dane_produktu **lista){
edytuj_baze_danych(lista); // lista już jest wskaźnikiem na wskaźnik
}

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.