Prethodna tema :: Sljedeća tema |
Autor/ica |
Poruka |
Ongo Forumaš(ica)

Pridružen/a: 13. 02. 2006. (14:37:33) Postovi: (23)16
|
Postano: 17:06 sub, 13. 5. 2006 Naslov: Jos opakije pitanje |
|
|
Me again. Ukoliko u slijedecem kodu,
[code:1]int a,b;
printf("%X",&a);
scanf("%X",&b);
scanf("%d",b);
[/code:1]
pri prvom scanf-u jednostavno prepisemo ono sto je ispisao printf-a, rezultat ce biti ekvavilentan ovom kodu:
[code:1]int a;
scanf("%d",&a);
[/code:1]
Moje prvo pitanje je zasto postoje pointeri, kad ih obicni interegi mogu tako lako zamijeniti, tj. cemu definirati novi tip koji ce sluziti memoriranju brojeva (memorijskih adresa), kad vec postoji tip s istom ulogom?
Drugo pitanje u neku ruku slijedi iz prvog: kad vec postoji zasebni tip, zasto ne postoji samo jedan, nego po jedan pointerski tip za svaki obican?
Trece pitanje takoder slijedi iz prvog: na mom OSu sizeof pointera je 4. Bi li imalo smisla reci da je maksimalna memorija koju mogu instalirati na ovom OSu 4GB?
Me again. Ukoliko u slijedecem kodu,
Kod: | int a,b;
printf("%X",&a);
scanf("%X",&b);
scanf("%d",b);
|
pri prvom scanf-u jednostavno prepisemo ono sto je ispisao printf-a, rezultat ce biti ekvavilentan ovom kodu:
Kod: | int a;
scanf("%d",&a);
|
Moje prvo pitanje je zasto postoje pointeri, kad ih obicni interegi mogu tako lako zamijeniti, tj. cemu definirati novi tip koji ce sluziti memoriranju brojeva (memorijskih adresa), kad vec postoji tip s istom ulogom?
Drugo pitanje u neku ruku slijedi iz prvog: kad vec postoji zasebni tip, zasto ne postoji samo jedan, nego po jedan pointerski tip za svaki obican?
Trece pitanje takoder slijedi iz prvog: na mom OSu sizeof pointera je 4. Bi li imalo smisla reci da je maksimalna memorija koju mogu instalirati na ovom OSu 4GB?
|
|
[Vrh] |
|
mdoko Forumaš(ica)


Pridružen/a: 30. 11. 2002. (22:17:12) Postovi: (71A)16
Spol: 
Lokacija: Heriot-Watt University, Edinburgh
|
Postano: 18:11 sub, 13. 5. 2006 Naslov: Re: Jos opakije pitanje |
|
|
[quote]
Moje prvo pitanje je zasto postoje pointeri, kad ih obicni interegi mogu tako lako zamijeniti, tj. cemu definirati novi tip koji ce sluziti memoriranju brojeva (memorijskih adresa), kad vec postoji tip s istom ulogom?
Drugo pitanje u neku ruku slijedi iz prvog: kad vec postoji zasebni tip, zasto ne postoji samo jedan, nego po jedan pointerski tip za svaki obican?
[/quote]
Da odgovorim na oba pitanja. Radi se o tome da ako kompajler zna da je varijabla [tt]t[/tt] pointer na tip [tt]T[/tt], onda prilikom dereferenciranja te varijable kompajler zna da se na adresi koja je zapisana u [tt]t[/tt] nalazi pocetak zapisa tipa [tt]T[/tt], pa prema tome zna koliko je taj zapis dugacak i na koji ga nacin interpretirati.
Kod funkcija kao sto su [tt]scanf[/tt] i [tt]printf[/tt] nemas problema radi specificnog nacina na koji te funkcije rade. Za vise informacija pogledaj [url]http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.10.html[/url].
Vec kod baratanja s poljima postaje vrlo jasno zasto je bitno imati poseban tip pointera za svaki drugi tip, jer je tada boguce uvesti pointersku aritmetiku, sto u slucaju da pointere ne razlikujemo medjusobno ne bi bilo moguce.
[quote]
Trece pitanje takoder slijedi iz prvog: na mom OSu sizeof pointera je 4. Bi li imalo smisla reci da je maksimalna memorija koju mogu instalirati na ovom OSu 4GB?[/quote]
Arhitektura tvog kompjutera je takva da je maksimalni adresirljivi prostor velicine 4GB, pa je prema tome logicno da je velicina pointera 4B
Citat: |
Moje prvo pitanje je zasto postoje pointeri, kad ih obicni interegi mogu tako lako zamijeniti, tj. cemu definirati novi tip koji ce sluziti memoriranju brojeva (memorijskih adresa), kad vec postoji tip s istom ulogom?
Drugo pitanje u neku ruku slijedi iz prvog: kad vec postoji zasebni tip, zasto ne postoji samo jedan, nego po jedan pointerski tip za svaki obican?
|
Da odgovorim na oba pitanja. Radi se o tome da ako kompajler zna da je varijabla t pointer na tip T, onda prilikom dereferenciranja te varijable kompajler zna da se na adresi koja je zapisana u t nalazi pocetak zapisa tipa T, pa prema tome zna koliko je taj zapis dugacak i na koji ga nacin interpretirati.
Kod funkcija kao sto su scanf i printf nemas problema radi specificnog nacina na koji te funkcije rade. Za vise informacija pogledaj http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.10.html.
Vec kod baratanja s poljima postaje vrlo jasno zasto je bitno imati poseban tip pointera za svaki drugi tip, jer je tada boguce uvesti pointersku aritmetiku, sto u slucaju da pointere ne razlikujemo medjusobno ne bi bilo moguce.
Citat: |
Trece pitanje takoder slijedi iz prvog: na mom OSu sizeof pointera je 4. Bi li imalo smisla reci da je maksimalna memorija koju mogu instalirati na ovom OSu 4GB? |
Arhitektura tvog kompjutera je takva da je maksimalni adresirljivi prostor velicine 4GB, pa je prema tome logicno da je velicina pointera 4B
_________________ Extraordinary claims require extraordinary evidence. – Carl Sagan
|
|
[Vrh] |
|
vsego Site Admin


Pridružen/a: 06. 10. 2002. (22:07:09) Postovi: (3561)16
Spol: 
Lokacija: /sbin/init
|
Postano: 1:33 ned, 14. 5. 2006 Naslov: |
|
|
Evo primjer [tt]52a_pointeri_i_polja.c[/tt] koji sam ja nakucao za svoje prosle vjezbe:
[code:1]/*
Ovaj primjer pokazuje vaznost tipa podataka na koje pointer pokazuje.
Ovisno o tom tipu, inkrement daje razlicite vrijednosti.
*/
int main() {
char c;
int i;
float f;
double d;
char *pc = &c;
int *pi = &i;
float *pf = &f;
double *pd = &d;
printf("pc = %u, pc+1 = %u, (pc+1)-pc = %u, sizeof(pc) = %u, sizeof(*pc) = %u, sizeof(char) = %u\n", pc, pc + 1, (int)(pc+1) - (int)pc, sizeof(pc), sizeof(*pc), sizeof(char));
printf("pi = %u, pi+1 = %u, (pi+1)-pi = %u, sizeof(pi) = %u, sizeof(*pi) = %u, sizeof(int) = %u\n", pi, pi + 1, (int)(pi+1) - (int)pi, sizeof(pi), sizeof(*pi), sizeof(int));
printf("pf = %u, pf+1 = %u, (pf+1)-pf = %u, sizeof(pf) = %u, sizeof(*pf) = %u, sizeof(float) = %u\n", pf, pf + 1, (int)(pf+1) - (int)pf, sizeof(pf), sizeof(*pf), sizeof(float));
printf("pd = %u, pd+1 = %u, (pd+1)-pd = %u, sizeof(pd) = %u, sizeof(*pd) = %u, sizeof(double) = %u\n", pd, pd + 1, (int)(pd+1) - (int)pd, sizeof(pd), sizeof(*pd), sizeof(double));
return 0;
}[/code:1]
Obrati paznju na "stupac" [tt](p*+1)-p*[/tt] koji ne daje ocekivanih 1, nego [tt]sizeof(*)[/tt]. 8) Tu ulazi u igru ovo sto je mdoko spomenuo (kombiniranje pointera i nizova). :)
Naravno da bi se sve to moglo castanjem na integere, ali bi bilo daleko teze za pisati, nepreglednije za citati i podloznije greskama. :( I, naravno, opet bi trebao operatore za referenciranje ([tt]&[/tt]) i dereferenciranje ([tt]*[/tt]). :) Sto (tj. koji tip podataka) bi oni vracali? :-k Operator [tt]&[/tt] bi vracao [tt]int[/tt], a operator [tt]*[/tt]? :-k
Dakle, umjesto
[code:1]float x[50], max; int n;
float *pf;
...
max = *x;
for(pf = x; pf <= x + n - 1; pf++)
if (*pf > max) max = *pf;
...[/code:1]
bi imao
[code:1]float x[50], max; int n;
int pf;
...
max = x[0];
for(pf = (int)x; pf <= (int)x + (n - 1) * sizeof(float); pf += sizeof(float))
if ((float)(*pf) > max) max = (float)(*pf);
...[/code:1]
I onda se sjetis da ti ne treba niz [tt]float[/tt]-ova nego [tt]double[/tt]-ova i ides ispravljati takav program. :shock:
P.S. Sugeriram korisnije naslove topica. ;) Ovi mozda jesu [i]cool[/i] ili zabavni, ali su totalno neinformativni. :(
Evo primjer 52a_pointeri_i_polja.c koji sam ja nakucao za svoje prosle vjezbe:
Kod: | /*
Ovaj primjer pokazuje vaznost tipa podataka na koje pointer pokazuje.
Ovisno o tom tipu, inkrement daje razlicite vrijednosti.
*/
int main() {
char c;
int i;
float f;
double d;
char *pc = &c;
int *pi = &i;
float *pf = &f;
double *pd = &d;
printf("pc = %u, pc+1 = %u, (pc+1)-pc = %u, sizeof(pc) = %u, sizeof(*pc) = %u, sizeof(char) = %u\n", pc, pc + 1, (int)(pc+1) - (int)pc, sizeof(pc), sizeof(*pc), sizeof(char));
printf("pi = %u, pi+1 = %u, (pi+1)-pi = %u, sizeof(pi) = %u, sizeof(*pi) = %u, sizeof(int) = %u\n", pi, pi + 1, (int)(pi+1) - (int)pi, sizeof(pi), sizeof(*pi), sizeof(int));
printf("pf = %u, pf+1 = %u, (pf+1)-pf = %u, sizeof(pf) = %u, sizeof(*pf) = %u, sizeof(float) = %u\n", pf, pf + 1, (int)(pf+1) - (int)pf, sizeof(pf), sizeof(*pf), sizeof(float));
printf("pd = %u, pd+1 = %u, (pd+1)-pd = %u, sizeof(pd) = %u, sizeof(*pd) = %u, sizeof(double) = %u\n", pd, pd + 1, (int)(pd+1) - (int)pd, sizeof(pd), sizeof(*pd), sizeof(double));
return 0;
} |
Obrati paznju na "stupac" (p*+1)-p* koji ne daje ocekivanih 1, nego sizeof(*). Tu ulazi u igru ovo sto je mdoko spomenuo (kombiniranje pointera i nizova).
Naravno da bi se sve to moglo castanjem na integere, ali bi bilo daleko teze za pisati, nepreglednije za citati i podloznije greskama. I, naravno, opet bi trebao operatore za referenciranje (&) i dereferenciranje (*). Sto (tj. koji tip podataka) bi oni vracali? Operator & bi vracao int, a operator *?
Dakle, umjesto
Kod: | float x[50], max; int n;
float *pf;
...
max = *x;
for(pf = x; pf <= x + n - 1; pf++)
if (*pf > max) max = *pf;
... |
bi imao
Kod: | float x[50], max; int n;
int pf;
...
max = x[0];
for(pf = (int)x; pf <= (int)x + (n - 1) * sizeof(float); pf += sizeof(float))
if ((float)(*pf) > max) max = (float)(*pf);
... |
I onda se sjetis da ti ne treba niz float-ova nego double-ova i ides ispravljati takav program.
P.S. Sugeriram korisnije naslove topica. Ovi mozda jesu cool ili zabavni, ali su totalno neinformativni.
_________________ 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] |
|
Ongo Forumaš(ica)

Pridružen/a: 13. 02. 2006. (14:37:33) Postovi: (23)16
|
Postano: 14:16 ned, 14. 5. 2006 Naslov: |
|
|
Jasno da bi u okruzju koje sam prikazao bilo znatno teze i (u neku ruku) kompliciranije pisati programe, sto se vec vidi i iz mojeg primjera. Moje pitanje je cisto teorijske prirode.
Mdoko, hvala na linku; nije vezano, ali mjesto gdje su mi sve naredbe u svim librarijima lijepo objasnjene sam si vec dugo zelio. :)
Zahvaljujem na svim objasnjenjima (vsego, hvala na primjerima; zlata vrijede). Sad razumijem zasto i kako. U nekom svom svijetu programiranje dozivljavam kao upravljanjem strojem, u nasem slucaju njegovim procesorom i memorijom, pa me bajke koje prodaje vecina programskih jezika (osobito Pascal) redovito zbunjuju. Nije da bih volio programirati iskljucivo u asembleru ili tako necem, ali bi mi ta razina razumijevanja zasigurno pomogla u asimiliranju programskih jezika (such as C). Nazalost, bojim se da sam u takvom shvacanju poprilicno usamljen.
Eto, zato mi je drago znati da predlozeno okruzje nema vecih funkcionalnih mana osim predhodno navedenih.
[quote="mdoko"]Arhitektura tvog kompjutera je takva da je maksimalni adresirljivi prostor velicine 4GB, pa je prema tome logicno da je velicina pointera 4B[/quote]
Hmm... siguran? Arhitektura je 64-bitna, ali OS je 32-bitni (drugi je 64-bitni); sizeof(long int) na prvom je 4, a na drugom 8...
[quote="vsego"]P.S. Sugeriram korisnije naslove topica. Ovi mozda jesu cool ili zabavni, ali su totalno neinformativni. [/quote]
My mistake.
Jasno da bi u okruzju koje sam prikazao bilo znatno teze i (u neku ruku) kompliciranije pisati programe, sto se vec vidi i iz mojeg primjera. Moje pitanje je cisto teorijske prirode.
Mdoko, hvala na linku; nije vezano, ali mjesto gdje su mi sve naredbe u svim librarijima lijepo objasnjene sam si vec dugo zelio.
Zahvaljujem na svim objasnjenjima (vsego, hvala na primjerima; zlata vrijede). Sad razumijem zasto i kako. U nekom svom svijetu programiranje dozivljavam kao upravljanjem strojem, u nasem slucaju njegovim procesorom i memorijom, pa me bajke koje prodaje vecina programskih jezika (osobito Pascal) redovito zbunjuju. Nije da bih volio programirati iskljucivo u asembleru ili tako necem, ali bi mi ta razina razumijevanja zasigurno pomogla u asimiliranju programskih jezika (such as C). Nazalost, bojim se da sam u takvom shvacanju poprilicno usamljen.
Eto, zato mi je drago znati da predlozeno okruzje nema vecih funkcionalnih mana osim predhodno navedenih.
mdoko (napisa): | Arhitektura tvog kompjutera je takva da je maksimalni adresirljivi prostor velicine 4GB, pa je prema tome logicno da je velicina pointera 4B |
Hmm... siguran? Arhitektura je 64-bitna, ali OS je 32-bitni (drugi je 64-bitni); sizeof(long int) na prvom je 4, a na drugom 8...
vsego (napisa): | P.S. Sugeriram korisnije naslove topica. Ovi mozda jesu cool ili zabavni, ali su totalno neinformativni. |
My mistake.
|
|
[Vrh] |
|
mdoko Forumaš(ica)


Pridružen/a: 30. 11. 2002. (22:17:12) Postovi: (71A)16
Spol: 
Lokacija: Heriot-Watt University, Edinburgh
|
|
[Vrh] |
|
Ongo Forumaš(ica)

Pridružen/a: 13. 02. 2006. (14:37:33) Postovi: (23)16
|
|
[Vrh] |
|
ay4u5unwzb Forumaš(ica)

Pridružen/a: 30. 07. 2003. (19:46:43) Postovi: (5E)16
Spol: 
|
Postano: 18:47 ned, 14. 5. 2006 Naslov: |
|
|
[quote]Hmm... siguran? Arhitektura je 64-bitna, ali OS je 32-bitni (drugi je 64-bitni); sizeof(long int) na prvom je 4, a na drugom 8...[/quote]
Na 64bitnoj arhitekturi 64bitni Windowsi koriste LLP64 model, tojest: int je 32bitni, long je isto 32bitni, a long long je 64 bitni. Pointer je naravno 64 bitni. Stoga, ako se ne varam, 64bitni Windowsi ce ti kao sizeof(long) na 64 bitnoj arhitekturi svejedno vratiti 4. 32bitni Windowsi na 64bitnoj arhitekturi koriste ILP32 mode, gdje su i int i long dugi 32 bita, pa je sizeof(int) i sizeof(long) 4.
S druge strane, Linux na 64bitnoj arhitekturi koristi LP64, sto znaci da je int velik 32, a long 64 bita. Pointer je opet naravno 64 bitni. Stoga, sizeof(int) je 4, a sizeof(long) je 8.
Citat: | Hmm... siguran? Arhitektura je 64-bitna, ali OS je 32-bitni (drugi je 64-bitni); sizeof(long int) na prvom je 4, a na drugom 8... |
Na 64bitnoj arhitekturi 64bitni Windowsi koriste LLP64 model, tojest: int je 32bitni, long je isto 32bitni, a long long je 64 bitni. Pointer je naravno 64 bitni. Stoga, ako se ne varam, 64bitni Windowsi ce ti kao sizeof(long) na 64 bitnoj arhitekturi svejedno vratiti 4. 32bitni Windowsi na 64bitnoj arhitekturi koriste ILP32 mode, gdje su i int i long dugi 32 bita, pa je sizeof(int) i sizeof(long) 4.
S druge strane, Linux na 64bitnoj arhitekturi koristi LP64, sto znaci da je int velik 32, a long 64 bita. Pointer je opet naravno 64 bitni. Stoga, sizeof(int) je 4, a sizeof(long) je 8.
|
|
[Vrh] |
|
Ongo Forumaš(ica)

Pridružen/a: 13. 02. 2006. (14:37:33) Postovi: (23)16
|
|
[Vrh] |
|
ay4u5unwzb Forumaš(ica)

Pridružen/a: 30. 07. 2003. (19:46:43) Postovi: (5E)16
Spol: 
|
Postano: 23:32 ned, 14. 5. 2006 Naslov: |
|
|
[quote="Ongo"]Mosore, zahvaljujem na ovom strucnom pojasnjenju. Nemam 64bitne Windoze, no tko zna...
Negdje sam cuo da AMD arhitektura koju ja koristim moze adresirati do 64 terabajta RAM-a (nisam bas siguran da je toliko, ali je svakako vise od 4Gb), pa eto pitam.[/quote]
Ako me sjecanje sluzi, AMD64 platforma je zasad ogranicena, tako da moze moze adresirati "samo" 2^48 (256 TB) virtualnog adresnog prostora, iako bi ga se teoretski lako moglo prepraviti pa da mu limit bude 2^64. Naravno, sve opet ovisi o OSu koji se vrti povrh svega toga, ali ovo su teoretska ogranicenja same hardverske platforme.
Ongo (napisa): | Mosore, zahvaljujem na ovom strucnom pojasnjenju. Nemam 64bitne Windoze, no tko zna...
Negdje sam cuo da AMD arhitektura koju ja koristim moze adresirati do 64 terabajta RAM-a (nisam bas siguran da je toliko, ali je svakako vise od 4Gb), pa eto pitam. |
Ako me sjecanje sluzi, AMD64 platforma je zasad ogranicena, tako da moze moze adresirati "samo" 2^48 (256 TB) virtualnog adresnog prostora, iako bi ga se teoretski lako moglo prepraviti pa da mu limit bude 2^64. Naravno, sve opet ovisi o OSu koji se vrti povrh svega toga, ali ovo su teoretska ogranicenja same hardverske platforme.
|
|
[Vrh] |
|
Buraz Gost
|
|
[Vrh] |
|
|