[ korak @ 06.05.2013. 13:12 ] @
Prepisujem jedan paskalski program u C - sta ces musterija tako trazi.

u PASCALU imam:

Code:

type
tNiz = array[0..9] of byte;
var
PNizB : ^tNiz;
.
.
pNizB := @Niz;
.
.
pNizB^[ba] := bb;
Code:


Varijable ba i bb su tipa byte (neoznaceni char). Niz je niz bajtova. Prevod treba da uzme vrednost pointera pNizB i da mu doda vrednost indeksa ba, i to je odredisna adresa na koju se upisuje vrednost varijable bb.

U C-u sam napisao:

Code:

typedef unsigned char tpNiz[10]; //mozda je ovde greska, ali kompajler ne prihvata ako to drukcije napisem
tNiz * pNizB;
.
.
pNizB = &Niz;
.
.
*pNizB[bc] = ba; //ovo mi nije logicno, ali kompajler ne prihvata nista drugo
Code:


C prevod nije ono sto mi treba.

Nadam se da je ovo za vecinu lako, ali nemam vremena da zastajkujem oko ovakvih problema, jer prevod istalih iskaya ide lako i brzo. Ovo preskacem i idem dalje, nadam se skorasnjem odgovoru.

Pozdrav i hvala.
[ korak @ 06.05.2013. 13:25 ] @
Setio sam se:

napisao sam:

Code:

(*pNizB)[bc] = ba;
Code:


i sada imam zeljeni prevod.

Pozdrav.
[ bogdan.kecman @ 08.05.2013. 20:44 ] @
Citat:
korak:
u PASCALU imam:

Code:

type
  tNiz = array[0..9] of byte;
var
  PNizB : ^tNiz;
  .
  .
  pNizB := @Niz;
  .
  .
  pNizB^[ba] := bb;




ne valja ti to sto si radio posto:

Code:

unsigned char *PNizB[10];
unsigned char Niz[3];
unsigned char Nix[4];
...
Niz[0]=1;
Niz[1]='x';
Niz[2]='\0';

Nix[0]=1;
Nix[1]='x';
Nix[2]='\0';
Nix[3]='\0';
...
pNizB[0] = Niz;
pNizB[1] = Nix;
...
pNizB[0][ab]=bb;



ti si verovatno hteo:


Code:

unsigned char *PNizB;
unsigned char Niz[10];
...
Niz[0]=1;
Niz[1]='x';
Niz[2]=207;
...
Niz[8]='\n';
Niz[9]='\0';
...
pNizB= Niz; // ovde moze i: pNzB = &Niz[0];
...
pNizB[7] = 22;
...


ovo sto si ti uradio:
Code:

(*pNizB)[bc] = ba;


je sledece:

Code:

pNizB[0][bc] = ba;


dakle sa unsigned char *PNizB[10]; ti dobijes niz od 10 pointera, ne pointer na niz od 10 elemenata, ti dodelis adresu niza na prvi od tih 10 pointera pa ga onda juris .. sve je pitanje sta si hteo ali koliko ja vidim ti samo hoces pointer na niz a ne niz pointera

[ korak @ 19.05.2013. 22:10 ] @
Evo sa kakvom sam deklaraciom proveravao:

Code:

unsigned char ba,bb;
unsigned char Niz[10];

typedef unsigned char tNiz[10];

tNiz * pNizB



Ako napisem

Code:

pNizB = &Niz;

*pNizB[ba] = bb;


Adresu odredista sracunava kao ba*10+pNizB sto je pogresno - ne zelim to.

Ali ako napisem:

Code:

pNizB = &Niz;

(*pNizB)[ba] = bb;


Adresa odredista se racuna kao ba+pNizB sto je ispravno.

Ovde je slucaj da pNizB nije niz vec pointer, pa se zato moraju koristiti zagrade da izdvoje pointer u iskazu. Uostalom tako pise u definiciji C-a.

Neispravni iskaz (bez zagrada) podrazumeva da je pNizB niz od pointera na unsigned char i otuda pogresan prevod.

Pozdrav.

[ Odin D. @ 20.05.2013. 09:25 ] @
U C-u, samo ime niza je pokazivač koji sadrži adresu prvog člana niza.
(Ime niza pokazuje na prvi član niza, tj. samo ime niza, bez ikakvih operatora * ili & ili [] je pokazivač koji pokazuje na prvi član niza i njegova vrednost je memorijska adresa na kojoj se nalazi taj prvi član niza.)
Uglaste zagrade su operator koji tu adresu (početnog člana niza) uvećava za potreban broj (broj_u_ulgastim_zagradama * broj_memorijskih_lokacija koju_zauzima_jedan_član_niza) da bi se dobila adresa člana niza čiji je indeks u uglastim zagradama i pri tome onda još i automatski dereferencira tu adresu da bi rezultat izraza na kraju bio vrednost samog tog člana niza.

Ako imaš niz koji sadrži pet karaktera, npr.

char Niz[] = {'A', 'B', 'C', 'D', 'E'};

onda je

Niz = pointer koji pokazuje na karakter 'A' (prvi član u nizu)
*Niz = karakter A
Niz[0] = karakter A

Niz + 3 = adresa na kojoj se nalazi karakter 'D'
*(Niz + 3) = karakter 'D'
Niz[3] = karakter 'D'

Dakle, u opštem slučaju: Niz[k] = *(Niz + k*s), gdje je s broj bajtova u memoriji (tj. broj memorijskih lokacija) koje zauzima jedan član niza.

Izraz &Niz nema naročitog smisla pošto je to samo neka adresa na koju je kompajler smjestio pointer na prvi član niza.
Ispravan je, dobićeš njime tu adresu, ali šta će ti kad toj vrednosti koja je na toj adresi već možeš pristupiti preko imena Niz.
[ korak @ 20.05.2013. 21:37 ] @
Znam za to, zato Niz1 = Niz2 ne dodeljuje vrednosti elemenata jednog niza drugom, vec pointer Niz2 na Niz1, pa ce onda Niz1 ukazivati na elemente Niz2.

Ja sam testirao PASCAL-ski prevod, i paralelno tome isto u C-u. Znam da je suvisan znak & pri dodeljivanju, ali nie ni greska.

Medjutim ne komentarises prevod *pNizB[ba] i (*pNizB)[ba] buduci da daju razliciti prevod.

Pozdrav.
[ Odin D. @ 20.05.2013. 22:08 ] @
Citat:
korak:Medjutim ne komentarises prevod *pNizB[ba] i (*pNizB)[ba] buduci da daju razliciti prevod.

U pitanju je to što je operator indeksiranja [] većeg prioriteta nego operator dereferenciranja *.

U prvom slučaju prvo će se izvršiti uvećavanje adrese koja se nalazi u pNizB za ba, pa će se to dereferencirati i time je završen posao operatora indeksiranja [].
Zatim će se tako dobijena vrednost (ako je izraz smislen trebalo bi da je u pitanju neka memorijska adresa, tj. pNizB bi trebao da je niz pokazivača na nešto) još jednom dereferencirati operatorom dereferenciranja *.

U drugom slučaju zagradama mijenjaš redosljed operacija: prvo se pNizB dereferencira operatorom dereferenciranja * (a rezultat toga bi trebao da bude pokazivač na neki niz, tj. adresa na kojoj počinje neki niz), a onda se na tako dobijenu vrednost primjernjuje operator indeksiranja [], tj. [ba] da bi se pristupilo nekom članu tog niza koji ima indeks ba.

Ti bi trebalo da objasni u čemu je razlika.

E sad, da li ove među-vrednosti koje se javljaju u toku izračunavanja izraza predstavljaju smislene adrese memorijskih lokacija na kojima se nalazi nešto smisleno ili si jednostavno dobio lutajuće pointere kao grešku nastalu ili zbog pogrešnog kodiranja ili pogrešnog razmišljanja... nemam pojma, mrzi me da pokušavam shvatiti šta si htio da postigneš, jer su ti objašnjenja malo konfuzna, a ja sam pascal 90% zaboravio, tako da...

Aritmetika pokazivača u C-u je izuzetno fleksibilna i moćna, ali znaš kako se kaže međ' C-programerima:

"With simple and powerfull tools you are in position to make simple but powerfull errors."

[Ovu poruku je menjao Odin D. dana 20.05.2013. u 23:31 GMT+1]
[ bogdan.kecman @ 20.05.2013. 23:33 ] @
Citat:
korak:
Evo sa kakvom sam deklaraciom proveravao:



uprosceno, ja sam ti napisao sta znaci jedna, sta druga i sta treca sintaksa. ono sto si ti napisao sigurno nisi hteo da napises a radi ti samo slucajno, ako ti neces da skontas zasto radi slucajno i kako treba a svidja ti se da napises kako si napisao - go for it
[ korak @ 21.05.2013. 00:25 ] @
Ne moze biti slucajno. Pogledao sam prevod, napisao ti kako generie adresu, isao korak po korak i pratio kako varijable dobijaju vrednosti, i tako je kako sam ti napisao.

U principu mozes imati pointer kome dodeljujes adrese razlicitih nizova, a kod je nadalje isti jer koristi taj isti pointer.

Isti rezultat daje (*pNizB)[ba] = bb i Niz[ba] = bb, sto se i ocekuje. Provereno na simulaturu - nista nije slucajno. Doduse, normalno da su generisani kodovi razliciti.
[ bogdan.kecman @ 21.05.2013. 01:00 ] @
ne kapiras ti sta ti ja pricam ali nema veze, slucajno je zato sto se jedno koristi u jednom a drugo u drugom slucaju, ti si napravio niz nizova pa onda nisi koristio celu jednu dimenziju a pogodile su ti se vrednosti zato sto c nije strongly typed pa je svejendno adresa prvog clana niza i adresa tog niza, ti trazis preko adrese niza adresu prvog clana ne kapirajuci da je to adresa niza ... da si hteo da imas dvodimenzionalni niz to bi bilo ok ali nisi, i kao sto rekoh slucajno si dobio pravu vrednost, slucajno u smislu da si radio pogresno pa ti se pogodilo isto, ne slucajno u smislu da je to kod c-a slucajno posto adresa niza i adresa prvog clana nisu jesu uvek isti
[ korak @ 21.05.2013. 21:55 ] @
Ma razumem te ja, ali razmisljamo razlicito, i koristimo razlicite reci.

Procitao sam, nekada, da jezik kojim se sluzimo neprimetno vrsi veliki uticaj na nacin kako razmisljamo. To je izjavio neki uvazeni strucnjak za programske jezike jos 60-tih godina proslog veka. Nasa komunikacija je dobar primer toga.

Znam ja da ortogonalnost nije jaca strana C-a. U njenu kada navedes ime varijable u izrzu, podrazumeva se njena vrednost, ali ako je to ime ime niza, onda se radi o pointeru.

Video si da sam naveo i iskaz dodele u C-u koji daje isti rezultat. Ali ja trenutno testiram iskaze dodele u PASCAL-u, a u njemu kada se navede ime niza podrazumeva se vrednost niza, a ne njegova adresa. Zato mi je deklaracija onakva kakvu sam naveo u prvom postu.

Hteo sam nesto isto i u C-u, bez obzira sto je tu niz vec pointer. Eto svi nesporazumi se vrte oko toga.