[ kajla @ 13.07.2001. 13:50 ] @
Imam ovakav program:

const int twodim[10][6]=
{
{1,2,3,4,5,6},
{7,8,9,10,11,12},
{13,14,15,16,17,18},
{19,20,21,22,23,24},
{25,26,27,28,29,30},
{31,32,33,34,35,36},
{37,38,39,40,41,42},
{43,44,45,46,47,48},
{49,50,51,52,53,54},
{55,56,57,58,59,60}
};

main()
{
clrscr();
print_2(twodim,6,10);
getch();

return 0;
}

E sad cu dati 4 verzije funkcije print_2() od toga prve dve rade,
a druge dve nerade. Pa ako neko moze da objasni zasto ove zadnje dve
nerade.
(sve 4 funkcije su iste razlika je samo u deklarisanju prvog argumenta)

PS. nikako mi nije jasno kako ako imam:

int twodim[10][6];

i sad ovaj izraz je tacan: (leva strana JESTE jednaka desnoj).

(twodim + 1)==*(twodim + 1);

zasto?

evo sad 4 verzije funkcije print_2():

print_2(array,x,y) /*ove prve dve verzije daju iste rezultate*/
int array[][6],x,y;

{
int hor,ver;

for (ver=0;ver<y;ver++)
for (hor=0;hor<x;hor++)
printf("%it",*(*(array+ver)+hor));

return 0;
}

print_2(array,x,y)
int (*array)[6],x,y;

{
int hor,ver;

for (ver=0;ver<y;ver++)
for (hor=0;hor<x;hor++)
printf("%it",*(*(array+ver)+hor));

return 0;
}

print_2(array,x,y) /*ove zadnje dve verzije daju iste rezultate*/
int *array[6],x,y;

{
int hor,ver;

for (ver=0;ver<y;ver++)
for (hor=0;hor<x;hor++)
printf("%it",*(*(array+ver)+hor));

return 0;
}

print_2(array,x,y)
int **array,x,y;

{
int hor,ver;

for (ver=0;ver<y;ver++)
for (hor=0;hor<x;hor++)
printf("%it",*(*(array+ver)+hor));

return 0;
}

Kako da deklarisem prvi argument ako ne znam koliko clanova ima niz?

naravno funkcija print_2() se uvek moze napisati ovako (posto je
dvo-dimenzionali niz smesten kontinualno u memoriji) :

print_2(array,x,y)
int *array,x,y;

{
int i;

for (i=0;i<x*y;i++)
printf("%it",*(array+i) );

return 0;
}


poz.


[Ovu poruku je menjao kajla dana 07-13-2001 u 01:52 PM GMT]
[ Vojislav Milunovic @ 14.07.2001. 11:31 ] @
robaj ovako :
Code:

print_2(array,x,y) /*ove zadnje dve verzije daju iste rezultate*/
                          int **array,x,y;

                          {
                          int hor,ver;

                          for (ver=0;ver<y;ver++)
                          for (hor=0;hor<x;hor++)
                          printf("%dn",(*(array+ver)+hor));
                          return 0;
                          }  


Moram opet da se pozabavim sa ovim pointerima pa da vidim sta kako,naime i meni je ovo cudno ali opet radi ;o)
[ kajla @ 15.07.2001. 00:56 ] @
Dvo-dimenzionalni niz:

01|02|03|04|05|06
-----------------------
07|08|09|10|11|12
-----------------------
13|14|15|16|17|18
-----------------------
19|20|21|22|23|24
-----------------------
.
.
.

je smesten u memoriji ovako

01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20....

kao sto vidis smesten je kontinualno, kao i jednodimenzionalini niz.
E sad ti kad hoces dvo-dimenzionalni niz da smestis u **array, ne moras

da smestas kontinualno, vec napravis niz pointera(koji je kontinualan)
koji pokazuju na pocetne adrese blokova u memorji koji nemoraju da budu
smesteni kontinualno vec ih ti alociras dinamicki kad ti zatrebaju.
E sad fora je u tome sto je kod int twodim[10][6]:

*(twodim+1)=twodim+1

a kod **array:

*(array+1) != array+1 tj.

array+1 = adresa 2. broja u nizu, a *(array+1) = drugi broj u nizu.

kad mu ti napises **(array+1) dobijes vredost na memorijskoj lokaciji
2(drugi broj u nizu), tj dobijes neku bezveze vrednost.

Sto se tice one verzije print_2() koji si ti predlozio nevalja:

jer ti kad dodas +1 varijabli **array ti ustvari dodas +4 (1*sizeof(int
*)) tako da preskaces neke brojeve, naravno posto je dvo-dimenzionalini
niz smeste isto kao i jednodimenzionalni, neke brojeve stampa vise puta
jer imas dve petlje, jednu u drugoj.

Nego meni je cudno kako se ponasa "diferencing operator" (*) kad ga
primenis na dvodimenzionalni niz na primer:

kad varijabli twodim(pocetna adresa dvo-dimenzionalnog niza)
dodajemo aritmeticki izraz taj izraz je pomnozen sa velicinom
jednog reda tog dvo-dimenzinalnog niza.

znaci u nasem slucaju int twodim[10][6] je:

twodim + 1 u stvari memorijska lokacija dvo-dimenzionalnog
niza + 6*sizeof(int)

*(twodim + 1) vrednost je ista kao i twodim + 1 ali
ako izrazu *(twodim +1) dodamo neki broj taj broj je
pomnozen za sizeof(int) (u proslom slucaju je bio
pomnozen sa broj_kolona*sizeof(int) )

posto mi imamo da je *(twodim + 1) = twodim +1 to znaci
da je vrednost na memorijskoj lokaciji twodim + 1 ista
ta memorijska lokacija STO JE VRLO CUDNO!

iz svega ovoga izgleda kao da se operator * ponasa
razlicito kad su u pitanju **array odnosno twodim.


poz.
[ Vojislav Milunovic @ 15.07.2001. 10:32 ] @
Cek sad me ti zbunjujes? Jel ti oces objasnjnje ili postavljas pitanje da bi sam na njgea sebi odgvoorio????? Sto se tice svega u C i manipulsanja pointerima ja to sve kad me nesto zbunjuje provalim za manje od 10min uz pomoc gdb.

Moj printf() radi i vise mi ne treba.A sto se tice onog :

print_2(int (*array)[6],x,y) ->>>> tu ti je array pokazivac na funkciju....toliko
[ Vojislav Milunovic @ 15.07.2001. 10:46 ] @
Citat:
kajla je napisao:

je smesten u memoriji ovako

01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20....


Znam ovo sam video iz prve...a evo ti i dokaz a ne naklapanja tek tako:

Code:

int gg[2][2]={ {1,2} , {3,4} };

int main(){
 int gg1 = (int) gg;
}     


ista kaze nas friend gdb :
Code:
GNU gdb 4.18
Copyright 1998 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-unknown-freebsd"...
(no debugging symbols found)...
(gdb) disass main
Dump of assembler code for function main:
0x804847c <main>:       push   %ebp
0x804847d <main+1>:     mov    %esp,%ebp
0x804847f <main+3>:     sub    $0x18,%esp
0x8048482 <main+6>:     movl   $0x80494d4,0xfffffffc(%ebp)
0x8048489 <main+13>:    mov    %ebp,%esp
0x804848b <main+15>:    pop    %ebp
0x804848c <main+16>:    ret
0x804848d <main+17>:    nop
0x804848e <main+18>:    nop
0x804848f <main+19>:    nop
End of assembler dump.
(gdb)   x/x 0x80494d4
0x80494d4 <gg>: 0x00000001
(gdb)
0x80494d8 <gg+4>:       0x00000002
(gdb)
0x80494dc <gg+8>:       0x00000003
(gdb)
0x80494e0 <gg+12>:      0x00000004
(gdb)  quit


[ kajla @ 15.07.2001. 11:27 ] @
Citat:
predator je napisao:
Cek sad me ti zbunjujes? Jel ti oces objasnjnje ili postavljas pitanje da bi sam na njgea sebi odgvoorio????? Sto se tice svega u C i manipulsanja pointerima ja to sve kad me nesto zbunjuje provalim za manje od 10min uz pomoc gdb.

Moj printf() radi i vise mi ne treba.A sto se tice onog :

print_2(int (*array)[6],x,y) ->>>> tu ti je array pokazivac na funkciju....toliko


Ocu da postavim pitanje, ali posto sam u prvom postu dao primer nisam lepo istakao sta je pitanje, pa sam hteo da kazem sta mi je jasno a
sta me zbunjuje, tj zbunjuje me ono twdim + 1=*(twdim +1).

print_2(int (*array)[6],x,y)

sta je pokazivas na funkciju???
ako si mislio na int (*array)[6] - to ti NIKAKO nije pokazivac na funkciju
kolko sam ja citao koristi se int (*array)[6] umesto *array[6], jer je zagrada potrebna da bi prvo bio primenjen operator * pa onda napravljen niz. Neznam nasa mislis ali ovde nema nigde pokazivaca na funkciju.


poz.
[ kajla @ 15.07.2001. 11:34 ] @
Citat:
predator je napisao:
Citat:
kajla je napisao:

je smesten u memoriji ovako

01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20....


Znam ovo sam video iz prve...a evo ti i dokaz a ne naklapanja tek tako:

Code:

int gg[2][2]={ {1,2} , {3,4} };

int main(){
 int gg1 = (int) gg;
}     


ista kaze nas friend gdb :
Code:
GNU gdb 4.18
Copyright 1998 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-unknown-freebsd"...
(no debugging symbols found)...
(gdb) disass main
Dump of assembler code for function main:
0x804847c <main>:       push   %ebp
0x804847d <main+1>:     mov    %esp,%ebp
0x804847f <main+3>:     sub    $0x18,%esp
0x8048482 <main+6>:     movl   $0x80494d4,0xfffffffc(%ebp)
0x8048489 <main+13>:    mov    %ebp,%esp
0x804848b <main+15>:    pop    %ebp
0x804848c <main+16>:    ret
0x804848d <main+17>:    nop
0x804848e <main+18>:    nop
0x804848f <main+19>:    nop
End of assembler dump.
(gdb)   x/x 0x80494d4
0x80494d4 <gg>: 0x00000001
(gdb)
0x80494d8 <gg+4>:       0x00000002
(gdb)
0x80494dc <gg+8>:       0x00000003
(gdb)
0x80494e0 <gg+12>:      0x00000004
(gdb)  quit




Pa da tako je, ja nisam koristio gdb, ali sam citao u knjizi AOA(Art of Assembly Language) kako su smesteni dvo-dimenzionalni nizovi u memoriji
tamo je sve lepo objasnjeno, ali kako sam rekao i pre zbunjuje me ponasanje operatora * - kad ka primeniz na twodim i kad ga primenis na **array.

Prema tome ako to mozes da objasnis bio bi zahvalan (kako je
twodim + 1 = *(twodim + 1) a array + 1 != *(array + 1) )

poz.
[ kajla @ 15.07.2001. 11:46 ] @
Citat:

Moj printf() radi i vise mi ne treba.A sto se tice onog :


Mislis na print_2() - onu verziju koju si ti reko da probam?
Fora je u tome sto je sizeof (int) na 32bit-nim sistemima = 4 sto je isto kao i sizeof (int *), ali na 16 bit-nim sistemima (Kao dos na kome sam ja i radio ovaj primer) sizeof (int) NIJE JEDNAKO sizeof (int *)

poz.
[ Milan Aksic @ 15.07.2001. 13:08 ] @
Ne znam mozda gresim ali da pokusam ja da odgovorim :) Koliko sam ja razumeo pitanje, ako vas zbunjuje ponasanje
operatora dereferenciranja kada se primeni na twodim i array, mislim da je to zbog toga sto to
nisu dve iste vrste pokazivaca odnosno niza. Kao prvo ne treba mesati twodim + sizeof(int), u tom
slucaju ako je int velicine 4 bajta, znak u nizu twodim se pomera za cetiri znaka, ili broja a ne
za odredjenu velicinu u memoriji da pokazuje na sledeci znak. Aritmetika pokazivaca je jasna
kada se doda broj pokazivacu na niz on pomera za toliko mesta od nule. Sto se operatora dereferenciranja
tice, on se ponasa cudno, naglasavam ovako sam ja razumeo pitanje pa stoga mozda gresim, zbog toga
sto je twodim deklarisan kao obican dvo-dimenzionalni niz a array kao pokazivac na dvo-dimenzionalni
niz. E sada samo ime niza, u ovom slucaju twodim je KONSTANTNI pokazivac na prvi element u nizu. To
znaci da dok u array mozes da dodajes, pa onda maknes i opet dodajes adrese da pokazuje na nesto drugo
sa imenom niza twodim to ne moze. Pousaj dodele nove adrese imenu niza ili adresi prvog elementa u
nizu generise gresku. I zadnja stvar iako je twodim konstantni pokazivac, njemu ne treba opertator
dereferenciranja da bi prikazao element iz svog niza jer je on i deklarisan kao obican dvo-dimenzionalni niz.
Pozdrav.
[ Vojislav Milunovic @ 15.07.2001. 16:36 ] @
Citat:
kajla je napisao:

print_2(int (*array)[6],x,y)

sta je pokazivas na funkciju???


Ja sam se istripovao ;o) Nisam uopste pratio kod a ucinilo mi se da vidim
int (*array)() ...moja greskica
[ Vojislav Milunovic @ 15.07.2001. 16:40 ] @
Da da na 16bitnim sistemima ili procesorima sizeof(int) != sizeof(int *) ... nisam probao na DOSu nikad ali na njemu se sve adresira sa 20 bita pa bi onda sizeof(int *) ili bilo oji pokazivac trebalo da bude 20bita...nisam siguran jel nikad nisam probao ali mislim da bi tako trebalo da bude