Prethodna tema :: Sljedeća tema |
Autor/ica |
Poruka |
matmih Forumaš(ica)
Pridružen/a: 07. 12. 2006. (22:57:42) Postovi: (1A4)16
Spol:
Lokacija: {Zg, De , Ri}
|
|
[Vrh] |
|
mdoko Forumaš(ica)
Pridružen/a: 30. 11. 2002. (22:17:12) Postovi: (71A)16
Spol:
Lokacija: Heriot-Watt University, Edinburgh
|
Postano: 14:46 čet, 28. 6. 2007 Naslov: |
|
|
[quote="MKova"]
[tt]char* s2;
s2 = (char*) malloc ( (m + 1) * sizeof (char) );[/tt]
nikako mi nije jasno što radi ovaj cast u char* poslije malloca. Čemu to? Nije za aritmetiku (tipa s2+1), jer smo za s2 već u deklaraciji rekli da je pointer na char. s2 sadrži adresu i malloc vraća adresu kao brojeve, što cast u char* točno radi tim brojevima?[/quote]
Funkcija [tt]malloc[/tt] ima ovakav prototip: [tt]void* malloc(size_t size);[/tt]
Dakle, malloc vraca [tt]void*[/tt] koji se u C-u implicitno konvertitra u bilo koji pointerski tip. [size=4](u C++u ne, ali to sad nije bitno)[/size] Dakle, nije nuzno castati povratnu vrijednost [tt]malloc[/tt]a, ali je to dobra navika zato sto osim lakse citljivosti koda pridonosi i laksem otkrivanju mogucih gresaka.
Na primjer, ako imas jako velik program u kojem imas pointer [tt]long double* podaci;[/tt], te u jednom trenutku trebas napraviti realokaciju pointera [tt]podaci[/tt], ali zaboravis da si ga deklarirao kao [tt]long double[/tt] i napravis nesto ovakvo:
[code:1]podaci = realloc(podaci, new_size * sizeof(double));[/code:1]
Ovo je jako lose iz razloga sto smo alocirali onoliko memorije koliko nam treba za [tt]new_size[/tt] varijabli tipa [tt]double[/tt], a nasi podaci su tipa [tt]long double[/tt]. Ovakva greska se jako tesko pronalazi, jer te kompajler nece upozoriti da si nesto cudno napisao.
S druge strane, ako imas naviku castanja povratnih vrijednosti funkcija za alokaciju memorije, onda ces u slucaju da se prevaris (pomislis da su podaci koje cuvas u polju [tt]podaci[/tt] tipa [tt]double[/tt]) i napises
[code:1]podaci = (double*) realloc(podaci, new_size * sizeof(double));[/code:1]
prilikom kompajliranja dobiti poruku od strane kompajlera koja ce izgledati nekeko ovako:
[code:1]warning: assignment from incompatible pointer type[/code:1]
I u ovom slucaju kompajliranje prolazi, ali ces barem biti upozoren od strane kompajlera da je izvrsena konverzija nekompatibilnih pointerskih tipova (u ovom slucaju iz [tt]double*[/tt] u [tt]long double*[/tt]), pa ces pogledati na kojoj se liniji takvo nesto nalazi i lagano ces otkloniti potencijalni problem.
Nadam se da je sad jasnije cemu sluzi onaj cast-operator ispred poziva funkcije [tt]malloc[/tt].
MKova (napisa): |
char* s2;
s2 = (char*) malloc ( (m + 1) * sizeof (char) );
nikako mi nije jasno što radi ovaj cast u char* poslije malloca. Čemu to? Nije za aritmetiku (tipa s2+1), jer smo za s2 već u deklaraciji rekli da je pointer na char. s2 sadrži adresu i malloc vraća adresu kao brojeve, što cast u char* točno radi tim brojevima? |
Funkcija malloc ima ovakav prototip: void* malloc(size_t size);
Dakle, malloc vraca void* koji se u C-u implicitno konvertitra u bilo koji pointerski tip. (u C++u ne, ali to sad nije bitno) Dakle, nije nuzno castati povratnu vrijednost malloca, ali je to dobra navika zato sto osim lakse citljivosti koda pridonosi i laksem otkrivanju mogucih gresaka.
Na primjer, ako imas jako velik program u kojem imas pointer long double* podaci;, te u jednom trenutku trebas napraviti realokaciju pointera podaci, ali zaboravis da si ga deklarirao kao long double i napravis nesto ovakvo:
Kod: | podaci = realloc(podaci, new_size * sizeof(double)); |
Ovo je jako lose iz razloga sto smo alocirali onoliko memorije koliko nam treba za new_size varijabli tipa double, a nasi podaci su tipa long double. Ovakva greska se jako tesko pronalazi, jer te kompajler nece upozoriti da si nesto cudno napisao.
S druge strane, ako imas naviku castanja povratnih vrijednosti funkcija za alokaciju memorije, onda ces u slucaju da se prevaris (pomislis da su podaci koje cuvas u polju podaci tipa double) i napises
Kod: | podaci = (double*) realloc(podaci, new_size * sizeof(double)); |
prilikom kompajliranja dobiti poruku od strane kompajlera koja ce izgledati nekeko ovako:
Kod: | warning: assignment from incompatible pointer type |
I u ovom slucaju kompajliranje prolazi, ali ces barem biti upozoren od strane kompajlera da je izvrsena konverzija nekompatibilnih pointerskih tipova (u ovom slucaju iz double* u long double*), pa ces pogledati na kojoj se liniji takvo nesto nalazi i lagano ces otkloniti potencijalni problem.
Nadam se da je sad jasnije cemu sluzi onaj cast-operator ispred poziva funkcije malloc.
_________________ Extraordinary claims require extraordinary evidence. – Carl Sagan
|
|
[Vrh] |
|
mdoko Forumaš(ica)
Pridružen/a: 30. 11. 2002. (22:17:12) Postovi: (71A)16
Spol:
Lokacija: Heriot-Watt University, Edinburgh
|
|
[Vrh] |
|
anekalo Forumaš(ica)
Pridružen/a: 05. 03. 2007. (16:48:54) Postovi: (55)16
|
|
[Vrh] |
|
vsego Site Admin
Pridružen/a: 06. 10. 2002. (22:07:09) Postovi: (3560)16
Spol:
Lokacija: /sbin/init
|
|
[Vrh] |
|
Luuka Forumaš(ica)
Pridružen/a: 13. 02. 2007. (20:34:54) Postovi: (925)16
Spol:
Lokacija: Hakuna Matata
|
Postano: 18:13 čet, 28. 6. 2007 Naslov: |
|
|
Hej ljudi molio bih pomoć...ne znam zašto, al program mi ne radi...čini mi se da uopće ne upisuje klubove u strukturu...napravio sam datoteku rezultati.txt i unutra upisao što treba...program napravi datoteku tablica koja je prazna...ovo je program 9.10 sa modifikacijama (dodana gol razlika i bubble sort...) evo koda:
[code:1]#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
char ime[51];
int bod,gr,ut;
} tim;
int indexkluba(char ime[],tim klub[],int *n)
{
int i;
for (i=0;i<*n;i++)
if ( !(strcmp(ime,klub[i].ime) )) {klub[i].ut++;return i;}
strcpy(klub[i].ime,ime);
klub[i].gr=0;
klub[i].bod=0;
klub[i].ut=1;
(*n)++;
return i;
}
int main ()
{
FILE *rez,*tab;
tim klub[20];
int n=0,g1,g2,i1,i2,nered=1,zadnji,i;
char ime1[51],ime2[51];
if ( ( rez=fopen("rezultati.txt","rt"))==NULL)
{ printf("Greska!!");
exit(1);
}
if ( ( tab=fopen("tablica.txt","wt"))==NULL)
{ fclose(rez);
printf("greska");
exit(1);
}
while (fscanf(rez,"%[^:]:%[^=]=%d:%d ",ime1,ime2,&g1,&g2)==4)
{
i1=indexkluba(ime1,klub,&n);
i2=indexkluba(ime2,klub,&n);
klub[i1].gr=klub[i1].gr+g1-g2;
klub[i2].gr=klub[i2].gr+g2-g1;
if (g2>g1) klub[i2].bod+=3;
if (g2<g1) klub[i1].bod+=3;
if (g2==g1) {klub[i2].bod++;klub[i1].bod++;}
}
fclose(rez);
zadnji=n;
while (nered)
{ nered=0;
for (i=0;i<zadnji;i++)
if ( klub[i].bod<klub[i+1].bod) {
tim pom=klub[i];
klub[i]=klub[i+1];
klub[i+1]=pom;
nered=1;
}
zadnji--;
}
fprintf(tab," [ime kluba] broj utakmica gol razlika broj bodova \n\n");
for (i=0;i<n;i++)
fprintf(tab,"%d. [ %10s ]%10d%10d%15d \n",i+1,klub[i].ime,klub[i].ut,klub[i].gr,klub[i].bod);
fclose(tab);
system ("PAUSE");
return 0;
}[/code:1]
EDIT greška na?ena, u fji indexkluba treba ic'i (*n)++ a ja stavio bez zagrada...uf mrzim takve greške...
EDIT2 sad je popravljeno skroz (bila je još mala greškica kod rac(unanja gol razlike) Sad skroz radi
EDIT3 Sad je još ljepše...ima i broj utakmica i malo ljepši ispis...
Hej ljudi molio bih pomoć...ne znam zašto, al program mi ne radi...čini mi se da uopće ne upisuje klubove u strukturu...napravio sam datoteku rezultati.txt i unutra upisao što treba...program napravi datoteku tablica koja je prazna...ovo je program 9.10 sa modifikacijama (dodana gol razlika i bubble sort...) evo koda:
Kod: | #include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
char ime[51];
int bod,gr,ut;
} tim;
int indexkluba(char ime[],tim klub[],int *n)
{
int i;
for (i=0;i<*n;i++)
if ( !(strcmp(ime,klub[i].ime) )) {klub[i].ut++;return i;}
strcpy(klub[i].ime,ime);
klub[i].gr=0;
klub[i].bod=0;
klub[i].ut=1;
(*n)++;
return i;
}
int main ()
{
FILE *rez,*tab;
tim klub[20];
int n=0,g1,g2,i1,i2,nered=1,zadnji,i;
char ime1[51],ime2[51];
if ( ( rez=fopen("rezultati.txt","rt"))==NULL)
{ printf("Greska!!");
exit(1);
}
if ( ( tab=fopen("tablica.txt","wt"))==NULL)
{ fclose(rez);
printf("greska");
exit(1);
}
while (fscanf(rez,"%[^:]:%[^=]=%d:%d ",ime1,ime2,&g1,&g2)==4)
{
i1=indexkluba(ime1,klub,&n);
i2=indexkluba(ime2,klub,&n);
klub[i1].gr=klub[i1].gr+g1-g2;
klub[i2].gr=klub[i2].gr+g2-g1;
if (g2>g1) klub[i2].bod+=3;
if (g2<g1) klub[i1].bod+=3;
if (g2==g1) {klub[i2].bod++;klub[i1].bod++;}
}
fclose(rez);
zadnji=n;
while (nered)
{ nered=0;
for (i=0;i<zadnji;i++)
if ( klub[i].bod<klub[i+1].bod) {
tim pom=klub[i];
klub[i]=klub[i+1];
klub[i+1]=pom;
nered=1;
}
zadnji--;
}
fprintf(tab," [ime kluba] broj utakmica gol razlika broj bodova \n\n");
for (i=0;i<n;i++)
fprintf(tab,"%d. [ %10s ]%10d%10d%15d \n",i+1,klub[i].ime,klub[i].ut,klub[i].gr,klub[i].bod);
fclose(tab);
system ("PAUSE");
return 0;
} |
EDIT greška na?ena, u fji indexkluba treba ic'i (*n)++ a ja stavio bez zagrada...uf mrzim takve greške...
EDIT2 sad je popravljeno skroz (bila je još mala greškica kod rac(unanja gol razlike) Sad skroz radi
EDIT3 Sad je još ljepše...ima i broj utakmica i malo ljepši ispis...
_________________ "Bolje bi prolazio na faxu da sam na drogama nego na netu" - by a friend of mine
"Poslije spavanja doma spavanje bilo di mi je najdraža stvar" - by the same guy
Zadnja promjena: Luuka; 19:29 čet, 28. 6. 2007; ukupno mijenjano 1 put.
|
|
[Vrh] |
|
Luuka Forumaš(ica)
Pridružen/a: 13. 02. 2007. (20:34:54) Postovi: (925)16
Spol:
Lokacija: Hakuna Matata
|
Postano: 19:19 čet, 28. 6. 2007 Naslov: |
|
|
Još jedan question...kako da napravim da mi ispis u stvorenoj datoteci bude lijepo poravnat? Da budu lijepe kolone? Probao sam sa
[code:1]fprintf(tab,"%d. [ %15s ]%10d%10d \n",i+1,klub[i].ime,klub[i].gr,klub[i].bod);[/code:1]
ali s tim mi nije centrirano ime kluba...jel se to može cetrirat uopće? ili se moram igrat sa svakim imenom da ispred stringa stavljam razmake,pa iza razmake,ovisno koliko treba da se centrira pa ispis sa %s? imaa li nek lakši i brži način?
Još jedan question...kako da napravim da mi ispis u stvorenoj datoteci bude lijepo poravnat? Da budu lijepe kolone? Probao sam sa
Kod: | fprintf(tab,"%d. [ %15s ]%10d%10d \n",i+1,klub[i].ime,klub[i].gr,klub[i].bod); |
ali s tim mi nije centrirano ime kluba...jel se to može cetrirat uopće? ili se moram igrat sa svakim imenom da ispred stringa stavljam razmake,pa iza razmake,ovisno koliko treba da se centrira pa ispis sa %s? imaa li nek lakši i brži način?
_________________ "Bolje bi prolazio na faxu da sam na drogama nego na netu" - by a friend of mine
"Poslije spavanja doma spavanje bilo di mi je najdraža stvar" - by the same guy
|
|
[Vrh] |
|
arya Forumaš(ica)
Pridružen/a: 30. 11. 2006. (20:10:37) Postovi: (233)16
Spol:
Lokacija: forum
|
Postano: 20:52 čet, 28. 6. 2007 Naslov: |
|
|
sorry na offtopicu, al luuka, daj uči za kolokvij, imat ćeš vremena za ovo nakon toga ;) mislim, znam da ti je ovo daleko zanimljivije, ali što ćeš :D
sorry na offtopicu, al luuka, daj uči za kolokvij, imat ćeš vremena za ovo nakon toga mislim, znam da ti je ovo daleko zanimljivije, ali što ćeš
_________________ kalendar
|
|
[Vrh] |
|
vsego Site Admin
Pridružen/a: 06. 10. 2002. (22:07:09) Postovi: (3560)16
Spol:
Lokacija: /sbin/init
|
Postano: 20:53 čet, 28. 6. 2007 Naslov: |
|
|
Imas i gresku u sortu:
[tt]for (i=0; i<[color=red]zadnji[/color]; i++)[/tt]
(pristupas elementu [tt]klub[i+1][/tt])
[quote="Luuka"]Još jedan question...kako da napravim da mi ispis u stvorenoj datoteci bude lijepo poravnat? Da budu lijepe kolone? Probao sam sa
[code:1]fprintf(tab,"%d. [ %15s ]%10d%10d \n",i+1,klub[i].ime,klub[i].gr,klub[i].bod);[/code:1]
ali s tim mi nije centrirano ime kluba...jel se to može cetrirat uopće? ili se moram igrat sa svakim imenom da ispred stringa stavljam razmake,pa iza razmake,ovisno koliko treba da se centrira pa ispis sa %s? imaa li nek lakši i brži način?[/quote]
Moze se i to; evo ti jedan mali demo (sve koristeno bi vam trebalo biti poznato):
[code:1]#include<stdio.h>
int main(){
int i, j, n;
char s[20];
srand(time());
for (i = 0; i < 10; i++) {
n = rand() % 20;
for (j = 0; j < n; j++) s[j] = '*';
s[n] = '\0';
printf("|%*s%*s|\n", 10 + n/2, s, 10 - n/2, "");
}
return 0;
}[/code:1]
8)
Imas i gresku u sortu:
for (i=0; i<zadnji; i++)
(pristupas elementu klub[i+1])
Luuka (napisa): | Još jedan question...kako da napravim da mi ispis u stvorenoj datoteci bude lijepo poravnat? Da budu lijepe kolone? Probao sam sa
Kod: | fprintf(tab,"%d. [ %15s ]%10d%10d \n",i+1,klub[i].ime,klub[i].gr,klub[i].bod); |
ali s tim mi nije centrirano ime kluba...jel se to može cetrirat uopće? ili se moram igrat sa svakim imenom da ispred stringa stavljam razmake,pa iza razmake,ovisno koliko treba da se centrira pa ispis sa %s? imaa li nek lakši i brži način? |
Moze se i to; evo ti jedan mali demo (sve koristeno bi vam trebalo biti poznato):
Kod: | #include<stdio.h>
int main(){
int i, j, n;
char s[20];
srand(time());
for (i = 0; i < 10; i++) {
n = rand() % 20;
for (j = 0; j < n; j++) s[j] = '*';
s[n] = '\0';
printf("|%*s%*s|\n", 10 + n/2, s, 10 - n/2, "");
}
return 0;
} |
_________________ U pravilu ignoriram pitanja u krivim topicima i kodove koji nisu u [code]...[/code] blokovima.
Takodjer, OBJASNITE sto vas muci! "Sto mi je krivo?", bez opisa u cemu je problem, rijetko ce zadobiti moju paznju.
|
|
[Vrh] |
|
Luuka Forumaš(ica)
Pridružen/a: 13. 02. 2007. (20:34:54) Postovi: (925)16
Spol:
Lokacija: Hakuna Matata
|
|
[Vrh] |
|
matmih Forumaš(ica)
Pridružen/a: 07. 12. 2006. (22:57:42) Postovi: (1A4)16
Spol:
Lokacija: {Zg, De , Ri}
|
|
[Vrh] |
|
dvičak Forumaš(ica)
Pridružen/a: 02. 11. 2006. (17:55:13) Postovi: (60)16
Spol:
Lokacija: dj-zg
|
|
[Vrh] |
|
vsego Site Admin
Pridružen/a: 06. 10. 2002. (22:07:09) Postovi: (3560)16
Spol:
Lokacija: /sbin/init
|
Postano: 0:21 pet, 29. 6. 2007 Naslov: |
|
|
[quote="dvičak"]a ovo drugo ti je da ne učita onaj '\n' do kojeg se prethodni string učitavao, akoji je ipak tu u obliku prelaska u novi redm kao _%s
nisam 100% siguran, ali mislim da je tako[/quote]
Nije bas tako, mada mu je to cesta namjena. :)
Format [tt]%c[/tt] ucitava jedan znak i sprema ga u odgovarajucu varijablu. :)
Format [tt]%*c[/tt] ucitava jedan znak, ali ga odbacujemo (i.e. ne zadajemo varijablu u koju se to sprema). :D
Npr.
[tt]scanf("%d%[color=red]*[/color]c%d", &x, &y);[/tt]
ce ucitati dva cijela broja odvojena jednim znakom. :) Brojevi ce biti pospremljeni u varijablama [tt]x[/tt] i [tt]y[/tt], a znak nece biti pospremljen nigdje. 8) Slicno,
[tt]scanf("%[color=red]*[/color]d%c%d", &c, &y);[/tt]
ce odbaciti prvi broj, znak ce spremiti u varijablu [tt]c[/tt], a drugi broj u varijablu [tt]y[/tt]. 8)
dvičak (napisa): | a ovo drugo ti je da ne učita onaj '\n' do kojeg se prethodni string učitavao, akoji je ipak tu u obliku prelaska u novi redm kao _%s
nisam 100% siguran, ali mislim da je tako |
Nije bas tako, mada mu je to cesta namjena.
Format %c ucitava jedan znak i sprema ga u odgovarajucu varijablu.
Format %*c ucitava jedan znak, ali ga odbacujemo (i.e. ne zadajemo varijablu u koju se to sprema).
Npr.
scanf("%d%*c%d", &x, &y);
ce ucitati dva cijela broja odvojena jednim znakom. Brojevi ce biti pospremljeni u varijablama x i y, a znak nece biti pospremljen nigdje. Slicno,
scanf("%*d%c%d", &c, &y);
ce odbaciti prvi broj, znak ce spremiti u varijablu c, a drugi broj u varijablu y.
_________________ U pravilu ignoriram pitanja u krivim topicima i kodove koji nisu u [code]...[/code] blokovima.
Takodjer, OBJASNITE sto vas muci! "Sto mi je krivo?", bez opisa u cemu je problem, rijetko ce zadobiti moju paznju.
|
|
[Vrh] |
|
ma Forumaš(ica)
Pridružen/a: 27. 01. 2007. (12:06:50) Postovi: (347)16
Spol:
|
|
[Vrh] |
|
vsego Site Admin
Pridružen/a: 06. 10. 2002. (22:07:09) Postovi: (3560)16
Spol:
Lokacija: /sbin/init
|
Postano: 1:55 pet, 29. 6. 2007 Naslov: |
|
|
Nece ici... uopce. :(
[tt]pom = first -> next;[/tt]
Ako je lista prazna, ovo ce srusiti program. :(
[tt]first -> next -> next = first;[/tt]
Upravo si rekao da je sljedbenig drugog elementa liste sadasnji prvi, a da adesu treceg nisi nigdje pospremio :arrow: ode lista! :shock: Dapace, dobio si cirkularnu listu od prva dva elementa stare liste i nepovratno izgubio ostatak. :(
[b]Preporuke:[/b]
1. Uvijek crtati listu i sto kod radi po njoj; ja to nisam crtao po ploci jer mi je zabavno, nego zato jer je korisno. :prodike:
2. Za ovaj konketni zadatak, prosvrljaj malo po ovom topicu. :)
Nece ici... uopce.
pom = first → next;
Ako je lista prazna, ovo ce srusiti program.
first → next → next = first;
Upravo si rekao da je sljedbenig drugog elementa liste sadasnji prvi, a da adesu treceg nisi nigdje pospremio ode lista! Dapace, dobio si cirkularnu listu od prva dva elementa stare liste i nepovratno izgubio ostatak.
Preporuke:
1. Uvijek crtati listu i sto kod radi po njoj; ja to nisam crtao po ploci jer mi je zabavno, nego zato jer je korisno.
2. Za ovaj konketni zadatak, prosvrljaj malo po ovom topicu.
_________________ U pravilu ignoriram pitanja u krivim topicima i kodove koji nisu u [code]...[/code] blokovima.
Takodjer, OBJASNITE sto vas muci! "Sto mi je krivo?", bez opisa u cemu je problem, rijetko ce zadobiti moju paznju.
|
|
[Vrh] |
|
ma Forumaš(ica)
Pridružen/a: 27. 01. 2007. (12:06:50) Postovi: (347)16
Spol:
|
|
[Vrh] |
|
vsego Site Admin
Pridružen/a: 06. 10. 2002. (22:07:09) Postovi: (3560)16
Spol:
Lokacija: /sbin/init
|
|
[Vrh] |
|
me_me Forumaš(ica)
Pridružen/a: 10. 09. 2006. (11:56:01) Postovi: (CC)16
|
|
[Vrh] |
|
fluff Forumaš(ica)
Pridružen/a: 06. 03. 2007. (11:45:29) Postovi: (5A)16
Spol:
Lokacija: zgb
|
|
[Vrh] |
|
me_me Forumaš(ica)
Pridružen/a: 10. 09. 2006. (11:56:01) Postovi: (CC)16
|
|
[Vrh] |
|
|