[ stalker @ 15.08.2004. 19:22 ] @
1.Nije mi jasno sta se trazi u ovom zadatku i kako bi resenje trebalo da izgleda (znaci, sve skolski). Evo dela postavke:
Napisati f-ju na C-u ciji ce argumenti biti znakovni niz i pokazivac na rezultujuci niz
Treba sada nesto da se radi sa prvim nizom i da napravimo drugi. Sada meni nije jasno ono - pokazivac na rez. niz. Zar niz vec nije pokazivac? Prototip bi bio:
a) int funkcija(char*, char*); ili
b) int funkcija(char*,char**); ?

Ja glasam za b) jer dalje kaze Za smestanje rezultata treba alocirati mem. prostor dovoljan za smestanje maks. niza znakova. Ako imam prototip kao pod a) besmisleno je raditi malloc nad tim pokazivacem???

2. Nadovezujuci se na prethodno - ako koristimo pod b) i ja uradim u funkciji *pok=malloc... koliko ce dugo ta memorija biti "moja", tj. u nasem programu? Dok se ne izadje iz funkcije ili iz programa ili dok ne lupim jedno free (ovde glasam za free)?
[ milanche @ 15.08.2004. 21:11 ] @
1) Moze i jedno i drugo. Ako se opredelis za resenje pod a) onda je obaveza onog
ko poziva funkciju da unapred alocira memoriju (sto podrazumeva da je duzina
rezultujuceg niza unapred poznata). Ako se opredelis za resenje pod b) onda se
memorija za rezultujuci niz moze alocirati kako pre poziva funkcije tako i u samoj
funkciji.

2) Dinamicki alocirana memorija (pomocu malloc( ) ili pomocu free( ) u C++-u) ne
ispada iz 'vazenja'. Jedino lokalne promenljive funkcije prestaju da postoje cim se
funkcija izvrsi, zato sto stack frame namenjen funkciji postaje nevazeci. Moras se
potruditi jedino da adresu alocirane memorije (tj. vrednost pointera) prosledis van
funkcije pre nego sto ona zavrsi posao (sto ces verovatno uraditi po zahtevu zadatka.
[ deckic @ 27.08.2004. 19:42 ] @
Zdravo,

mislim da zadatak nije dobro postavljen. To sto treba da se uradi je u stvari jedna procedura a ne funkcija, jer procedure nemaju povratne vrednosti a zadatak glasi napisati funkciju (proceduru) koja uzima jedan niz (a u c++ je uvek predaja argumenata by value, hoce reci taj niz se kopira i funkcija ga obradjuje ali ne menja onaj predati niz).
Taj pokazivac koji treba da se preda kao parametar nije nista drugo nego pokazivac na povratni niz a korisnik funkcije mora da vodi racuna o tome da je za taj niz spremna memorija. Nesto kao jedan prametar je ulazna a jedan izlazna vrednost. Takva tehnika je jako rasprostranjena ( COM programiranje) jer pozivni program nemora da ceka na povratnu vrednost sto je vrlo bitno kod client - server programiranja gde se koriste direktni pozivi funkcija na drugim racunarima preko protokola koji ne stvaraju permanentnu vezu. I u c ima dosta takvih "funkcija".

Izvinjavam se unapred ako sam pogresio, deckic
[ Koljenovic @ 27.08.2004. 21:54 ] @
OK je zadatak u nekoj mjeri, ukoliko je ono sto ja mislim onda nejjednostavnija skolska deklaracija funkcije koja vraca pokazivac radi, ali i ona tvoja a) varijanta bi radila sa prosljedjivanjem po referenci, deklaracija funkcije treba otprilike da izgleda ovako :

Code:

char *nesto(char *) {

  char *xxl;

  xxl = new char[duzina];    // duzina je po tvom kroju :)


  /* ovdje valjda treba da radis 
      nesto sa tim nizom, punis, praznis ness*/

return xxl;
}


U ovom slucaju rezultirajuci podatci su ti pointer na alocirani niz karaktera.

P.S. Samo jos dodam da moras promijeniti rezeviranu rijec new (Cpp) u odgovarajucu C funkciju, mislim da je malloc kao sto si spomenuo.
[ cicika @ 27.08.2004. 23:10 ] @
Citat:
To sto treba da se uradi je u stvari jedna procedura a ne funkcija,


U C-u ne posto je procedure, sve se naziva f-jama iako logicki void funkcije mozes da smatras procedurama ako ti je tako lakse, mada ne vidim cemu to. Neke f-je vracaju vrednost neke ne, vec se koriste njihovi side-effects.

Citat:
Zar niz vec nije pokazivac?


Sam niz nije, ali ako je niz npr. obelezen sa
Code:
a[i]
gde je i index clana onda je samo a (bez indeksa i uglastih zagrada) pokazivac na prvi clan niza dok se i-ti clan dobija kao *(a+i) (sadrzaj memorijske lokacije a+i).

Onda je deklaracija f-je:
Code:

int ImeFje(char Niz[], char *Pok) {
 /*telo funkcije*/
}


A ovo:
Code:
 **Pok 

deklarise pokazivac na dvodimenzionalni niz.
[ DeepInBrain @ 28.08.2004. 02:16 ] @
ovo zadnje od cicike je sasvim odgovarajuci odgovor!
mislim da si bas to trazio.
bravo cicika
;)
[ mmirilovic @ 28.08.2004. 11:18 ] @
Ime niza jeste konstantni pokazivač na početak niza. Odnosno pokazivač koji
nemože da pokazuje ninašta drugo sem na početak niza.

char niz[] = "0123456789";
int i;

for (int i =0; i<11; ++i)
{
printf("%c", *(niz+i) );
}
[ blaza @ 28.08.2004. 12:19 ] @
Citat:
...na prvi clan niza dok se i-ti clan dobija kao *(a+i) (sadrzaj memorijske lokacije a+i).

Zapravo, ne radi se o sadrzaju memorijske lokacije a + i, vec o interpretiranom sadrzaju memorijskog bloka cija je pocetna adresa a + i * korak, cija je velicina jednaka velicini memorijskog bloka koji okupira objekat istog tipa kao i elementi niza. korak oznacava razliku pocetne adrese dva susedna elementa niza. korak je jednak ili veci od broja memorijskih lokacija koje zauzima objekat tipa od kojeg je kreiran niz.
Hint: Pointer Arithmetic
[ cicika @ 28.08.2004. 12:49 ] @
Teoretski to je to, samo sam ja to malo jednostavnije rekla, bez osvrta na duzinu podatka, podrazumeva se da je tako.

Citat:
korak oznacava razliku pocetne adrese dva susedna elementa niza


Sto u stvari predstavlja velicinu podatka u bajtovima, a kako su pokazivac i podatak na koji pokazuje uvek istog tipa, pa samim tim i iste velicine to nije stvar o kojoj mora posebno da se misli pri lociranju i-tog clana niza, C to regulise sam.
Posebno nije bitno u primeru koji je stalker postavio.
[ srki @ 28.08.2004. 14:51 ] @
Citat:
mmirilovic: Ime niza jeste konstantni pokazivač na početak niza.

Nije bas tako ali je blizu. Ime niza ti je adresa memorijske lokacije odakle pocinje niz tako da ne moze da se koristi svuda gde i konstantni pokazivac.

http://www.eskimo.com/~scs/C-faq/q6.2.html
http://www.eskimo.com/~scs/C-faq/q6.8.html
http://www.eskimo.com/~scs/C-faq/q6.9.html

Citat:
for (int i =0; i<11; ++i)

treba i<10
[ blaza @ 28.08.2004. 16:27 ] @
Citat:
Sto u stvari predstavlja velicinu podatka u bajtovima.

Ne obavezno.
Kompajler moze, ako mu je dozvoljeno, da izvrsi preraspodelu pocetnih adresa objekta u memoriji u cilju povecanja brzine izvrsenja koda. korak moze biti veci od velicine memorijskog bloka koji zauzima elemenat niza.
Na 32-bitnim x86 masinama npr. zbog postupka citanja memorije pristup 32-bitnom podatku u memoriji najbrzi je ako je pocetna adresa podatka deljiva sa 4. Kompajler moze, u cilju ubrzanja koda, rasporediti elemente niza, tako da pocetna adresa prvog elementa i korak budu deljivi sa 4. Gubi se na prostoru, ali se dobija na brzini.
[ filmil @ 28.08.2004. 16:55 ] @
Citat:
Gubi se na prostoru, ali se dobija na brzini.
Čak se ni ne gubi na prostoru. SPARC računari recimo mogu da pristupaju podacima samo i isključivo ako su uravnati. Bilo kakvo drugo čitanje proizvodi grešku.

f
[ mmirilovic @ 28.08.2004. 19:38 ] @
> *blaza* Kompajler moze, ako mu je dozvoljeno, da izvrsi preraspodelu
pocetnih adresa objekta u memoriji ...

Ako kompajler izvrši takvu optimizaciju, tada će optimizovati i pokazivačku
aritmetiku, pa će, na primer:
*(a + i)
biti prilikom kompajliranja pretvoreno u:
*(a + i*korak)
[ Nedeljko @ 28.08.2004. 23:38 ] @
Niz je u C-u konstantan pokazivač kome se pre početka izvršavanja programa dodeljuje vrednost. Ta vrednost je adresa memorijskog bloka koji je rezervisan takođe pre početka izvršavanja programa. On je konstantan u smislu da se ne može u programu javiti sa leve strane operatora dodele. Dakle, nije moguće nešto poput

int a[3], b[3];

a=b;

Njegova se adresa tokom izvršavanja ne menja. To treba tumačiti u smislu da je ta pretpostavka dobra kada treba utvrditi šta je rezultat izvršavanja nekog programa. Operativni sistem i kompajler mogu da vrše samo one intervencije koje neće promeniti rezultat izvršavanja programa.

Sa druge strane, niz ima i neka svojstva promenljivih (u ovom slučaju pokazivačkih). Kao i promenljive, on zauzima mesto u memoriji i ima svoju adresu. Dakle, ako je x definisan kao niz, onda možemo pisati i nešto poput &x, mada to nije ni najmanje preporučljivo. Štaviše, takva konstrukcija praktično uvek znači da negde grešiš.

Ukoliko argument funkcije treba da bude niz x pri funkcija eventualno treba da menje članove tog niza x[0],x[1],... , a ne i samu adresu x (recimo da oslobađa zauzet prostor na koji x pokazuje ili da menja veličinu tog prosora), onda vrši prenos niza po vrednosti, a inače po adresi. Znači, ako treba samo da sortiraš niz, onda ćeš samo menjati članove tog niza, pa prenosiš niz po vrednosti. Ali ako pišeš funkciju koja treba da oslobodi prostor na koji pokazuje neki pokazivač i da mu dodeli vrednost NULL, onda prenosiš pokazivač na taj pokazivač.
[ cicika @ 29.08.2004. 17:28 ] @
Citat:
pa će, na primer:
*(a + i)
biti prilikom kompajliranja pretvoreno u:
*(a + i*korak)


To sam pokusavala da kazem.