Przekazywanie listy do fukncji wiele razy.

0

Witam!

Mam taki problem otóź:
Mam stukturę:

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

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

0

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

0
void f(int* p);
int a = 5;
f(&a); //wyłuskujesz adres zmienne a i przekazujesz do funkcji
void f(int* p);
int a = 5;
int* wsk = &a;
f(wsk); //przekazujesz wskaźnik zawierający adres.
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:

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:

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:

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.

0

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

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.

0
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;
  }
 
0
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?

0
void menu(dane_produktu **lista){
edytuj_baze_danych(lista); // lista już jest wskaźnikiem na wskaźnik
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1