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ć
|