misia - 2007-06-12 16:22:09

#include<stdio.h>
#include<conio.h> // do funkci getch() - zczytanie pojedynczego znaku z klawiatury
#include<stdlib.h>

struct nazwa
{
    int klucz;
    struct nazwa *next,*prev;
};

int main(){

  int i,n;
  struct nazwa *first,*last,*wsk,*tmp,*wsk2;
  first=(struct nazwa*)malloc(sizeof(struct nazwa));

        // zapełnienie listy

  tmp=first;
  tmp->prev=0;
  tmp->klucz=1;

  for(i=2;i<=10;i++){
      wsk=tmp;
      tmp->next=(struct nazwa*)malloc(sizeof(struct nazwa));
      tmp=tmp->next;
tmp->prev=wsk;
      tmp->klucz=i;
  }
 
  last=tmp;
  last->next=0;

         // wydruk listy
  tmp=first;
  printf("\nTablica ma postac\n ");
  printf("\n%d",tmp->klucz);
 
  for(i=0;i<10;i++){
      tmp=tmp->next;
      printf("\n%d",tmp->klucz);
      if(tmp->next==0){break;}
   }

       // wybor elementu do skasowania


  printf("\nPodaj element ktory skasowac ");
  scanf("%d",&n);


  if(n==1){ // jesli wybrany pierwszy
      wsk=first->next;
      wsk->prev=0;
      free(first);
      first=wsk;
  }

  else if(n==10){ // jesli ostatni
      wsk=last->prev;
      wsk->next=0;
      free(last);
      last=wsk;
  }
  else{ // jesli w srodku

      tmp=first;
      for(i=1;i<n;i++){ // dojscie do wybranego
          tmp=tmp->next;

          if(tmp->next==0){
printf("\nBlad ");
break;
}
}

      wsk=tmp->prev; // podmiana wskaznikow (za wybranym i przed wybranym)
      wsk2=tmp->next;
      wsk->next=wsk2;
      wsk2->prev=wsk;
      free(tmp);
 
  }


                          // wydruk po kasowaniu
  tmp=first;
  printf("\nTablica ma postac ");
  printf("\n%d",tmp->klucz);
  for(i=1;i=9;i++){
      tmp=tmp->next;
      printf("\n%d",tmp->klucz);
      if(tmp->next==0){break;}

  }

  tmp=first; // zwalnianie pamieci
  for(i=1;i=9;i++){
      wsk=tmp->next;
      free(tmp);
      if(wsk->next==0){break;}
      tmp=wsk;
  }

  free(wsk);

getch();
}

Kasia - 2007-06-12 16:29:51

jestes wielka :) gracias :*

Grunia - 2007-06-12 17:16:35

Dziękuje. Uratowałaś nas!

Kasia - 2007-06-13 15:14:22

PROGRAM KTORY USUWA I DODAJE :)


#include<stdio.h>
#include<conio.h> // do funkci getch() - zczytanie pojedynczego znaku z klawiatury
#include<stdlib.h>

struct nazwa
{
    int klucz;
    struct nazwa *next,*prev;
};

int main(){

    int i,n,co;
    struct nazwa *first,*last,*wsk,*tmp,*wsk2;
    first=(struct nazwa*)malloc(sizeof(struct nazwa));

    // zapełnienie listy

    tmp=first;
    tmp->prev=0;
    tmp->klucz=1;

    for(i=2;i<=10;i++)
    {
        wsk=tmp;
        tmp->next=(struct nazwa*)malloc(sizeof(struct nazwa));
        tmp=tmp->next;
        tmp->prev=wsk;
        tmp->klucz=i;
    }

    last=tmp;
    last->next=0;

    // wydruk listy
    tmp=first;
    printf("\nTablica ma postac\n ");
    printf("\n%d",tmp->klucz);

    for(i=0;i<10;i++){
        tmp=tmp->next;
        printf("\n%d",tmp->klucz);
        if(tmp->next==0) break;
    }

    // wybor elementu do skasowania


    printf("\nPodaj element ktory skasowac (0 - nic nie kasuj) ");
    scanf("%d",&n);


    if(n==1)    // jesli wybrany pierwszy
    {
        wsk=first->next;
        wsk->prev=0;
        free(first);
        first=wsk;
    }

    else if(n==10)    // jesli ostatni
    {
        wsk=last->prev;
        wsk->next=0;
        free(last);
        last=wsk;
    }
   
    else if (n!=0)    // jesli w srodku
    {
        tmp=first;
        for(i=1;i<n;i++)    // dojscie do wybranego
        {
            tmp=tmp->next;
            if(tmp->next==0)
            {
                printf("\nBlad ");
                getch();
                exit(0);
            }
        }

    wsk=tmp->prev; // podmiana wskaznikow (za wybranym i przed wybranym)
    wsk2=tmp->next;
    wsk->next=wsk2;
    wsk2->prev=wsk;
    free(tmp);

    }

    else;    // jesli nic nie chcemy skasowac

    // gdzie dodac?

    printf("\nPodaj jaka liczbe chcesz dodac ");
    scanf("%d", &co);

    printf("\nPodaj na ktorym miejscu chcesz dodac (0 - nigdzie nie dodawaj) ");
    scanf("%d",&n);


    if(n==1)    // jesli na poczatku
    {
        wsk=(struct nazwa*)malloc(sizeof(struct nazwa));
        first->prev=wsk;
        wsk->next=first;
        wsk->prev=0;
        wsk->klucz=co;
        first=wsk;
    }

    else if(n==10)    // jesli na koncu
    {
        wsk=(struct nazwa*)malloc(sizeof(struct nazwa));
        last->next=wsk;
        wsk->prev=last;
        wsk->next=0;
        wsk->klucz=co;
        last=wsk;
    }
   
    else if(n!=0)    // w wybrane miejsce
    {
        tmp=first;
        for(i=1;i<n;i++)    // dojscie do wybranego miejsca
        {
            tmp=tmp->next;
            if(tmp->next==0)
            {
                printf("\nBlad ");
                getch();
                exit(0);
            }
        }

   
        wsk=(struct nazwa*)malloc(sizeof(struct nazwa));    //wcisniecie nowego w wybrane miejsce
        tmp->prev->next=wsk;
        wsk->next=tmp;
        wsk->prev=tmp->prev;
        tmp->prev=wsk;
        wsk->klucz=co;
    }

    else;    //jesli nic nie dodajemy


    // wydruk po kasowaniu
    tmp=first;
    printf("\nTablica ma postac ");
    printf("\n%d",tmp->klucz);

    for(i=1;i=9;i++)
    {
    tmp=tmp->next;
    printf("\n%d",tmp->klucz);
    if(tmp->next==0){break;}
    }

    tmp=first; // zwalnianie pamieci

    for(i=1;i=9;i++)
    {
        wsk=tmp->next;
        free(tmp);
        if(wsk->next==0){break;}
        tmp=wsk;
    }

    free(wsk);

    getch();
}


*edit by Tomek :) (Podziękować ładnie!)

Pap - 2007-06-13 15:31:26

dziekowac :)

Kinia - 2007-06-13 15:32:45

..Ładnie ! :)

Mlody - 2007-06-13 17:06:53

Te else'y, co nic się po nich nie dzieje (samo ";") i które skomentowane są jako "nic nie usuwaj/dodawaj" są zbędne jakby o to pytał. Wrzuciłem je tylko po to, żeby zaakcentować, że tam wykonuje się ta opcja (czyli nic się nie dzieje).

A jeśli chodzi o  "// zwalnianie pamieci" obok tmp=first, to powinno raczej być przy tym ostatnim forze i free(wsk), bo tmp=first to powrót do pierwszego elementu a nie zwalnianie pamięci. Pamięć zwalniamy tam, gdzie jest free. Nie wiem skąd to się tam wzięło, chyba zapomniałem tego zmienić jak przerabiałem program.

I jeszcze kilka tipsów:
1. jeśli po pętli, albo instrukcji warunkowej wykonujemy tylko jedną czynność, to nie trzeba stosować klamer, czyli:
można tak:
if (x==y)
{
break
}
ale można też tak:
if (x==y) break;
i to jest to samo.
Ale już np. nie można dać:
if (x==y) x=1; y=2;
tylko trzeba:
if (x==y)
{
x=1;
y=2;
}
Znaczy się pierwszy zapis też jest poprawny, ale są to dwie różne instrukcje, bo w drugim przypadku liczby zostaną przypisane do zmiennych pod jakimś warunkiem, a w pierwszym przypadku tylko do x przypisujemy pod warunkiem, a przypisanie do y wykona się zawsze.
2. = jest operatorem przypisania, a == jest operatorem porównania.
3. & jest operatorem pobrania adresu.
4. Język C/C++ nie zwraca uwagi na liczbę białych znaków (spacji i znaków nowej linii, czyli enterów). Cały kod można równie dobrze napisać w jednej linijce. Stąd też czasem widzimy zapis:
if (x==y){break};
a czasem:
if (x==y)
{
break
}
Dla kompilatora nie ma róznicy. Jest to tylko kosmetyka ułatwiająca czytelność.
5. break to wyjście z pętli.
6. To (struct nazwa*) przed mallociem, to o ile pamiętam operator rzutowania.
7. != to "różne od".
8. \n oznacza przejście do nowej linii.

O niektóre te rzeczy może zapytać, niektóre można mu powiedzieć, żeby się przed nim zalansić. Może dzięki temu nie będzie tak cisnął ;)

G'luck

misia - 2007-06-13 18:49:19

Dziekujemy bardzo:*

Pap - 2007-06-13 20:01:42

a moglby ktos zrobic z menu? bo nasz many tak chcial. ma byc menu wyboru: czy dodaj czy odjac czy wyjsc
:)

Mlody - 2007-06-13 21:15:46

Nie mam już niestety czasu, ale to jest pewnie na 5. Mogę tylko podać sposób.

//Tworzymy nową zmienną typu int, np. wybor.

//robimy menu:
printf("1. Usuwanie\n2.Dodawanie\n3.Wyjscie\nTwoj wybor: ");
scanf("%d",wybor);
//i teraz jest cos takiego jak switch()
switch(wybor)
{
case 1:
//wklejamy tu kod odpowiedzialny za usuwanie
break; //break MUSI byc
case 2:
//wklajamy tu kod odpowiedzialny za dodawanie
break; //pamietac o breaku!
case 3:
exit(0);
}


Kod od kasowania jest od
// wybor elementu do skasowania
do
else;    // jesli nic nie chcemy skasowac
włącznie.

Od dodawania:
od   // gdzie dodac? do else;    //jesli nic nie dodajemy włącznie.

Po switchu dajemy resztę, czyli od     // wydruk po kasowaniu do końca.
Menu robimy zaraz po drugim forze, przed        // wybor elementu do skasowania.

Więcej na temat switcha:
Tutaj

Jak ktoś boi się switcha, to można normalnie ifami. Menu normalnie, a potem:
if (wybor == 1)
{
//kod usuwania
}
if (wybor == 2)
{
//kod dodawania
}
if (wybor == 3) exit(0);

EDIT: DODANE MENU
Zrobione na szybkiego. Nie wiem nawet czy działa:

EDIT2:
Poprawiona wersja, działająca, dodane do while, dzięki któremu program nie kończy się po pierwszym dodaniu tylko można dodawać i usuwać aż się nie wyjdzie.

#include<stdio.h>
#include<conio.h> // do funkci getch() - zczytanie pojedynczego znaku z klawiatury
#include<stdlib.h>

struct nazwa
{
    int klucz;
    struct nazwa *next,*prev;
};

int main(){

    int i,n,co, wybor;
    struct nazwa *first,*last,*wsk,*tmp,*wsk2;
    first=(struct nazwa*)malloc(sizeof(struct nazwa));

    // zapełnienie listy

    tmp=first;
    tmp->prev=0;
    tmp->klucz=1;

    for(i=2;i<=10;i++)
    {
        wsk=tmp;
        tmp->next=(struct nazwa*)malloc(sizeof(struct nazwa));
        tmp=tmp->next;
        tmp->prev=wsk;
        tmp->klucz=i;
    }

    last=tmp;
    last->next=0;

    // wydruk listy
    tmp=first;
    printf("\nTablica ma postac\n ");
    printf("\n%d",tmp->klucz);

    for(i=0;i<10;i++){
        tmp=tmp->next;
        printf("\n%d",tmp->klucz);
        if(tmp->next==0) break;
    }

    do
    {

    printf("\n\n\n1.Usuwanie\n2.Dodawanie\n3.Wyjscie\nTwoj wybor: ");
    scanf("%d",&wybor);

    switch(wybor)
    {

    case 1:

    // wybor elementu do skasowania


    printf("\nPodaj element ktory skasowac (0 - nic nie kasuj) ");
    scanf("%d",&n);


    if(n==1)    // jesli wybrany pierwszy
    {
        wsk=first->next;
        wsk->prev=0;
        free(first);
        first=wsk;
    }

    else if(n==10)    // jesli ostatni
    {
        wsk=last->prev;
        wsk->next=0;
        free(last);
        last=wsk;
    }
   
    else if (n!=0)    // jesli w srodku
    {
        tmp=first;
        for(i=1;i<n;i++)    // dojscie do wybranego
        {
            tmp=tmp->next;
            if(tmp->next==0)
            {
                printf("\nBlad ");
                getch();
                exit(0);
            }
        }

    wsk=tmp->prev; // podmiana wskaznikow (za wybranym i przed wybranym)
    wsk2=tmp->next;
    wsk->next=wsk2;
    wsk2->prev=wsk;
    free(tmp);

    }

    else;    // jesli nic nie chcemy skasowac

    break;

    case 2:
   
    break;

   
    // gdzie dodac?

    printf("\nPodaj jaka liczbe chcesz dodac ");
    scanf("%d", &co);

    printf("\nPodaj na ktorym miejscu chcesz dodac (0 - nigdzie nie dodawaj) ");
    scanf("%d",&n);


    if(n==1)    // jesli na poczatku
    {
        wsk=(struct nazwa*)malloc(sizeof(struct nazwa));
        first->prev=wsk;
        wsk->next=first;
        wsk->prev=0;
        wsk->klucz=co;
        first=wsk;
    }

    else if(n==10)    // jesli na koncu
    {
        wsk=(struct nazwa*)malloc(sizeof(struct nazwa));
        last->next=wsk;
        wsk->prev=last;
        wsk->next=0;
        wsk->klucz=co;
        last=wsk;
    }
   
    else if(n!=0)    // w wybrane miejsce
    {
        tmp=first;
        for(i=1;i<n;i++)    // dojscie do wybranego miejsca
        {
            tmp=tmp->next;
            if(tmp->next==0)
            {
                printf("\nBlad ");
                getch();
                exit(0);
            }
        }

   
        wsk=(struct nazwa*)malloc(sizeof(struct nazwa));    //wcisniecie nowego w wybrane miejsce
        tmp->prev->next=wsk;
        wsk->next=tmp;
        wsk->prev=tmp->prev;
        tmp->prev=wsk;
        wsk->klucz=co;
    }

    else;    //jesli nic nie dodajemy

    break;
    }


    // wydruk po kasowaniu
    tmp=first;
    printf("\nTablica ma postac ");
    printf("\n%d",tmp->klucz);

    for(i=1;i=9;i++)
    {
    tmp=tmp->next;
    printf("\n%d",tmp->klucz);
    if(tmp->next==0){break;}
    }

    }
    while(wybor!=3);

    tmp=first; // zwalnianie pamieci

    for(i=1;i=9;i++)
    {
        wsk=tmp->next;
        free(tmp);
        if(wsk->next==0){break;}
        tmp=wsk;
    }

    free(wsk);

    getch();
}

EDIT3: Jak działa do while.

do while oznacza rób, dopóki. To jest tak

do
{
//program wykona tę operację
}
while(warunek) //jeśli warunek spełniony, pętla wykona się jeszcze raz, jeśli nie, koniec pętli.

Jest też samo while

while(warunek)
{
//program wykona tę operację
}

Jaka jest różnica? W przypadku while'a, program najpierw sprawdza warunek. Jeśli już na początku nie będzie spełniony, to pętla może się ani razu nie wykonać. W przypadku do while, pętla wykona się CO NAJMNIEJ RAZ, bo najpierw wykonywane są operacje, a potem sprawdzany warunek, czy wykonać jeszcze raz.

EDIT4: Jak Kasia słusznie zauważyła (brawo), tam w tych forach gdzie jest i=9, powinno być i<=9. Nie zauważyłem tego, bo błąd jest tak fartowny, że nie wpływa na poprawność działania programu. Jest to jednak niepoprane.

EDIT5 (mam nadzieję ostatni): Kolejna dobra uwaga debuggera Kasi. Zmażcie "break;" po "case 2:". Teraz już mam nadzieję, że wpełni działa, a ja idę spać, bo i tak już się nic nie nauczę hehe.

EDIT6: Z menu jest jednak więcej jebania, bo wtedy można dodawać i dodawać i zwiększa się liczba elementów więc 10 już nie będzie ostatnim. Jak ktoś załapał o co chodzi, może przerobić, reszta niech lepiej odda bez menu. Albo taki kompromis: usuwamy to do while i dodajemy case 3: exit(0);

Kasia - 2007-06-13 22:07:31

:) mam dzisiaj dobry dzien :D wyłapuje wszystkie błędy i mowie madre rzeczy. lol

Pap - 2007-06-14 00:06:57

mama pare pytan:
czemu po case 2 ma nie byc brake? o ile pamietam braka robi sie po kazdy case z "menu"?
i jesli dobrze pamietam to przy trzech opcjach menu nie robi sie ostatniego jako case 3 tylko jako else

wojti - 2007-06-14 05:31:44

Pap chodzi o to ze wkradl sie maly blad i w drugiej linijce po case 2 jest break a powinien byc na koncu tzn jak sie konczy kod odpowiedzialny ze wstawianie elementu.

Mlody - 2007-06-14 05:57:12

Pap napisał:

mama pare pytan:
przy trzech opcjach menu nie robi sie ostatniego jako case 3 tylko jako else

Nie ma takiej zasady, chyba że jest to jego własne widzimisie. A tak w ogóle to w switchu chyba nie ma else, tylko jest default. Można zrobić po case 3: jeszcze default: printf("\nZly wybor, wybierz ponownie");

moo-moo - 2007-06-14 08:36:18

duże podziękowania :)

Soli - 2007-06-14 09:30:52

tez macie problem z biblioteka conio ? bo mi jej nie widzi kompilator ;p

moo-moo - 2007-06-14 10:14:12

Soli napisał:

tez macie problem z biblioteka conio ? bo mi jej nie widzi kompilator ;p

skasuj conio i wszystkie trzy getch() :)
i będzie działać

wczasy w Kopalinie Kredyt pozabankowy www.gabinety-stomatologiczne.info.pl