|
[ kajla @ 05.07.2001. 00:43 ] @
| Da li je OK koristiti pointer-to-pointer umesto multi-dimenzonalnog niza ili "tables of pointers", evo jednog primera koji bi trebalo da isto radi i sa text[10][10] ili *text[10].
#include <stdio.h>
#include <alloc.h>
main()
{
char **text;
int i;
clrscr();
text=calloc(10,sizeof (char *));
for (i=0;i<10;i++)
{
*(text+i)=calloc(10,sizeof (char));
sprintf(*(text+i),"text-%d",i);
putchar(*(*(text+i)+2));
}
for (i=0;i<10;i++)
puts(*(text+i));
getch();
} |
[ tOwk @ 05.07.2001. 03:41 ] @
Naravno da je OK, samo je mnogo nečitljiviji kod. Ipak, ima i sintaksa oblika test[10] smisla, umesto *(test+10*sizeof(*test)).
Toliko.
dodatak: pošto smatram da ovo važi za jednodimenzione nizove, još više utiče na čitljivost koda kada se radi o dvodimenzionim nizovima. praktično, sam zapis indeksa označava upravo to, pa zašto ga ne iskoristiti.
[Ovu poruku je menjao tOwk dana 07-05-2001 u 03:46 AM GMT]
[ Vojislav Milunovic @ 05.07.2001. 11:28 ] @
pointer na pointer nije lose da koristis kada pises aplikaciju za koju ne znas koliko ce da ima redova/kolona u outputu...konkretno mislims na SQL baze...ja sam ovo koristio kod PostgreSQL baze i evo sacu da dam code:
Code:
#include<postgres/libpq-fe.h>
#include<stdio.h>
#include<stdlib.h>
int do_write(const char *ptr,int size);
int main(){
PGconn *db;
PGresult *result;
int field,tuple,i,j;
char *data,**fieldname;
char *conn_string="dbname=postgres user=postgres password=********";
db=PQconnectdb(conn_string);
if ( PQstatus(db) == CONNECTION_BAD ){
fprintf(stderr,"%s",PQerrorMessage(db));
exit(1);
}
result=PQexec(db,"select * from pilot");
if ( !result || PQresultStatus(result) == PGRES_FATAL_ERROR ){
fprintf(stderr,"%s",PQresultErrorMessage(result));
PQfinish(db);
exit(1);
}
field=PQnfields(result);
tuple=PQntuples(result);
fieldname=calloc(field,sizeof(char *));
for (i=0;i<field;i++)
fieldname[ i ]=PQfname(result,i);
/* Formating output */
for (i=0;i<tuple;i++)
for (j=0;j<field;j++)
printf("%s : %sn",fieldname[j],PQgetvalue(result,i,j));
PQclear(result);
PQfinish(db);
}
Kao sto vidis ovde sam koristio ** jel ne znam koliko kolona ima moja tabela...mogao sam to da uradim i za kolona/red ali ja sam to uradio samo za naziv kolona...
Recimo ako imas 10 naziva a ti si definisao niz od 5 char * onda postaje gadno jel prepisujes neke podatke u memoriji;o)
[ Ovu poruku je menjao predator dana 07-05-2001 u 10:30 AM GMT]
[ kajla @ 05.07.2001. 18:00 ] @
Citat: tOwk je napisao:
Naravno da je OK, samo je mnogo nečitljiviji kod. Ipak, ima i sintaksa oblika test[10] smisla, umesto *(test+10*sizeof(*test)).
Toliko.
dodatak: pošto smatram da ovo važi za jednodimenzione nizove, još više utiče na čitljivost koda kada se radi o dvodimenzionim nizovima. praktično, sam zapis indeksa označava upravo to, pa zašto ga ne iskoristiti.
[Ovu poruku je menjao tOwk dana 07-05-2001 u 03:46 AM GMT]
pazi, kad ti pointeru dodas +1 on je uvecan za 1*sizeof(tip), isto tako kod dvodimenzionalnih nizova kad pointeru dodaj +1 on je uvecan za broj_kolona*sizeof(tip)
imas int niz[10]
ti kad napises niz[10] kompajler to prevodi kao *(niz+10) (a ne *(niz+10*sizeof(int)) )
ili kad imas:
dvodim [10][10]
i kad napises dvodim[10] to je isto kao *(dvodim + 10) a,
kad napises dvodim[10][5] je isto kao *(*(dvodim + 10) + 5) ili kao (*(dvodim+10))[5]
ili opet *(dvodim[10]+5),
slicno predhodnom kad pointeru na pointer dodas aritmeticki izraz on je skaliran za velicinu pointera (4 byte)
na primer:
int **p;
printf("%dn",sizeof (int *));
printf("%Npn",p);
printf("%Npn",p+1);
program output ce biti:
4
1000 (lupam)
1004 (a ne 1001)
poz.
[ Ovu poruku je menjao kajla dana 07-05-2001 u 06:02 PM GMT]
[ Vojislav Milunovic @ 06.07.2001. 14:04 ] @
Pa da zato se uvek koristi trik sa pointerima, tj. casting u char * ;o) pa se onda na njega dodaje 10
sto je ekvivalentno pointer(20) + 10 = 30 pa tada vazi ovo
*(pointer + 10 *(sizeof(int *)))
;o) Veoma je zabavno ovo petljanje sa pointerima ;o))
[ Vojislav Milunovic @ 06.07.2001. 14:08 ] @
Code:
bash-2.04# cat gg1.c
int main(){
int *gg=(int *)0x1000;
printf("%p\n",gg);
printf("%p\n",gg + 1);
printf("%p\n",(char *)gg+1);
}
bash-2.04# make gg1
cc -pipe -march=pentiumpro gg1.c -o gg1
bash-2.04# ./gg1
0x1000
0x1004
0x1001
bash-2.04#
[ Ovu poruku je menjao predator dana 07-06-2001 u 01:11 PM GMT]
[ kajla @ 06.07.2001. 19:41 ] @
Tacno, u principu ako pointeru dodajes aritmeticki izraz taj izraz je skaliran za velicinu tipa varijable ciju adresu drzis u pointeru, naravno ako koristis type casting....
poz.
[ tOwk @ 07.07.2001. 14:24 ] @
Ok, u svakom slučaju može, ja sam dosad stalno i koristio casting "za svaki slučaj", pa sam i istripovao. Ali umesto čak i p+3, mislim da je bolje p[3] (mada to je stvar i stila).
Naravno, sada moja standardna kritika za neiskorišćavanje i nedovoljno poznavanje C-a važi za mene :).
Toliko.
[ Vojislav Milunovic @ 08.07.2001. 11:04 ] @
Nije to neznanje vec zaboravljanje ;o) A to se lako podseti na primeru koji sam malopre dao ...
[ sportbili @ 12.09.2002. 00:44 ] @
int *pa, i, niz[20];
pa=niz[0]; // pa=niz;
*(pa+i) != *(pa+i*(sizeof(int)))
Jel bi to bilo onda kao pristupanje clanu pa[4*i]?
I jos, kada se koristi castovanje u (char *) ako moze malo detaljnije objasnjenje
Izvinite za ponavljanje ali mi nije jasno.
[ Milan Aksic @ 12.09.2002. 02:36 ] @
Aritmetika pokazivaca je takva da kada se doda neki broj pokazivacu, onda se on 'pomera' da pokazuje na clan od trenutne pozicija + taj broj koji je dodat.
Znaci, ne pomeraju se bajtovi direktno da bi pokazivac pokazivao na neki clan.
Code:
*(pa+i);
Ako pa pokazuje na prvi clan u nizu (niz[0]) i ako je ovde i npr. 2 onda, pa pokazuje na treci clan.
Code:
*(pa+i*(sizeof(int))
U istom slucaju, ako pa pokazuje na prvi clan u nizu, i ako je i 2 a int 32-bitni, onda se pokazivac 'pomera' da pokazuje na 2 * 4, tj. na deveti clan.
Uostalom uveri se i sam:
Code:
int j, iNiz[10], *pNiz;
pNiz = iNiz;
for (j = 0; j < 10; j++)
iNiz[j] = j;
for (j = 0; j < 10; j++)
{
printf("iNiz[%d]:\t%d\t\t", j, iNiz[j]);
printf("pNiz + %d:\t%d\n", j, *(pNiz++));
}
pNiz -= 10;
printf("\n\n!!!\n*(pNiz + 2 * sizeof(int): %d\n", *(pNiz + 2 * sizeof(int)));
Nadam se da je sada jasnije ;o)
Copyright (C) 2001-2025 by www.elitesecurity.org. All rights reserved.
|