C kopiowanie elementów z listy do listy

0

Witam,
Mam problem z kopiowaniem elementów z listy jednokierunkowej . Chcę dodać z pierwszej listy do drugiej listy liczby podzielne przez 3, po odpaleniu program nie działa.

typedef struct Baza
{
int liczba;
struct Baza *next;
}el;

typedef struct Baza2
{
int liczba_mod;
struct Baza2 *n;
}el2;

el *head = NULL;
el2 *pocz = NULL;

int main()
{
int i;
for(i=1;i<=10;i++)
dodaj(&head,i);

edytuj(&pocz);
wypisz();

}

int dodaj(el**head,int x)
{
el *tmp = malloc(sizeof(el));
tmp->liczba = x;
tmp->next=*head;
*head = tmp;
}

void edytuj(el2**pocz)
{
el *tmp = head;
el2 *wsk = malloc(sizeof(el2));

while( tmp != NULL)
{

    if( (tmp->liczba)%3==0 )
    {
        wsk->liczba_mod = tmp->liczba;
        wsk->n = *pocz;
        *pocz = wsk;
    }
    tmp=tmp->next;
}

}
void wypisz()
{
el2 *wsk = pocz;
while( wsk != NULL)
{
printf(" %d ",wsk->liczba_mod);
wsk=wsk->n;
}
}

0

Brak bibliotek, wynik operacji malloc powinien być rzutowany na odpowiedni typ.

0

Biblioteki <stdio.h> <stdlib.h> mam dołączone do pliku, a z tym rzutowaniem to na jaki typ?

0

Trzymając się twojego zapisu, powinno być:

void edytuj(el2**pocz)
 {
     el *tmp = head;

     while( tmp != NULL)
     {

         if( (tmp->liczba)%3==0 )
         {
	     el2 *wsk = (el2 *)malloc(sizeof(el2));
             wsk->liczba_mod = tmp->liczba;
             wsk->n = *pocz;
             *pocz = wsk;
         }
         tmp=tmp->next;
     }
 }

Radziłbym jednak przeprowadzić refaktoryzację tego kodu i przede wszystkim zwalniaj przydzieloną pamięć. Btw rzutowania malloca - masz przykład w powyższym kodzie.

0

Teraz działa, a czemu alokowanie ma być w pętli a jak jest przed to nie działa?

0

Bo chcesz utworzyć nową listę. Wcześniej utworzyłeś 1 obiekt tej listy i w pętli zmieniałeś jego wartość, kolejno na: 9 - 6 - 3. Tymczasem powinieneś za każdym razem, gdy znajdziesz element podzielny przez 3 na pierwszej liście, dodawać nowy element do drugiej listy (z tą wartością podzielna przez 3).

0

Mam jeszcze jedno pytanie bo widziałem funkcje do dodawanie w takiej postaci dodaj( el*&head ) a mi działa tyko jak jest dodaj(el**head) dlaczego ten pierwszy sposób nie działa?

0

Co to znaczy "nie działa"? Referencja do wskaźnika działa tak samo dobrze jak wskaźnik na wkaźnik. Może źle wywołujesz te funkcje?
Np.

 
void dodaj(el*&head,int x)
 {
     el *tmp = (el *)malloc(sizeof(el));
     tmp->liczba = x;
     tmp->next=head;
     head = tmp;
 }

(...)
//wywołanie
dodaj(head,i);
0

Pokazuje że jest błąd w tej linijce...

0

http://ideone.com/moZq6y
Z jakiego kompilatora korzystasz i w której wersji?

0

Z GNU GCC

 
#include <stdio.h>
#include <stdlib.h>

typedef struct Baza
{
    int liczba;
    struct Baza *next;
}el;

typedef struct Baza2
{
    int liczba_mod;
    struct Baza2 *n;
}el2;

el *head = NULL;
el2 *pocz = NULL;


int main()
{
    int i;
    for(i=1;i<=10;i++)
        dodaj(head,i);

    edytuj(&pocz);
    wypisz(pocz);
}

void dodaj( el*&head,int x )
 {
     el *tmp = (el *)malloc(sizeof(el));
     tmp->liczba = x;
     tmp->next=head;
     head = tmp;
 }

void edytuj(el2**pocz)
{
    el *tmp = head;


    while( tmp != NULL)
    {
        el2 *wsk = malloc(sizeof(el2));

        if( (tmp->liczba)%3==0 )
        {
            wsk->liczba_mod = tmp->liczba;
            wsk->n = *pocz;
            *pocz = wsk;
        }
        tmp=tmp->next;
    }
}
void wypisz(adres_pocz)
{
    el2 *wsk = adres_pocz;
    while( wsk != NULL)
    {
        printf(" %d ",wsk->liczba_mod);
        wsk=wsk->n;
    }
}
 
0

Po pierwsze brakuje ci deklaracji tych funkcji (albo wypchnij je przed maina). Po drugie nie masz nigdzie zdefiniowanego typu 'adres_pocz' - innymi słowy pomysliłeś argument z typem i w ogóle zapomniałeś o typie. Dodaj w końcu zwalnianie zaalokowanej pamięci.
http://ideone.com/TdP22o

0
typedef struct Baza
{
    int liczba;
    struct Baza *next;
}el;

Dlaczego nadajesz strukturze dwie zupełnie różne nazwy: Baza i el?
Będziesz to potem pamiętał, która to to samo co która?

  1. Tak pobieżnie przeglądając, widzę u ciebie malloc-i a nie widzę nigdzie free. Niedobrze.
0

To jak mam strukture:

 
typedef struct Baza
{
    int liczba;
    struct Baza *next;
}Baza;

To jak stworzyć dwie listy?

Baza *head = NULL;
Baza *pocz = NULL;
 

W ten sposób?

0

Tak.

0

A co to zwalniania pamięci, to mam zwalniać na końcu w funkcji main?
free(head) i free(pocz) tak?

1

Nie. Musisz iterować po liście i usuwać każdy element, na końcu usunąć głowę listy.

0

Pamięć zwalniam w tak:

 
    Baza *px = head;
    while(px!=NULL)
    {
        px=head->next;
        free(head);
        head=px;
    }
    head = NULL;

Teraz jest dobrze?

0

Wygląda ok.

0

Jest dobrze ale można trochę uprościć:

Baza *tmp;
while(head)
  {
   tmp=head;
   head=tmp->next;
   free(tmp);
  }
0

A jeszcze co do funkcji dodającej nowy element jak miałam dodaj(Baza*&head) to mi nie działało bo miałem rozszerzenie nazwy pliku z małej litery (main.c) a jak zmieniłem na dużą (main.C) to działa i się zastanawiam dlaczego tak jest?

0

Jak zmodyfikować tą funkcję aby usuwała z listy elementy podzielne przez 3 ?

void edit(Baza *&head)
{
    Baza *tmp = head;
    Baza *wsk;

        while(tmp!=NULL)
        {
            if(tmp->liczba%3 == 0)
            {
                wsk = tmp;
                tmp = tmp->next;
                free(wsk);
            }
                tmp=tmp->next;
        }
}
 
0

Trzeba całkiem przerobić.

0

To znaczy jak?

0

Potrzebujesz albo podwójnego wskaźnika:
Baza **tmp = &head;
Albo dwóch wskaźników:
Baza *tmp=head,*prev=0;
Aby po usunięciu podmienić wskaźnik next poprzedniego rekordu.

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